8

Czytałem na wielu frameworkach PHP, szczególnie w Zend Framework, ale jestem już zdezorientowany co do właściwego sposobu na kontynuowanie.Czy wzór DataMapper łamie MVC?

Zend Framework nie używa ActiveRecords, ale zamiast tego korzysta z wzorca Table Data Gateway i Row Data Gateway, i używa DataMappera do mapowania zawartości Row Data Gateway do modelu, ponieważ ActiveRecord rozkłada się, gdy twoje modele nie mapowanie 1: 1 do tabel bazy danych. W przewodniku Zend Quickstart znajduje się example of this.

Dla mnie ich przykład wygląda bardzo rozdęty z mnóstwem kolekcjonerów w całym miejscu. Natknąłem się na różne posty na blogach na temat Domain Driven Design, argumentując, że używanie tylu pobierających i ustawiających jest złą praktyką, ponieważ eksponuje wszystkie wewnętrzne dane modelu na zewnątrz, więc nie ma żadnej przewagi nad atrybutami publicznymi. Here is one example.

Moje pytanie: Jeśli usuniesz te pobierające i ustawiające, w jaki sposób renderujesz swoje widoki? W pewnym momencie dane muszą trafić w widok, aby rzeczywiście pokazać coś użytkownikowi. Postępowanie zgodnie z poradą DDD wydaje się przełamać separację między M i V w MVC. Podążanie za przykładem MVC i Zend wydaje się przerwać DDD i pozostawia mi pisanie wielu pobierających, ustawiających i DataMapperów dla wszystkich moich modeli. Oprócz dużego nakładu pracy wydaje się, że narusza ona także system DRY.

Naprawdę doceniam niektóre (linki do) dobrych przykładów lub więcej informacji o tym, jak to wszystko razem pasuje. Próbuję poprawić tutaj moje umiejętności projektowania i projektowania.

Odpowiedz

2

Korzystając z obiektów wartości, można wyeliminować niektóre z tych metod ustawiania publicznego. Oto opis the difference between Entity and Value Objects. Obiekty wartości są niezmienne i często związane z Jednostką. Jeśli przekazujesz wszystkie wartości do konstruktora, nie musisz ustawiać tych właściwości z zewnętrznego kodu.

coś ekstra, które nie są bezpośrednio związane z odpowiedzią, ale bardziej skoncentrowane na DDD:

(Zastrzeżenie: Jedyne co wiem o Zend Framework jest to, co czytałem w połączonej artykułu.) Zend Framework używa DataMapperów zamiast repozytoriów. Czy to naprawdę DDD-ish? Cóż, Fowler's interpretation of a Repository może powiedzieć "nie". Jednak Eric Evans stwierdza, że ​​repozytorium DDD może być bardzo proste. W najprostszym przypadku Repozytorium jest a DataMapper (patrz książka DDD). Dla czegoś bardziej złożonego i wciąż DDD zobacz artykuł Fowlera. DDD posiada repozytorium pojęciowe, które może różnić się od definicji wzoru.

Zachęcam do dalszego czytania o projektowaniu opartym na domenie. Myślę, że istnieje luka w założeniu, że podmioty pobierające i ustanawiające naruszają DDD. DDD koncentruje się na modelu domeny i najlepszych praktykach, aby to osiągnąć. Akcesory to tylko drobny szczegół.

+0

Dzięki. Ten artykuł z Devlicious dobrze się czyta. Przeczytam także resztę serii. –

+0

To jest dobra odpowiedź, a ja dodam, że nie jest źle z pobierającymi, ustawiającymi. W rzeczywistości posiadanie ich jest doskonałym sposobem na dodanie logiki walidacji. Upublicznianie właściwości jest szybkie i brudne i jest w porządku podczas tworzenia prototypów, ale nie jest doskonałym rozwiązaniem długoterminowym. Załóżmy, że chcesz zmienić nazwę nieruchomości. Jeśli to zrobisz, każdy fragment kodu, który uzyskuje dostęp do tej właściwości, musi się zmienić. Jeśli używasz nazwy ogólnej dla metody akcesora, nie musisz zmieniać kodu klienta. Ponadto Doctrine jest znacznie bogatszym rozwiązaniem niż Zend DB. Nie polecałbym Doctrine1, ale wypróbuj Doctrine2. –

2

Nie musisz implementować wszystkich modułów pobierających/ustawiających, możesz użyć funkcji _get() i __set(). W czym więc jest problem?

1

Z mojego czytania postu, pytanie jest bardziej filozoficzne niż praktyczne.

Nie mam czasu, aby napisać dogłębnie, ale oto moje dwa centy. Chociaż zgadzam się, że chcesz ograniczyć liczbę żądań get i set, ponieważ klasa powinna ukrywać swoje wewnętrzne, musisz również wziąć pod uwagę, że Java i PHP są różnymi narzędziami i mają różne cele. W środowisku sieciowym klasy są budowane i usuwane z każdym żądaniem, a zatem napisany kod nie powinien zależeć od wielkich klas. W artykule, który wskazałeś, autor sugeruje umieszczenie logiki widoku w klasie. To prawdopodobnie nie ma sensu w sieci, ponieważ prawdopodobnie będę chciał przedstawić widok w wielu formatach (rss, html, etc ...). Stosowanie metod dostępu (otrzymanie zestawu &) jest zatem złem koniecznym. Nadal chcesz ich używać w zamyśleniu, aby nie strzelać sobie w stopę. Kluczem jest, aby twoje klasy zrobiły dla ciebie pracę, zamiast próbować zmusić ich do pracy na zewnątrz. Uzyskując dostęp do swoich właściwości za pomocą metody zamiast bezpośrednio ukrywasz wewnętrzne elementy, które chcesz.

Jeszcze raz ten post mógłby posłużyć się przykładami, ale nie mam teraz czasu.

Czy ktoś inny może podać kilka przykładów, dlaczego metody dostępu nie są złe?

+0

Dzięki. Moje pytanie jest bardziej filozoficzne niż praktyczne. Umieszczenie logiki widoku w modelu domeny wydawało mi się problematyczne (ponieważ narusza to MVC) i to właśnie spowodowało pytanie. Mam nadzieję, że zobaczę kilka praktycznych przykładów, które jasno pokazują teorię w działaniu. Jeśli rzeczywiście jest to równowaga między Domain Driven Design a MVC, chciałbym zobaczyć, jak inni rozwiązują pozorny konflikt między nimi. –

0

pobierające i ustawiające wykonawcza ma dwie zalety, moim oczom:

  1. Można wybrać, które właściwości do publicznej wiadomości, więc nie muszą wystawiać wszystkich wewnętrznych w modelu
  2. Jeśli użyj IDE z autouzupełnianiem, wszystkie dostępne właściwości będą TAB, gdy zaczniesz pisać "get" lub "set" - to sam dla mnie wystarczający powód.
1

Są tu dwa podejścia: To, co nazywam podejściem "nie pytaj", a drugie podejście typu ViewModel/DTO. Zasadniczo pytania koncentrują się wokół tego, jaki jest "model" w twoim widoku. Powiedz, nie pytaj wymaga, aby jedynym sposobem, w jaki obiekt może być uzewnętrzniany, jest sam obiekt. Innymi słowy, aby renderować obiekt, miałbyś metodę renderowania, ale ta metoda renderowania musiałaby rozmawiać z interfejsem. coś takiego:

class DomainObject { 
    .... 
    public function render(DomainObjectRenderer $renderer) { 
     return $renderer->renderDomainObject(array $thegorydetails); 
    } 
} 

W kontekście Zend Framework można podklasy Zend_View i mieć swój podklasa wdrożyć ten interfejs.

Zrobiłem to już wcześniej, ale jest trochę nieporęczne.

Druga opcja polega na przekonwertowaniu modelu domeny na obiekt ViewModel, który jest podobny do uproszczonego, spłaszczonego, "ciągniętego" widoku danych, dostosowanego do każdego określonego widoku (z jednym modelem ViewModel na widok), oraz w drodze powrotnej przekonwertuj dane POST na EditModel.

Jest to bardzo popularny wzorzec w świecie ASP.NET MVC, ale jest również podobny do wzorca "DTO" używanego do przesyłania danych między "warstwami" w aplikacji. Będziesz musiał stworzyć twórców odwzorowań, aby wykonać dla ciebie brudną robotę (w przeciwieństwie do DataMappera). W PHP 5.3 możesz użyć odbicia, aby zmienić prywatne właściwości, więc Twój obiekt DomainObject nie musi nawet się ujawniać!