Cechy były jednym z największych dodatków w PHP 5.4. Znam składnię i rozumiem ideę kryjącą się za cechami, takimi jak poziome ponowne wykorzystanie kodu do typowych rzeczy, takich jak logowanie, bezpieczeństwo, buforowanie itp.
Jednak nadal nie wiem, jak wykorzystałbym cechy w moich projektach.
Czy są jakieś projekty open source, które już używają cech? Jakieś dobre artykuły / materiały do czytania na temat tworzenia struktur architektur przy użyciu cech?
Odpowiedzi:
Osobiście uważam, że podczas pisania czystego kodu zastosowanie cech jest bardzo niewiele.
Zamiast używać cech do włamania kodu do klasy, lepiej jest przekazać zależności za pomocą konstruktora lub ustawiających:
Głównym powodem, dla którego uważam, że jest to lepsze niż używanie cech, jest to, że twój kod jest znacznie bardziej elastyczny dzięki usunięciu twardego sprzężenia z cechą. Na przykład możesz teraz po prostu przekazać inną klasę rejestratora. To sprawia, że twój kod jest wielokrotnego użytku i testowalny.
źródło
Wydaje mi się, że przez jakiś czas należałoby przyjrzeć się językom, które mają cechy, aby poznać przyjęte dobre / najlepsze praktyki. Moja obecna opinia na temat Trait jest taka, że powinieneś używać ich tylko do kodu, który musiałbyś powielać w innych klasach, które mają tę samą funkcjonalność.
Przykład cechy Loggera:
A potem robisz ( demo )
Myślę, że ważną rzeczą do rozważenia podczas używania cech jest to, że tak naprawdę są to tylko fragmenty kodu, które są kopiowane do klasy. Może to łatwo prowadzić do konfliktów, na przykład przy próbie zmiany widoczności metod, np
Powyższe spowoduje błąd ( demo ). Podobnie, żadne metody zadeklarowane w trait, które są już zadeklarowane w klasie using nie zostaną skopiowane do klasy, np.
wypisze 2 ( demo ). Są to rzeczy, których będziesz chciał uniknąć, ponieważ utrudniają one znalezienie błędów. Będziesz także chciał uniknąć przypisywania rzeczy cechom operującym na właściwościach lub metodach klasy, która z nich korzysta, np
działa ( wersja demonstracyjna ), ale teraz cecha jest ściśle powiązana z A i cała idea ponownego wykorzystania w poziomie zostaje utracona.
Postępując zgodnie z zasadą segregacji interfejsów , będziesz mieć wiele małych klas i interfejsów. To sprawia, że cechy są idealnym kandydatem do rzeczy, o których wspomniałeś, np. Przekrojów , ale nie do komponowania obiektów (w sensie strukturalnym). W powyższym przykładzie Loggera cecha jest całkowicie izolowana. Nie ma zależności od konkretnych klas.
Moglibyśmy użyć agregacji / kompozycji (jak pokazano w innym miejscu na tej stronie), aby osiągnąć tę samą wynikową klasę, ale wadą korzystania z agregacji / kompozycji jest to, że będziemy musieli ręcznie dodać metody proxy / delegatora do każdej klasy, a następnie powinno móc się logować. Cechy dobrze to rozwiązują, pozwalając mi trzymać szablon w jednym miejscu i selektywnie go stosować w razie potrzeby.
Uwaga: biorąc pod uwagę, że cechy są nową koncepcją w PHP, wszystkie opinie wyrażone powyżej mogą ulec zmianie. Nie miałem jeszcze zbyt wiele czasu, aby samemu ocenić koncepcję. Mam jednak nadzieję, że wystarczy, aby dać Ci coś do przemyślenia.
źródło
:) Nie lubię teoretyzować i debatować o tym, co z czymś zrobić. W tym przypadku cechy. Pokażę ci, do czego są przydatne cechy i możesz się z tego nauczyć lub zignorować.
Cechy - świetnie nadają się do stosowania strategii . Krótko mówiąc, wzorce projektowania strategii są przydatne, gdy chcesz, aby te same dane były obsługiwane w inny sposób (filtrowane, sortowane itp.).
Na przykład masz listę produktów, które chcesz odfiltrować na podstawie pewnych kryteriów (marki, specyfikacje, cokolwiek) lub posortować według różnych środków (cena, etykieta, cokolwiek). Możesz utworzyć cechę sortowania, która zawiera różne funkcje dla różnych typów sortowania (numeryczne, ciąg, data itp.). Możesz następnie użyć tej cechy nie tylko w swojej klasie produktu (jak podano w przykładzie), ale także w innych klasach, które wymagają podobnych strategii (aby zastosować sortowanie numeryczne do niektórych danych itp.).
Spróbuj:
Na koniec myślę o cechach, takich jak akcesoria (których mogę użyć do zmiany moich danych). Podobne metody i właściwości, które można wyciąć z moich klas i umieścić w jednym miejscu, dla łatwej obsługi, krótszego i czystszego kodu.
źródło
strategies
.Jestem podekscytowany cechami, ponieważ rozwiązują one częsty problem podczas tworzenia rozszerzeń dla platformy e-commerce Magento. Problem występuje, gdy rozszerzenia dodają funkcjonalność do klasy podstawowej (na przykład modelu użytkownika), rozszerzając ją. Odbywa się to poprzez wskazanie autoloaderowi Zend (poprzez plik konfiguracyjny XML), aby używał modelu użytkownika z rozszerzenia, a nowy model rozszerza model podstawowy. ( przykład ) Ale co, jeśli dwa rozszerzenia zastępują ten sam model? Otrzymujesz „stan wyścigu” i tylko jeden jest załadowany.
Obecnie rozwiązaniem jest edycja rozszerzeń, tak aby rozszerzyć klasę przesłaniania modelu drugiej strony w łańcuchu, a następnie ustawić konfigurację rozszerzenia tak, aby ładowała je we właściwej kolejności, tak aby łańcuch dziedziczenia działał.
Ten system często powoduje błędy, a podczas instalowania nowych rozszerzeń konieczne jest sprawdzenie konfliktów i edycja rozszerzeń. To jest uciążliwe i przerywa proces aktualizacji.
Myślę, że użycie cech byłoby dobrym sposobem na osiągnięcie tego samego bez tego irytującego modelu zastępującego „stan wyścigu”. To prawda, że nadal mogą występować konflikty, jeśli wiele cech zaimplementuje metody o tych samych nazwach, ale wyobrażam sobie, że coś takiego jak prosta konwencja przestrzeni nazw może rozwiązać ten problem w większości.
TL; DR Myślę, że cechy mogą być przydatne do tworzenia rozszerzeń / modułów / wtyczek dla dużych pakietów oprogramowania PHP, takich jak Magento.
źródło
Możesz mieć cechę dla obiektu tylko do odczytu, taką jak ta:
Możesz wykryć, czy ta cecha jest używana i określić, czy powinieneś zapisać ten obiekt w bazie danych, pliku itp.
źródło
use
tę cechę, zadzwoniif($this -> getReadonly($value))
; ale spowodowałoby to błąd, gdybyś nie miałuse
tej cechy. Dlatego ten przykład jest błędny.