Существует три распространенных способа, AFAIK, для реализации возможности повторного использования, когда дело доходит до ООП.
- Наследование: обычно представляет собой отношения (утка это птица)
- Состав: как правило, для обозначения отношения (автомобиль имеет двигатель)
- Черты (например, ключевое слово trait в PHP): ... не совсем уверен в этом
Хотя мне кажется, что черты могут реализовывать отношения «есть» и «есть», я не совсем уверен, для какого типа моделирования он был предназначен. Для каких ситуаций были разработаны черты?
object-oriented-design
Extrakun
источник
источник
Ответы:
Черты являются еще одним способом сделать композицию. Думайте о них как о способе составления всех частей класса во время компиляции (или JIT-компиляции), собирая конкретные реализации частей, которые вам понадобятся.
По сути, вы хотите использовать черты, когда вы делаете уроки с различными комбинациями функций. Эта ситуация возникает чаще всего для людей, пишущих гибкие библиотеки для других. Например, вот объявление класса модульного теста, который я недавно написал с использованием ScalaTest :
Раздел рамки испытаний имеют массу различных вариантов конфигурации, и каждая команда имеет разные предпочтения о том , как они хотят , чтобы делать вещи. Помещая параметры в черты (которые смешиваются при использовании
with
в Scala), ScalaTest может предложить все эти опции без необходимости создавать имена классов, напримерWordSpecLikeWithMatchersAndFutures
, или тонну логических флагов времени выполнения, подобныхWordSpecLike(enableFutures, enableMatchers, ...)
. Это позволяет легко следовать принципу « открыто / закрыто» . Вы можете добавлять новые функции и новые комбинации функций, просто добавив новую черту. Это также облегчает следование принципу сегрегации интерфейса , потому что вы можете легко поместить функции, которые не всегда необходимы, в черту.Черты также являются хорошим способом поместить общий код в несколько классов, которые не имеют смысла разделять иерархию наследования. Наследование - это очень тесно связанные отношения, и вы не должны оплачивать эти расходы, если можете помочь. Черты - намного более слабосвязанные отношения. В моем примере выше я
MyCustomTrait
легко делил реализацию фиктивной базы данных между несколькими иначе не связанными тестовыми классами.Внедрение зависимостей позволяет достичь многих из тех же целей, но во время выполнения на основе пользовательского ввода, а не во время компиляции на основе ввода программиста. Черты также предназначены больше для зависимостей, которые семантически являются частью одного и того же класса. Вы как бы собираете части одного класса, а не вызываете другие классы с другими обязанностями.
Инъекционное Dependency рамки достижение многих из тех же целей во время компиляции на основе ввода программиста, но в основном обходной путь для языков программирования без надлежащей поддержки признака. Черты привносят эти зависимости в область средства проверки типов компилятора с более чистым синтаксисом и более простым процессом сборки, что делает более четкое различие между зависимостями времени компиляции и времени выполнения.
источник
with
Оператор , что отличает их, иwith
является операцией композиции. И да, черты заменяют DI без необходимости определения в точке входа кода. Это одна из вещей, которая делает их предпочтительными по моему мнению.