Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: OOP struktura klasy cz.2
Forum PHP.pl > Forum > PHP > Object-oriented programming
rahul
Po zrobieniu klasy User i UserManager (poprzedni post) przyszedl czas na stworzenie komponentu odpowiedzialnego za Logowanie i sprawdzanie Sesji. Z tego co juz zrozumialem klasy User i UserManager nie powinny miec z tym nic wspolnego, zakladam zatem ze potrzebuje klase Login badz jakas inna ktora bedzie te funkcje posiadac. Do tego przy kazdym przeladowaniu strony potrzebuje cos co sprawdza czy sesja juz istnieje, czy to tez jest zadanie dla loginu czy kolejnego osobnego komponentu ? Lopatologiczne wyjasnienia mile widziane.
mike
Cytat(rahul @ 28.08.2011, 10:59:39 ) *
(...) zakladam zatem ze potrzebuje klase Login badz jakas inna ktora bedzie te funkcje posiadac
Nie. Login to czynność a nie klasa. Potrzebujesz klasy w stylu SessionManagement (nazwij jak chcesz, aby nie Login), która będzie miała funkcjonalność logowania.
Fanatyko
Moje pytanie w moim temacie:
Cytat
Zakładając, że chcę napisać klasę do logowania/rejestracji, jak powinienem to rozdzielić ? Osobna klasa do rejestracji i logowania, czy np. ogólnie klasa która będzie odpowiadała za te czynności ?


Odpowiedź użytkownika @smentek

Cytat
Im mniejsze czyli bardziej rozdrobnione obiekty tym lepszy system. Z drugiej strony jeżeli ma to być prosty system to nie ma sensu sztucznie go komplikować, tak że możesz rejestracje i logowanie zrobić w jednym obiekcie, tylko niech to nie będzie ten sam obiekt który reprezentuje użytkownika. Może 'UserAuthorisation'?


Może Ci się przyda wink.gif
cer98
Dobrze jest zrozumieć ideę autoryzacji i autentykacji.
LSM
Możesz to zrobić na bardzo wiele sposobów. Najpierw przemyśl czy i jak system będzie rozbudowywany. Mógłbyś zrobić klasę ogólną System, która byłaby odpowiedzialna za spr. sesji i zasobów, które ta sesja posiada.
  1. // uzytkownik wywołał akcję $objSystemController->login();
  2. public function login()
  3. {
  4. strHashResourceId = SessionManager::getUserHash();
  5. System::isLogged( $strHashResourceId );
  6. }

Przydałoby Ci się to w sytuacji gdzie zalogowany mógłby być nie tylko użytkownik ale np. zewnętrzny system. W klasie System chciałbyś wtedy zablokować korzystanie z systemu innym użytkownikom. Jeśli chcesz w ten sposób rozwijać projekt dobrze odseparować logikę zarządzania sesją właśnie do jakiejś osobnej klasy (System lub SessionLogger).

Inny patent to ustalenie w jakim stanie (userIsLogged, extSystemIsLogged, awaria, aktualizacja [...] ) znajduje się aplikacja. Tutaj też mógłbyś użyć klasy System. Wtedy w tejże klasie sprawdzałbyś stan całej aplikacji i udostepniał np. tylko niektóre zasoby jeśli system miałby jakąś awarie, ma to swoje wady/zalety/zależności.

Ale na początek zrobiłbym spr. sesji w najprostszy sposób jaki Ci odpowiada. Potem mógłbyś zmienić całość pod kątem pełniejszego zarządzania procesem logowania, jeśli uznasz że jest Ci to potrzebne.
Pamietaj, że rozbijanie odpowiedzialności ma swoje implikacje w rozrastaniu się kodu. Dlatego trzeba zawsze myśleć o tym co jest potrzebne na teraz, na za miesiąc i potem za rok czy dwa (czego nie jesteś w stanie już tak prosto określić). Więc trzymaj się prostoty i zbytnio nie uelastyczniaj aplikacji na początku, bo można się zamotać. Aplikacje można doskonalić w nieskończoność.
ano
Moim zdaniem mógłbyś zrobić to w taki sposób:

  1. public function login() {
  2. $sessionManager = System::getInstance()->getSessionManager();
  3.  
  4. if($sessionManager['user']) {
  5. return 'zalogowany'; //nic nie trzeba robić
  6. }
  7.  
  8. else {
  9. $login = $_POST['login']; // nie traktuj tych dwóch linijek całkiem poważnie. To powinno być zrealizowane w inny sposób
  10. $password = $_POST['password']; // np w taki: $this->getParam('login'); gdzie getParam filtruje dane itp.
  11.  
  12. $userManager = new UserManager();
  13. $user = $userManager->login($login, $password)
  14.  
  15. if($user) { // to lepiej za pomocą wyjątków try { } catch(UserNotFoundException $e) {} }
  16. $sessionManager['user'] = serialize($user); //zalogowany! do sesji został dodany obiekt użytkownika
  17. }
  18. }
  19.  
  20. }
  21.  
  22. public function showLogged() {
  23. $sessionManager = System::getInstance()->getSessionManager();
  24. print_r($sessionManager['user']);
  25. }


a teraz opis
klasa System jest singletonem (zobacz na wiki).
Przechowuje wszystkie 'kluczowe' dla aplikacji obiekty. Typu np SessionManager, może DBManager? tongue.gif
System::getInstance()->getSessionManager() zwraca obiekt SessionManagera który implementuje interfejs ArrayAccess dlatego można używać cudów jak $sManager['user'], ale powinna być też możliwość $sManager->get($user); itp

$sessionManager['user'] = serialize($user) - czyli przypisujesz do klucza sesji 'user' zserializowany obiekt użytkownika.

i voila!
CuteOne
Jeżeli nie masz dostępu do głównych obiektów inaczej niż przez kontener(w dodatku Singleton) to coś z Twoją aplikacją jest chyba nie tak? a może się mylę?
LSM
Klasa System nie musi być singletonem. Może spełniać rolę fasady. Dostęp do SessionManager może być również bezpośredni jeśli tak sobie to założysz. Ja wykorzystuje klasę System do paru podstawowych ogólnych czynności na wjazd i wyjazd z programu. Inny przykład $objSystem->setDeathView() co powoduje wykrozystanie klasy ustawiającej barwy strony na szare ($objColorizer) jak ktoś sławny kopyrtnie headsetsmiley.png . Jeśli ta klasa zacznie mi się rozrastać to powyrzucam części kodów do innych, ale narazie jakoś daje radę istnieć.
ano
Cytat(CuteOne @ 24.09.2011, 13:46:10 ) *
Jeżeli nie masz dostępu do głównych obiektów inaczej niż przez kontener(w dodatku Singleton) to coś z Twoją aplikacją jest chyba nie tak? a może się mylę?


z mojego kodu nic takiego przecież nie wynika.
To jak sobie zaimplementujesz zależy od Ciebie.
Ta metoda:
System::getInstance()->getDatabaseManager();
może wyglądać chociażby tak
  1. {
  2. return DatabaseManager::getInstance(); // LUB return $this->databaseManager; - DBM nie musi być singletonem.
  3. }


albo

  1. {
  2. return $this->register['DatabaseManager'];
  3. }


albo w ogóle nie mieć metody getDatabaseManager i takie obiekty zaprojektować jako singletony i 'brać je': DatabaseManager::getInstance()

to zależy od Ciebie jak to zaimplementujesz.
bastard13
Ale tych singletonów Ci się narobi w kodzie:)
Chcesz klasę do obsługi dwóch akcji: logowania i sprawdzania czy ktoś jest zalogowany . Do tego dodaj sobie jeszcze dwie akcje: wylogowanie i zwracanie zalogowanego użytkownika, bo jest to wszystko logicznie ze sobą powiązane. Jednym słowem potrzebujesz klasy do obsługi autoryzacji:
  1. class Authorization {
  2. public function login($login, $password);
  3. public function logout();
  4. public function isLogged(); //zwraca true, jeżeli jest ktoś zalogowany, false w innym wypadku
  5. public function getLoggedUser(); //zwraca zalogowanego użytkownika
  6. }

Do pełnej funkcjonalności są ci potrzebne jeszcze klasy do obsługi sesji, opcjonalnie cookie i do obsługi połączeń z bazą.
Żadna z tych klas nie powinna być singletonem, ponieważ nie ma ku temu żadnych powodów.
Klasy do obsługi sesji i ciasteczek i tak korzystają z globalnych tablic, więc po co ci implementowanie ich jako singletonów? Po to, żeby było:
  1. Session::getInstance()->method();

Zamiast:
  1. $session = new Session();
  2. $session->method();

A co do połączeń z bazą, to już tym bardziej jest to nie logiczne, bo co w przypadku, gdy będziesz obsługiwał x połączeń z różnymi bazami?
Sama aplikacja (czy też system, czy jak to tam nazwiesz) również nie ma żadnego większego powodu, żeby była singletonem, bo po co? Zastosowanie wzorca ma sens, wtedy i tylko wtedy, gdy ma sens:) Jeżeli nie ma żadnego logicznego uzasadnienia do używania wzorca, to się tego nie robi. Nawet jeżeli tworzysz zazwyczaj (albo nawet zawsze) tylko jeden obiekt danej klasy, to nie jest to żadnym uzasadnieniem do stosowania singletonu. Singleton stosujesz wtedy, gdy nie może być dwóch obiektów tego samego typu.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.