У світі Java (точніше, якщо у вас немає багаторазового успадкування / мікшину), емпіричне правило досить просте: "Надавайте перевагу композиції об'єкта над успадкуванням класу".
Я хотів би знати, чи / як це змінюється, якщо ви також розглядаєте міксини, особливо в Scala?
Чи вважаються міксини способом багаторазового успадкування чи більшим складом класу?
Чи існує також вказівка "Надати перевагу композиції об'єкта порівняно зі складом класу" (або навпаки)?
Я бачив чимало прикладів, коли люди використовують (або зловживають) мікшинами, коли композиція об’єктів також може виконати цю роботу, і я не завжди впевнений, який з них кращий. Мені здається, що з ними можна досягти досить подібних речей, але є також деякі відмінності, деякі приклади:
- видимість - з мікшинами все стає частиною публічного API, чого не можна сказати про композицію.
- багатослівність - у більшості випадків міксини менш багатослівні і дещо простіші у використанні, але це не завжди так (наприклад, якщо ви також використовуєте власні типи в складних ієрархіях)
Я знаю, що коротка відповідь "Це залежить", але, мабуть, буває якась типова ситуація, коли те чи інше краще.
Деякі приклади вказівок, які я міг би придумати до цього часу (припускаючи, що я маю дві риси A і B, і A хоче використовувати деякі методи з B):
- Якщо ви хочете розширити API A методами з B, то змішуйте, інакше склад. Але це не допомагає, якщо клас / екземпляр, який я створюю, не є частиною загальнодоступного API.
- Якщо ви хочете використовувати деякі шаблони, для яких потрібні міксини (наприклад, шаблон, що складається з ознак ), це просте рішення.
- Якщо у вас є кругові залежності, тоді можуть допомогти поєднання з власними типами. (Я намагаюся уникати цієї ситуації, але це не завжди легко)
- Якщо вам потрібні певні динамічні рішення, як виконувати композицію, а потім композицію об’єкта.
У багатьох випадках міксини здаються простішими (і / або менш багатослівними), але я впевнений, що вони також мають деякі підводні камені, такі як "клас Бога" та інші, описані у двох статтях artima: частина 1 , частина 2 (BTW it Мені здається, що більшість інших проблем не є актуальними / не такими серйозними для Scala).
У вас є більше таких підказок?
this => Logging
? Він не компілюється.