Scala имеет два инструмента для выражения композиции объекта: оригинальную концепцию самонаведения и известную тривиальную композицию. Я любопытно, в каких ситуациях я должен использовать это.
Существуют очевидные различия в их применимости. Самостоятельный тип требует использования признаков. Состав объекта позволяет изменять расширения во время выполнения с объявлением var.
Оставляя технические детали, я могу представить два показателя, чтобы помочь в классификации вариантов использования. Если какой-либо объект используется как комбинатор для сложной структуры, такой как дерево, или просто имеет несколько аналогичных типизированных частей (соотношение между 1 автомобилем и 4 колесами), то он должен использовать композицию. Существует крайний противоположный случай использования. Предположим, что одна черта становится слишком большой, чтобы четко ее наблюдать, и она раскололась. Вполне естественно, что для этого случая вы должны использовать self-types.
Эти правила не являются абсолютными. Вы можете сделать дополнительную работу для преобразования кода между этими методами. например вы можете заменить 4 состава колес на самонабор по продукту4. Вы можете использовать Cake[T <: MyType] {part : MyType}
вместо Cake { this : MyType => }
для зависимостей шаблона торта. Но оба случая кажутся противоречивыми и дают вам дополнительную работу.
Есть много случаев использования границ. Отношения "один-к-одному" очень сложно решить. Есть ли какое-то простое правило, чтобы решить, какая техника предпочтительнее?
self-type делает классы абстрактными, состав делает ваш код многословным. самонадеянность дает вам проблемы с смешиванием пространств имен, а также дает вам дополнительную распечатку бесплатно (у вас есть не просто коктейль из двух элементов, а бензиновый моторный коктейль, известный как бензиновая бомба).
Как я могу выбрать между ними? Какие намеки есть?
Update:
Обсудим следующий пример:
Шаблон адаптера. Какие преимущества у него есть как при наборе текста, так и в композиционном подходе?