Разве черты не просто состав? - PullRequest
21 голосов
/ 02 марта 2012

Я читал статью о новых функциях в PHP 5.4.0.Одним из наиболее ожидаемых является Черты .

Читая об этих Чертах , чтобы увидеть, о чем они, они простосмотри как мне помогло копирование-вставка компилятором;и язык, предоставляющий способ использовать композицию, очень похожий на хорошо известный шаблон стратегии, который использует принцип дизайна «композиция благосклонности над наследованием».

Правильно ли я понимаю это?

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

Ответы [ 4 ]

20 голосов
/ 02 марта 2012

Нет, черты - это не просто композиция, потому что правила, по которым черты «вставляются» в класс, совершенно разные.

При использовании Composition нет никаких шансов для перезаписи конфликтов или методов, потому что составной элемент является полностью изолированной единицей (экземпляром некоторого другого класса), с которой вы взаимодействуете через свой открытый API изнутри потребляющего экземпляра. Кроме того, если вам нужно предоставить доступ из потребляющего экземпляра, вам придется добавить прокси-методы для делегирования в составной элемент.

С другой стороны, черты становятся частью API того самого экземпляра, в котором они используются. Они не являются подсистемами в этом экземпляре. Это даже не экземпляры, а просто многократно используемый шаблонный код. Это дает одно преимущество - удовлетворение интерфейсов с чертой, как я показал в Черты в PHP - какие-либо реальные примеры / лучшие практики?

5 голосов
/ 16 марта 2012

Вы должны быть осторожны с тем значением, которое вы придаете композиции. В более общем смысле черты являются механизмом как разложения, так и состава.

  • Разложение - как мы разлагаем программную базу на подходящие единицы повторного использования (повторное использование кода, СУХОЙ).
  • Композиция - как мы составляем эти единицы для получения иерархии классов подходит для нашего приложения домена.

Черты - это механизм для композиции в том смысле, что они могут быть составлены с помощью класса. Многие реализации признаков также позволяют составлять признаки друг с другом.

Мантра GoF - «композиция благосклонности перед наследованием».

Все языки классов по умолчанию предпочитают наследование. Объект может приобретать поведение только у своего класса или у классов выше в цепочке наследования. Конечно, вы можете достичь одного и того же результата по-разному. Например, вы можете создать класс диспетчера (например, LayoutMananager), а затем добавить ссылку на него в любом классе, обладающем чертой поведения / макета, и добавить функцию, которая не выполняет ничего, кроме вызова методов диспетчера

public function doSomething() { return layoutManager.doSomething(); }

Черты благоприятствуют композиции. Просто как тот. Ключевой характеристикой черт является то, что они живут вне иерархии классов. Вы можете «приобретать» многократно используемые модели поведения или черты, не используя их ни в одном из ваших суперклассов (различие по горизонтали и вертикали, представленное в других публикациях). Это главное преимущество.

Самая большая проблема с признаками - это возникновение конфликта, когда признаки реализованы таким образом, что вы можете напрямую выполнить myObject.doSomething () вместо myObject.trait1.doSometing () (прямо или косвенно, как описано выше с layoutManager) , Как только вы добавите более одной черты в класс, конфликты могут легко возникнуть. Ваша реализация должна поддерживать такие механизмы, как псевдонимы и переопределения, чтобы помочь в разрешении конфликтов. Вы получаете некоторые накладные расходы обратно.

Не ясно, соответствует ли реализация PHP этому, но черты также не должны указывать какие-либо переменные экземпляра, и методы, предоставляемые чертами, никогда не должны напрямую обращаться к переменным экземпляра. (источник: Добавление признаков к (статически типизированным) языкам , PDF). Это сообщение в блоге обсуждает это. Он утверждает, что в PHP структура с именем trait действительно является смесью (то есть признаками с состоянием). (Хотя этот другой пост в блоге описывает их как не имеющих состояния )

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

2 голосов
/ 02 марта 2012

Черты «композиция» (это просто включение на уровне методов классов) происходит во время компиляции, тогда как композиция, о которой вы говорите, находится во время выполнения.

Когда вы делаете эту композицию, черта уже была там.

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

1 голос
/ 02 марта 2012

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

Вопрос действительно интересный.

...