В java-мире (точнее, если у вас нет множественного наследования /mixins ), эмпирическое правило довольно просто: "Использовать состав объектов над наследованием класса".
Я хотел бы знать, если/как это изменилось, если вы также рассматриваете mixins, особенно в scala?
Смешины считаются способом множественного наследования, или более классным составом?
Существует ли также "Опорная структура объекта над классом" (или наоборот)?
Я видел несколько примеров, когда люди используют (или злоупотребляют) миксины, когда композиция объекта также может выполнять эту работу, и я не всегда уверен, какой из них лучше. Мне кажется, что вы можете добиться с ними довольно схожих вещей, но есть и некоторые различия: некоторые примеры:
- видимость - с миксинами все становится частью публичного api, что не соответствует композиции.
- verbosity - в большинстве случаев mixins менее многословны и немного проще в использовании, но это не всегда так (например, если вы также используете типы self в сложных иерархиях)
Я знаю, что короткий ответ: "Это зависит", но, вероятно, есть типичная ситуация, когда это или лучше.
Некоторые примеры рекомендаций, которые я мог бы придумать до сих пор (если у меня есть две черты A и B, а A хочет использовать некоторые методы из B):
- Если вы хотите расширить API A с помощью методов из B, то mixins, иначе состав. Но это не помогает, если класс/экземпляр, который я создаю, не является частью общедоступного API.
- Если вы хотите использовать некоторые шаблоны, которым нужны микшины (например, Stackable Trait Pattern), тогда это простое решение.
- Если у вас есть круговые зависимости, то могут помочь mixins с типами self. (Я стараюсь избегать этой ситуации, но это не всегда легко)
- Если вам нужны какие-то динамические решения времени выполнения, как выполнить композицию, то состав объекта.
Во многих случаях mixins кажутся более легкими (и/или менее подробными), но я вполне уверен, что у них также есть некоторые подводные камни, такие как "класс Бога" и другие, описанные в двух статьях artima: часть 1, часть 2 (Кстати, мне кажется, что большинство других проблем не имеют отношения/не имеют отношения к scala).
Есть ли у вас больше таких советов?