Rozważ ten przykład:
Mam stronę internetową Pozwala użytkownikom tworzyć posty (mogą być dowolne) i dodawać tagi opisujące posty. W kodzie mam dwie klasy reprezentujące post i tagi. Nazwijmy te klasy Post
i Tag
.
Post
zajmuje się tworzeniem postów, usuwaniem postów, aktualizowaniem postów itp.
Tag
zajmuje się tworzeniem tagów, usuwaniem tagów, aktualizowaniem tagów itp.
Brak jednej operacji. Łączenie tagów z postami. Walczę z tym, kto powinien wykonać tę operację. Może pasować równie dobrze w obu klasach.
Z jednej strony Post
klasa może mieć funkcję, która przyjmuje Tag
jako parametr, a następnie przechowuje ją na liście znaczników. Z drugiej strony Tag
klasa może mieć funkcję, która przyjmuje Post
jako parametr i łączy z Tag
właściwością Post
.
Powyższe to tylko przykład mojego problemu. Tak naprawdę mam do czynienia z wieloma podobnymi klasami. Może pasować równie dobrze w obu. Poza faktem umieszczenia funkcjonalności w obu klasach, jakie konwencje lub style projektowania istnieją, aby pomóc mi rozwiązać ten problem. Zakładam, że musi być coś poza wybraniem jednego?
Może umieszczenie go w obu klasach jest prawidłową odpowiedzią?
źródło
Nie, nie w obu! Powinien być w jednym miejscu.
Niepokojące w moim pytaniu jest to, że mówisz „
Post
dba o tworzenie postów, usuwanie postów, aktualizowanie postów” i to samoTag
. Cóż, to nie w porządku.Post
może zająć się tylko aktualizacją, to samo dotyczyTag
. Tworzenie i usuwanie jest dziełem kogoś innego, zewnętrznegoPost
iTag
(nazwijmy toStore
).Dobra odpowiedzialność za
Post
to „zna autora, treść i datę ostatniej aktualizacji”. Dobra odpowiedzialność zaTag
to „zna jego nazwę i cel (czytaj: opis)”. Dobra odpowiedzialność zaStore
to: „zna wszystkie posty i wszystkie tagi oraz może je dodawać, usuwać i wyszukiwać”.Jeśli spojrzysz na tych trzech uczestników, kto w naturalny sposób powinien mieć wiedzę na temat relacji Post-Tag?
(dla mnie jest to Post, wydaje się naturalne, że „zna swoje tagi”; wyszukiwanie wsteczne (wszystkie posty dla tagu) wydaje się być zadaniem Sklepu; chociaż mogę się mylić)
źródło
ConditionalWeakTable
(zakładając, że ktoś ma szczęście, aby mieć strukturę, w której istnieje)?W równaniu brakuje ważnego szczegółu. Dlaczego tag zawiera post i visa-versa? Odpowiedź na to pytanie określa rozwiązanie dla każdego zestawu.
Ogólnie mogę sobie wyobrazić podobną sytuację. Pudełko i zawartość. Pudełko ma zawartość, więc odpowiedni jest związek typu „ma związek”. Czy zawartość może mieć pudełko? Jasne, pudełko z pudełkiem. Pudełko to zawartość. Ale IS-A nie jest dobrym projektem dla wszystkich pudeł. W takim przypadku rozważyłbym wzór dekoratora. W ten sposób pudełko jest w razie potrzeby ozdabiane zawartością w czasie wykonywania.
Tagi mogą mieć również posty, ale dla mnie nie jest to związek statyczny. Raczej może to być raport o wszystkich postach z tym tagiem. W tym przypadku jest to nowy byt, nie ma-a.
źródło
Podczas gdy w teorii takie rzeczy mogą pójść w obie strony, w praktyce, gdy zabierzesz się do implementacji, jedna droga jest prawie zawsze lepsza niż druga. Mam przeczucie, że będzie lepiej pasować do
Post
klasy, ponieważ skojarzenie zostanie utworzone podczas tworzenia lub edycji postu, gdy inne rzeczy dotyczące postu zmieniają się w tym samym czasie.Ponadto, jeśli kojarzysz wiele tagów i chcesz to zrobić w ramach jednej aktualizacji bazy danych, przed wykonaniem aktualizacji musisz utworzyć listę wszystkich tagów powiązanych z tym samym postem. Ta lista pasuje znacznie lepiej w
Post
klasie.źródło
Osobiście nie dodałbym tej funkcji do żadnego z nich.
Dla mnie oba
Post
iTag
są obiektami danych, więc nie powinno być funkcjonalność obsługi bazy danych. Powinny po prostu istnieć. Są przeznaczone do przechowywania danych i mogą być wykorzystywane przez inne części aplikacji.Zamiast tego miałbym inną klasę odpowiedzialną za logikę biznesową i dane dotyczące Twojej strony internetowej. Jeśli twoja strona wyświetla post i pozwala użytkownikom dodawać tagi, klasa miałaby
Post
obiekt i zawierałaby funkcjonalność do dodaniaTags
do niegoPost
. Jeśli strona wyświetla tagi i pozwala użytkownikom dodawać posty do tych tagów, zawierałbyTag
obiekt i miałby funkcję dodawaniaPosts
do niegoTag
.Ale to tylko ja. Jeśli uważasz, że musisz obsłużyć funkcjonalność bazy danych w swoich obiektach danych, polecam odpowiedź pdr
źródło
Gdy czytam to pytanie, pierwszą rzeczą, która przyszła mi do głowy, była relacja bazy danych Many To Many . Posty mogą mieć wiele tagów ... Tagi mogą mieć wiele postów .... Wydaje mi się, że obie klasy potrzebują do pewnego stopnia zarządzania tą relacją.
Z punktu widzenia Publikuj ...
Jeśli podczas edytowania lub tworzenia postu działaniem dodatkowym staje się zarządzanie relacjami z tagami .
IMO, stworzenie zupełnie nowej TAG nie należy tutaj.
Z punktu widzenia tagu ...
Możesz utworzyć tag bez konieczności przypisywania go do posta. Jedyne działanie, które widzę, które dotyczy interakcji z postem, to funkcja usuwania znaczników. Jednak ta funkcja powinna być niezależną niezależną funkcją.
Działa to tylko wtedy, gdy istnieje tabela łączy bazy danych, która rozwiązuje relację wiele do wielu
źródło