Modele na tabelę bazy danych?

11

Korzystam z Codeigniter i znalazłem się w podobnej sytuacji, w której powtórzyłem metody Model. Tworzę model dla kontrolera. Ale czy tworzenie modelu według tabeli bazy danych byłoby uważane za dobrą praktykę? W ten sposób metody nie są pisane dwukrotnie.

Zamiast modelu na kontroler lub kilku małych modeli, które są współużytkowane.

Przykład, jeśli mam metodę modelową get_user ($ user_id), mógłbym napisać ją na users_models.php ...

Jedną z wad, jakie widzę, jest to, że być może będę musiał wywołać kilka modeli, a nie tylko controlername_models.php.

Czy załadowanie kilku modeli, w których nie można zastosować kilku metod ze sterownika, może wpłynąć na wydajność i szybkość? Jaki może być najlepszy sposób rozwiązania tego problemu?

Uwaga: Istnieją podobne pytania, ale nie obejmują one podstaw Modelu według tabeli bazy danych.

Howard Steff
źródło

Odpowiedzi:

8

Mówię, że model na tabelę po prostu odtwarza twoją bazę danych w strukturze klas. Jest znany jako model anemiczny i uważany za anty-wzór. Jest tak, ponieważ klasy mają mieć zarówno dane, jak i zachowanie. Jeśli ograniczysz swoje modele do jednej tabeli, gdzie umieścisz kod (zachowanie), które musi radzić sobie z danymi i zachowaniem z wielu tabel? Twoje kontrolery będą wtedy potrzebować modeli, które wykorzystują jeden lub więcej z tych modeli „tabelowych” ... Więc oprócz najbardziej podstawowych aplikacji, zyskujesz niewiele, jeśli w ogóle, dzięki takiemu podejściu.

Marjan Venema
źródło
To tylko dodatek - uważany jest przez Martina Fowlera za anty-wzór. Zatrzymaj się tutaj. Ma pewien wgląd w tę sprawę, ale to nie znaczy, że jest zła - w przeciwieństwie do God Object, która prawie zawsze jest zła, taka struktura jest czasami niewiarygodnie przydatna i łatwa w obsłudze. W ogóle nie uważam tego za anty-wzór.
T. Sar
1
Na przykład „model anemiczny” jest zgodny z SOLID - czy naprawdę źle jest mieć obiekt o jednym celu (przechowywać dane)? Chociaż szanuję wiele rzeczy, które mówi pan Fowler, to była bzdura.
T. Sar
7

Zasadniczo należy tworzyć modele nie dla tabeli lub dla kontrolera, ale dla obiektu biznesowego. Czasami może to być relacja 1: 1 ze strukturą tabel lub kontrolerami, ale nie jest to konieczne.

W twoim przykładzie możesz mieć jedną users_modelklasę wywoływaną z kilku kontrolerów. To jest w porządku, a czasem nawet pożądane. Jednak w większości przypadków users_modelklasa otrzyma dane z kilku tabel.
Na przykład last_login_datewłaściwość users_modelklasy można ( nie trzeba ) uzyskać z oddzielnej user_audittabeli, która ma relację jeden do wielu z userstabelą główną .

Powiedziałbym, że jeśli masz jedną tabelę SQL na obiekt biznesowy, najprawdopodobniej struktura bazy danych nie jest znormalizowana.

Moneta dziesięciocentowa
źródło
3

W większości zgadzam się z odpowiedzią Dime'a, że ​​chcesz tworzyć modele dla każdego obiektu biznesowego - problemy, które firma próbuje rozwiązać, powinny determinować sposób tworzenia klas modeli. W praktyce odkryłem, że dobrym pomysłem jest stworzenie jednego modelu na stół. Prawidłowo zaprojektowany schemat prawdopodobnie naśladuje procesy biznesowe, które należy modelować w kodzie aplikacji - zwanym także modelem domeny.

Korzystanie z warstwy mapowania obiektów / relacji jest przydatne, dlatego model domeny zawiera te same relacje co schemat bazy danych bez potrzeby powtarzalnych wywołań do warstwy dostępu do danych. Sprawdź Eloquent dla PHP jako przykład. Zarówno schemat, jak i model domeny powinny być zaprojektowane do obsługi procesów biznesowych.

To prowadzi do pierwszej części odpowiedzi Marjana Venema:

Mówię, że model na tabelę po prostu odtwarza twoją bazę danych w strukturze klas. Jest znany jako model anemiczny i uważany za anty-wzór.

Anemic Domain model jest anty-wzór. „Model na tabelę”, jak sugeruje Venema, może być postrzegany jako „odtwarzanie bazy danych”, jednak absolutnie niepoprawne jest twierdzenie, że sam jest anemicznym modelem domeny.

Od Martina Fowlera:

Podstawowym objawem modelu domeny anemicznej jest to, że na pierwszy rzut oka wygląda jak prawdziwa. Istnieją obiekty, z których wiele nazwano na cześć rzeczowników w przestrzeni domen, a obiekty te są powiązane z bogatymi relacjami i strukturą, jakie mają prawdziwe modele domen. Haczyk pojawia się, gdy spojrzysz na zachowanie i zdasz sobie sprawę, że prawie nie ma żadnego zachowania na tych obiektach, co czyni je niewiele więcej niż worki osób pobierających i ustawiających.

(podkreślenie, moje)

Kluczowym czynnikiem w anemicznym modelu domeny jest brak zachowania lub metod w klasach modelu domeny.

Jest tak, ponieważ klasy mają mieć zarówno dane, jak i zachowanie. Jeśli ograniczysz swoje modele do jednej tabeli, gdzie umieścisz kod (zachowanie), które musi radzić sobie z danymi i zachowaniem z wielu tabel?

Ponownie, możesz i powinieneś umieścić zachowanie w swoich modelach domen, nawet jeśli są one mapowane tylko do jednej tabeli. Zachowanie, które wpływa na wiele tabel, naprawdę wpływa na wiele obiektów, które przypadkiem są mapowane na wiele tabel. Domain Driven Design to podejście do dokładnie tego samego problemu, o którym wspomniał Venema: „gdzie umieszczasz kod (zachowanie), który musi radzić sobie z danymi i zachowaniem z wielu tabel?”

Odpowiedź brzmi: Korzeń zagregowany . Martin Fowler stwierdza:

Agregat to wzorzec w projektowaniu opartym na domenie. Agregat DDD to klaster obiektów domeny, który można traktować jako pojedynczą jednostkę. Przykładem może być zamówienie i jego elementy zamówienia, będą to oddzielne obiekty, ale przydatne jest traktowanie zamówienia (wraz z jego elementami zamówienia) jako pojedynczej agregacji.

(podkreślenie, moje)

„Klaster obiektów domenowych” można również wyświetlić jako „Modele domenowe odwzorowane na wiele tabel”. Zachowanie, które wpływa na wiele tabel, powinno być zdefiniowane w katalogu głównym agregacji - klasa, która zawiera „rzecz”, która wpływa na wiele tabel lub obiektów:

Ponownie od Martina Fowlera:

Agregat często będzie zawierał wiele zbiorów wraz z prostymi polami.

Aby odpowiedzieć na oryginalne pytanie PO:

... czy tworzenie modelu według tabeli bazy danych byłoby uważane za dobrą praktykę? W ten sposób metody nie są pisane dwukrotnie.

Powiedziałbym, że jest to dobre miejsce na rozpoczęcie, ale należy pamiętać, że twój schemat i model obiektowy nie muszą się zgadzać w 100%. Model obiektowy powinien bardziej koncentrować się na wdrażaniu i egzekwowaniu reguł biznesowych. Schemat powinien bardziej koncentrować się na przechowywaniu danych biznesowych w sposób modułowy i skalowalny.

Model na kontroler nie byłby dobrą praktyką, chociaż istnieje odmiana modelu o nazwie Model widoku, który pasuje do warstwy Kontrolera. Widok Model jest reorganizacja modelu domeny, aby dopasować pewien rodzaj wyświetlacza, czy jest to strona internetowa lub forma w aplikacji GUI.

Greg Burghardt
źródło