Что такое лучший дизайн?

Вместо этого попробуйте заменить ваш код следующим:

the_title( '<h1 class="product_title entry-title">', '</h1>' ); 
$terms = wp_get_post_terms( get_the_id(), 'product_cat' );
$term  = reset($terms);
echo $term->name;

Это должно сработать.

7
задан Chad Johnson 8 April 2009 в 17:38
поделиться

13 ответов

Yes, I think your User class is doing too much.

Split some of the group-related functions into a Group class, and the module-related functions into a Module class. Or maybe split permissions into its own set of classes.

8
ответ дан 6 December 2019 в 07:52
поделиться

Its hard to tell from method names alone. One heuristic I use to break a class up is to look at the state variables. Are there pieces of state that tend to be used together? Can they be broken out into a separate class?

4
ответ дан 6 December 2019 в 07:52
поделиться

Будет полезно, если вы сможете описать, как ведет себя ваш объект Пользователь , с кем все это взаимодействует, какова его среда и т. Д.

Полагаю, я мог бы поставить связанные с разрешениями методы в некотором классе разрешений [...]

Да, вы можете взглянуть на дизайн, основанный на политике.

Я также хотел бы предложить вам удалить фиксированное состояние пользователя т.е. адрес электронной почты / имя и т. Д. И поместите его в отдельный класс.

1
ответ дан 6 December 2019 в 07:52
поделиться

Насколько сложно теперь добавить новые функции или сохранить существующие функции в вашем приложении? Если у вас нет проблем в этом отношении, то вы, вероятно, в порядке, сохраняя вещи такими, какие они есть (по крайней мере, на некоторое время).

Да, у вашего класса User есть некоторые перекрывающиеся обязанности, которые потенциально могут быть преобразованы в Система контроля доступа на основе ролей .

Суть в следующем: вам действительно она понадобится ?

1
ответ дан 6 December 2019 в 07:52
поделиться

Если у вас уже есть исполняемый код, то рефакторинг на мелкие кусочки. Если нет, я бы посмотрел на следующее:


class User {
  String username
  String name
  String emailAddress
  Boolean active
  Integer permission # A bitmask of the statics in the Permission class
}

class Group {
  String name
}

class UserGroupMapping {
  User user
  Group group
  Boolean administrator
}

class Permission {
  static IS_ROOT = 1
  static IS_SITE_ADMIN = 2
}

class Session {
  User user
  Boolean logged_in
}

Остальное действительно принадлежит классу обслуживания:

 class SecurityService {
 статическая публичная функция hasModulePermission ($ пользователь, $ модуль, $ запись, $ разрешение) {...}
 статическая публичная функция hasGroupPermission ($ пользователь, $ группа, $ разрешение) {...}
 статическая публичная функция hasContentPermission ($ user, $ record, $missions) {...}
 статическая публичная функция hasModulePermission ($ пользователь, $ модуль, $ запись, $ разрешение) {...}
}

9
ответ дан 6 December 2019 в 07:52
поделиться

Я бы разделил аспект "пользователь" и " группа «Управленческий аспект занятия».

0
ответ дан 6 December 2019 в 07:52
поделиться

I would at least remove the setCanLogIn($canLogIn) function. This should really be determined internally within the class based on if the user has supplied the correct credentials and has been authenticated.

Depending on how large this project is, or whether this is part of a framework will determine if more abstraction is needed.

0
ответ дан 6 December 2019 в 07:52
поделиться

Это выглядит достаточно правдоподобно. Конечно, я не знаю приложения. Я думаю, что имеет смысл выделить класс Permissions.

В идеале, тогда вы должны подумать о том, что значит иметь класс Permissions - что он знает, каковы его реальные действия? Кроме того, поскольку «разрешения» множественного числа, вы можете задаться вопросом, действительно ли вы хотите набор отдельных объектов разрешений, но действительно ли они являются доступными для простого логического значения, которое может быть излишним.

0
ответ дан 6 December 2019 в 07:52
поделиться

Похоже, вам нужны отдельные объекты ACL и Role от объекта User.
http: //en.wikipedia .org / wiki / Role-based_access_control

Вы также можете увидеть , как это делается в ZF .

Для удобства чтения вы можете использовать __ get () и __ set () вместо:

  public function setName($value) { ... }
  public function setEmailAddress($value) { ... }
  public function setUsername($value) { ... }
  public function getName() { ... }
  public function getEmailAddress() { ... }
  public function getUsername() { ... }
0
ответ дан 6 December 2019 в 07:52
поделиться

Пока методы класса возвращают данные экземпляра или изменяют только внутреннее состояние, в классе нет ничего плохого

Но, например, если метод canLogIn () ищет какую-то внешнюю службу (репозиторий, служба членства и т. Д.), Возникает проблема простоты и тестируемости. Если это так, у вас должен быть какой-то класс обслуживания и эти методы. Например,

new SomeFactory().GetUserService().canLogIn(user);
0
ответ дан 6 December 2019 в 07:52
поделиться

Это не так уж плохо, но я думаю, что ваши механики разрешений могут использовать факторинг. Это тот случай, когда явно требуется агрегация, а не наследование. Если есть вероятность того, что нетривиальная контактная информация будет связана с пользователем, вы также можете выделить адрес электронной почты, возможно, в удостоверение, в которое при необходимости может быть загружена другая контактная информация.

В общем, я мог бы рекомендовать думать о своем пользователе как о центральном пункте для агрегации и составления (а не наследования) субъединиц функциональности - подхода, который позволяет достичь статуса модного слова в разработке игр под рубрикой «система сущностей».

0
ответ дан 6 December 2019 в 07:52
поделиться
(event.start BETWEEN week.start AND week.end)
OR
(week.start BETWEEN event.start AND event.end)

Проще говоря, либо неделя начинается во время события, либо событие начинается в течение недели.

Давайте проверьте его:

Событие начинается и заканчивается в течение недели.

Событие начинается в течение недели.

Событие начинается до недели, но заканчивается в течение недели.

Неделя начинается во время события.

Событие начинается в течение недели, но заканчивается после недели.

Событие начинается в течение недели.

Событие начинается до недели, а также заканчивается после недели.

Неделя начинается во время события.

Обратите внимание, что МЕЖДУ в вышеприведенных выражениях используется просто для краткости.

Строгое выражение выглядит следующим образом:

(event.start >= week.start AND event.start < week.end)
OR
(week.start >= event.start AND week.start < event.end)

, при условии, что week.end является неделей . начало + ИНТЕРВАЛ 7 ДНЯ .

I. е. если у вас неделя начинается вс, 0:00:00 ,

  • Когда требуется проверка на равенство ссылок, вы должны использовать operator ==, operator! = И Object.ReferenceEquals .
  • Вы должны только переопределить operator == и operator! = Для ValueTypes и неизменные ссылочные типы.

  • Обоснование

    IEquatable

    Интерфейс System.IEquatable используется для сравнения двух экземпляров объекта на равенство. Объекты сравниваются на основе логики, реализованной в классе. Сравнение приводит к логическому значению, указывающему, отличаются ли объекты. Это отличается от интерфейса System.IComparable, который возвращает целое число, указывающее, как отличаются значения объекта.

    Интерфейс IEquatable объявляет два метода, которые должны быть переопределены. Метод Equals содержит реализацию, которая выполняет фактическое сравнение и возвращает true, если значения объекта равны, или false, если они не равны. Метод GetHashCode должен возвращать уникальное хеш-значение, которое можно использовать для уникальной идентификации идентичных объектов, которые содержат разные значения. Тип используемого алгоритма хеширования зависит от реализации.

    Метод IEquatable.Equals

    • Вы должны реализовать IEquatable для своих объектов, чтобы обрабатывать вероятность того, что они будут храниться в массиве или универсальной коллекции.
    • Если вы реализуете IEquatable, вам также следует переопределить реализации базового класса Object .Equals (Object) и GetHashCode, чтобы их поведение соответствовало поведению метода IEquatable.Equals

    Рекомендации по переопределению Equals () и Operator == (Руководство по программированию в C #)

    • x.Equals (x) возвращает true . [1 269] х. Equals (y) возвращает то же значение, что и y.Equals (x)
    • , если (x.Equals (y) && y.Equals (z)) возвращает true, тогда x.Equals (z) возвращает true.
    • Последовательные вызовы х. Equals (y) возвращает одно и то же значение, если объекты, на которые ссылаются x и y, не изменены.
    • x. Equals (null) возвращает false (только для типов значений, не допускающих значения NULL). Для получения дополнительной информации см. Nullable Types (Руководство по программированию в C #) .)
    • Новая реализация Equals не должна генерировать исключения.
    • Рекомендуется, чтобы любой класс, который переопределяет Equals, также переопределял Object.GetHashCode.
    • Рекомендуется, чтобы в дополнение к реализации Equals (объект), любой класс также реализовывал Equals (тип) для своего собственного типа, чтобы повысить производительность.

    По умолчанию оператор == проверяет равенство ссылок, определяя, указывают ли две ссылки на один и тот же объект. Следовательно, ссылочные типы не должны реализовывать оператор == для получения этой функциональности. Когда тип является неизменяемым, то есть данные, содержащиеся в экземпляре, не могут быть изменены, может быть полезен оператор перегрузки == для сравнения равенства значений вместо ссылочного равенства, поскольку в качестве неизменяемых объектов они могут рассматриваться как длинные так как они имеют одинаковое значение. Не рекомендуется переопределять оператор == в неизменяемых типах.

    • Перегруженный оператор == реализации не должны вызывать исключения.
    • Любой тип, перегружающий оператор ==, также должен перегружать оператор! =.

    == Оператор (C # Reference)

    • Для предопределенных типов значений Оператор равенства (==) возвращает true, если значения его операндов равны, в противном случае - false.
    • Для ссылочных типов, отличных от строки, == возвращает true, если два его операнда ссылаются на один и тот же объект.
    • Для строкового типа == сравнивает значения строк.
    • При проверке на нулевое значение с использованием == сравнений в переопределениях вашего оператора == убедитесь, что вы используете оператор базового класса объектов. Если вы этого не сделаете, произойдет бесконечная рекурсия, приводящая к переполнению стека.

    Метод Object.Equals (Object)

    Если ваш язык программирования поддерживает перегрузку операторов и если вы решите перегрузить оператор равенства для данного типа, то Тип должен переопределить метод Equals. Такие реализации метода Equals должны возвращать те же результаты, что и оператор равенства

    Следующие рекомендации предназначены для реализации типа значения :

    • Рассмотрите возможность переопределения Equals для повышения производительности по сравнению с тем, который предоставляется по умолчанию реализация Equals для ValueType.
    • Если вы переопределяете Equals и язык поддерживает перегрузку операторов, вы должны перегрузить оператор равенства для вашего типа значения.

    Следующие рекомендации касаются реализации ссылочного типа :

    • Рассмотрите возможность переопределения Equals для ссылочного типа, если семантика типа основана на том факте, что тип представляет некоторое значение (я).
    • Большинство ссылочных типов не должны перегружать оператор равенства, даже если они переопределяют Equals. Однако,

      .MemberOfGroup(GroupID)
      .AdminSite
      .Root
      .AdminGroup(GroupID)
      

      Предлагаем заменить их функциями получения / установки разрешений, которые обрабатывают экземпляр TUserPermissions:

      public function hasModulePermission($moduleId, $recordId, $permissionCode) 
      public function hasGroupPermission($groupId, $permissionCode) 
      public function hasContentPermission($recordId, $permissionCode) 
      public function hasModulePermission($moduleId, $recordId, $permissionCode) 
      public function canLogIn() 
      public function setCanLogIn($canLogIn)
      

      TUserPermissions будет иметь:

      .ModulePermitted(ModuleID,RecordID,PermCode)
      .GroupPermitted(GroupID,PermCode)
      .ContentPermitted(RecordID,PermCode)
      .ModulePermitted(ModuleID,RecordID,PermCode)
      .CanLogIn
      
    0
    ответ дан 6 December 2019 в 07:52
    поделиться

    I would consider creating a Permissions class and making that a member of the User class.

    0
    ответ дан 6 December 2019 в 07:52
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: