2011-07-10 16 views
5

Podczas wdrażania modeli wykorzystujących wzorzec MVC, jak złożone powinny być moje modele?Jak złożone powinny być modele?

Powiedzmy mam kilka stolików tak:

  • użytkownika (identyfikator, hasło, stworzony ...)
  • e-maile (user_id, e-mail ...)
  • adresów (user_id , adres ...)

Posiadam kontroler o nazwie UserController. Sterownik ten powinien pozwolić mi do użytkowników w dzienniku tworzyć użytkowników, itp

<!-- language: php --> 
class UserController{ 

    public function create($array){ 
     ... 
    } 

    public function login($email, $password){ 
     ... 
    } 
} 

Gdyby moi modele są bardzo prymitywne, implemeting tylko poprzez operacje CRUD ORM? Spowodowałoby to w kodzie jak:

<!-- language: php --> 
class UserController{ 

    public function create($array){ 
     $userModel->username = 'blah'; 
     $userModel->blah = 'blah'; 
     $id = $userModel->save(); 

     $emailModel->id = $id; 
     $emailModel->email = "emailhere"; 
     $emailModel->save(); 

     //Do the same for addresses 
    } 

    public function login($email, $password){ 
     ... 
    } 
} 

lub, alternatywnie, mógłbym modele, które są bardziej skomplikowane:

<!-- language: php --> 
UserModel{ 
    public function login($email, $password){ 
     //Do the joining and checking here, then return true or false to the controller 
    } 
} 

Wtedy w moim kontrolera:

<!-- language: php --> 
userModel->login($mail, $password); 

tak, która jest lepszy sposób? Przerzucić całą logikę na modele, czy też mam modele, które wykonują tylko podstawowe operacje CRUD? Na koniec, jak mam sobie radzić z połączeniami tabel? Czy powinny być obsługiwane w modelu, czy w kontrolerze?

Cheers

+0

nie jest użytkownikiem, który musi mieć metodę logowania, ale system lub model auth. Obiekt użytkownika nadal nie istnieje przed zalogowaniem. –

+1

Wystarczy notatkę: Dlaczego masz model e-mail? Czy nie powinno wystarczyć pole e-mail w modelu użytkownika? – Alp

+0

Użytkownicy mogą mieć wiele adresów e-mail powiązanych ze swoim kontem w tej aplikacji. – F21

Odpowiedz

3

Większość ludzi myśli o „Fat Models, chude kontrolerów” paradygmat, i to działa lepiej w dłuższej perspektywie.

Ogromną zasadą jest myśleć o swoich modelach jako o ich własnej istocie, w tym sensie, że gdyby np. Przenieść swoje modele do innej struktury, nadal by działały.

Prostym przykładem byłoby zapisanie informacji o zamówieniu w witrynie e-commerce. Załóżmy, że chcesz zapisać informacje o podatku, a mianowicie ile podatku znajduje się w zamówieniu. Abstrakcyjnym sposobem osiągnięcia tego celu jest ...

$tax_amount = $order_amount * (TAX_PERCENTAGE/100);

powinniśmy zrobić to w kontrolerze lub modelu? Załóżmy, że zrobiliśmy to w kontrolerze, cóż ... w naszej akcji tworzenia i akcji aktualizacji obliczalibyśmy podatek, co utrudniało utrzymanie kodu i zmiany reguł biznesowych witryny e-commerce (powiedzmy, zacznij sprzedawać do firm zwolnionych z podatku lub z zagranicy), wtedy będziemy musieli zmienić dowolnego kontrolera, który zapisuje informacje o zamówieniu.

Gdybyśmy jednak obliczyli podatek w naszym modelu zamówienia, robilibyśmy to raz w naszej metodzie save(), która byłaby wywoływana podczas edycji i dodawania zamówień.

public function save() { 
    //calculate tax first 
    $q = $this->db->query($sql); 
} 

Imo, to lepiej egzekwować reguł biznesowych w modelu, ponieważ to sprawia, że ​​bardziej przenośne kodu i mniej bólów głowy, jeśli chodzi o utrzymanie kodu. Oczywiście są ludzie, którzy się nie zgodzą, a to bardzo subiektywny obszar.

EDIT:

Stosując to do konkretnego pytania, które prosił, myśleć o tym, czy będzie kiedykolwiek potrzebne metody nigdzie indziej login() ale model użytkownik? Możliwe, że chcesz podzielić swoje modele na inne, bardziej szczegółowe. Ale w takim przypadku możesz rozszerzyć swój model użytkownika.

Co się stanie, jeśli całkowicie zdejmiesz kontroler? Lub jeśli chcesz, aby interfejs z modelami w zupełnie inny sposób (powiedzmy za pomocą innej struktury w przyszłości). Myśląc w ten sposób, lepiej byłoby, gdybyś użył swojej metody logowania w swoim modelu użytkownika.

Osobiście chciałbym stworzyć metodę logowania na moim modelu, ponieważ jest to operacja na danych i do tego służą nasze modele. Chciałbym również stworzyć na moim kontrolerze metodę loginAction(), która zainicjowałaby metodę login() w naszym modelu i wykonać dowolną inną akcję (na przykład, nieudane próby/przekierowanie dziennika), które musi się zdarzyć po zalogowaniu, jeśli to się uda lub nieskuteczne. Przykładem loginAction() może wyglądać następująco ...

class UserController extends GenericController { 
    public function loginAction() { 
     $post = $this->form->getPost(); 
     if(UserModel::login($post)) { 
      //do something 
     } else { 
      //do something else 
     } 
    } 
} 
+0

Czy możesz również podać swoją opinię na temat pierwszego pytania z użytkownikiem/loginem? – Alp

+0

Czytałem również o "Modelach tłuszczu i chudych kontrolerach". Czy w moim przypadku czynności w moim kontrolerze powinny być w zasadzie pełnomocnikami operacji w moim modelu? Na przykład UserController-> login() powinien po prostu wywołać UserModel-> login()? – F21

+0

Edytowałem swoją odpowiedź, aby wyrazić moją opinię na temat konkretnego problemu. – JamesHalsall

0

Wszystkie funkcje, które będą lub mogą być ponownie wykorzystane w różnych częściach we wniosku powinny być accessbile globalnie, tak, że sprzęgło jest niska i nie ma potrzeby, aby go redeclare .

Myślę, że potrzebujesz dodatkowego modelu do autoryzacji i/lub aktualnych parametrów systemu. AuthModel może przechowywać informacje o różnych rolach autoryzacji, a SysModel zapisuje parametry aplikacji, takie jak domyślne ustawienia logowania (np. Użyj plików cookie tak lub nie).

Metodę logowania można następnie umieścić w AuthModel, co moim zdaniem powinno być dobrym miejscem. Również modele są odpowiedzialne za weryfikację wprowadzonych danych, więc tworzenie nowych użytkowników powinno znajdować się w UserModelu.

+0

Załóżmy, że mam AuthModel z funkcją logowania. Muszę połączyć e-maile i użytkowników, aby ustalić, czy istnieje ważne konto. Czy powinienem mówić do EmailModel i UserModel za pomocą ORM, aby ustalić, czy mogę się zalogować? A może powinienem użyć bezpośredniego SQL? Czy powinienem mieć nawet EmailModel? – F21

+0

Powiedziałeś, że każdy użytkownik może mieć dowolną liczbę e-maili, co prowadzi do obecności EmailModel. Tak więc twoja metoda 'AuthModel: login()' musi komunikować się zarówno z UserModel, jak i EmailModel, aby ustalić, czy logowanie jest w porządku. – Alp