Istnieją trzy powszechne sposoby AFAIK na wdrożenie wielokrotnego użytku, jeśli chodzi o OOP
- Dziedziczenie: zwykle w celu przedstawienia związku jest (kaczka jest ptakiem)
- Skład: zwykle reprezentuje relację „ma związek” (samochód ma silnik)
- Cechy (np. Słowo kluczowe cecha w PHP): ... naprawdę nie jestem tego pewien
Chociaż wydaje mi się, że cechy mogą implementować zarówno relacje typu „a”, jak i „to”, nie jestem do końca pewien, do jakiego rodzaju modelowania był przeznaczony. Do jakich sytuacji zaprojektowano cechy?
object-oriented-design
Extrakun
źródło
źródło
Odpowiedzi:
Cechy to kolejny sposób na komponowanie. Pomyśl o nich jako o sposobie komponowania wszystkich części klasy w czasie kompilacji (lub w czasie kompilacji JIT), składając konkretne implementacje potrzebnych części.
Zasadniczo chcesz korzystać z cech, gdy tworzysz zajęcia z różnymi kombinacjami funkcji. Sytuacja ta pojawia się najczęściej u osób piszących elastyczne biblioteki, z których mogą korzystać inni. Na przykład, oto deklaracja klasy testu jednostkowego, którą ostatnio napisałem za pomocą ScalaTest :
Struktury testów jednostkowych mają mnóstwo różnych opcji konfiguracji, a każdy zespół ma inne preferencje co do tego, jak chcą to robić. Umieszczając opcje w cechach (które są mieszane przy użyciu
with
w Scali), ScalaTest może zaoferować wszystkie te opcje bez konieczności tworzenia nazw klas, takich jakWordSpecLikeWithMatchersAndFutures
, lub ton flagi logicznej środowiska wykonawczego, takich jakWordSpecLike(enableFutures, enableMatchers, ...)
. Ułatwia to przestrzeganie zasady otwartej / zamkniętej . Możesz dodać nowe funkcje i nowe kombinacje funkcji, po prostu dodając nową cechę. Ułatwia także przestrzeganie zasady segregacji interfejsów , ponieważ łatwo można umieścić w funkcji cechy, które nie są powszechnie potrzebne.Cechy są również dobrym sposobem na umieszczenie wspólnego kodu w kilku klasach, które nie mają sensu współdzielić hierarchii dziedziczenia. Dziedziczenie jest związkiem bardzo ściśle powiązanym i nie powinieneś ponosić tych kosztów, jeśli możesz mu pomóc. Cechy są relacją znacznie bardziej luźno powiązaną. W powyższym przykładzie
MyCustomTrait
z łatwością korzystałem z udawanej implementacji bazy danych między kilkoma niezwiązanymi ze sobą klasami testów.Wstrzykiwanie zależności osiąga wiele takich samych celów, ale w czasie wykonywania na podstawie danych wejściowych użytkownika zamiast w czasie kompilacji na podstawie danych programisty. Cechy są również przeznaczone bardziej dla zależności, które są semantycznie częścią tej samej klasy. Gromadzisz części jednej klasy, a nie dzwonisz do innych klas z innymi obowiązkami.
Ramy wstrzykiwania zależności osiągają wiele takich samych celów w czasie kompilacji w oparciu o dane programistyczne, ale w dużej mierze są obejściem dla języków programowania bez odpowiedniego wsparcia cech. Cechy wprowadzają te zależności do dziedziny sprawdzania typu kompilatora, z czystszą składnią, z prostszym procesem kompilacji, który czyni wyraźniejsze rozróżnienie między zależnościami czasu kompilacji i środowiska wykonawczego.
źródło
with
Operator jest to, co je odróżnia, awith
to działanie kompozycji. I tak, cechy zastępują DI bez konieczności definiowania w punkcie wejścia kodu. To jedna z rzeczy, która sprawia, że moim zdaniem są lepsze.