Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Przybliżenie zasady SRP
Szymciosek
post
Post #1





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Witam,
prosiłbym o podanie przykładu np na klasie logowania lub obsługi użytkowników (logowanie, rejestracja, walidacja, usuwanie itd).
Jak to rozbić wg. zasady SRP?
Szukam na internecie różnych wątków na ten temat, ale nie bardzo mi to podchodzi i pomyślałem, że może tu mi pomożecie pokazując to na przykładzie bardziej życiowym.

Pozdrawiam
Szymon
Go to the top of the page
+Quote Post
!*!
post
Post #2





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

Ostrzeżenie: (0%)
-----


A co to jest SPR?
Go to the top of the page
+Quote Post
Szymciosek
post
Post #3





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


SRP - Single Responsibility Principle

Nie pisałem tego, bo myślałem, że ktoś wie.
Go to the top of the page
+Quote Post
!*!
post
Post #4





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

Ostrzeżenie: (0%)
-----


Nie słyszałem, choć ma to nawet sens o ile ktoś lubi się rozdrabniać. Uważam że jeśli Twoja klasa ma więcej niż 300 linijek kodu, to robisz coś źle, ale to tylko moje zdanie i całkowicie się z nim zgadzam (IMG:style_emoticons/default/wink.gif)

Wpisałem w google "Single Responsibility Principle" i wyskoczyło kilka sensownych artów z wyjaśnieniem nawet po polsku.
http://sprawnainzynieriaoprogramowania.blo...-principle.html (jest też 2 część)
http://przemyslawczatrowski.com/2010/07/15...ple-w-praktyce/

Pytanie, dlaczego chcesz to stosować i czy w Twojej aplikacji się to przyda?
Go to the top of the page
+Quote Post
nospor
post
Post #5





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
SRP - Single Responsibility Principle

Nie pisałem tego, bo myślałem, że ktoś wie.

SRP - Secure Remote Password
(IMG:style_emoticons/default/smile.gif)

Tak więc na przyszłość wyjaśniaj od razu czego dokładnie szukasz, bo skróty mogą mieć różne znaczenia.
Go to the top of the page
+Quote Post
Szymciosek
post
Post #6





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Czy stosować to inna sprawa, po prostu chodzi o wyczucie pisania klasy wg. tejże zasady.
Co klasa obsługi użytkownika np. UserManager może zawierać w sobie, a co już będzie za dużo itd?
Go to the top of the page
+Quote Post
Crozin
post
Post #7





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Logowanie, rejestracja, walidacja czy bliżej nieokreślone usuwanie to już mocno złożone operacje, które niejednokrotnie wymagają współpracy dziesiątek różnego rodzaju obiektów - tak więc raczej nikt nie będzie tutaj wpisywał tak sporego przykładu.

Chcesz trzymać się zasady pojedynczej odpowiedzialności? Odpowiedz sobie na pytanie za co odpowiedzalny jest dany obiekt/klasa - jeżeli użyjesz w odpowiedzi "i", "lub", "albo", "oraz" czy czegoś w tym stylu, najprawdopodobniej nie trzymasz się tej zasady.

Cytat
Co klasa obsługi użytkownika np. UserManager może zawierać w sobie, a co już będzie za dużo itd?
Może zawierać w sobie dużo różnych rzeczy. Przyrostek "manager" nie mówi kompletnie nic.
Go to the top of the page
+Quote Post
Szymciosek
post
Post #8





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Czyli wg. Twojej teorii Crozin, klasa, która będzie obierała dane z formularza, następnie te dane sprawdzała z danymi z bazy i na koniec w przypadku zgodności tworzyła sesję, w której będę trzymał informację o zalogowaniu jest przykładem na poziomie zasady pojedynczej odpowiedzialności?
Dalej: Logowania i rejestracja w takim przypadku są osobnymi klasami, które działają na podobnej zasadzie, czyli pobranie danych z formularza, walidacja itd?

Jeszcze gdzieś wyczytałem na jakimś blogu w wątku o SRP, że klasa taka powinna współpracować z formularzem, że jak zmieniam np ilość pól czy nazwę pola w formularzu, to powinno to współgrać z klasą np. Login. Czy dobrze to rozumiem, że zanim rozpocznę pracę z klasą Login, powinienem jej przekazać dane dotyczące formularza tj. jakie pola posiada żeby później zmienić to tylko w liniach $obj->addElement('username')?
http://sebastian-malaca.blogspot.com/2013/...onsibility.html tutaj jest ten przykład.

Kolejne pytanie jakie mi się nasuwa, to czy mogę bezpośrednio z formularz uruchomić klasę Login? Sterowanie całością mam w index.php, gdzie na podstawie url ładowane są potrzebne klasy, ale zastanawia mnie czy taką drogą mogę odebrać dane z index.php, który zostanie przeładowany (zostanie załadowany login.php) w login.php i czy takie rozwiązanie jest dobre i bezpieczne?

mam teraz coś w tym stylu:
index.php
  1. ...
  2. <body>
  3. <?php
  4. //tutaj sprawdzam czy jest sesja, jesli nie, to uruchamiam widok login.html
  5. include_once 'login.html'; // ogólnie ładowane w ten sposób będą widoki w zależności od podstrony //tutaj jest formularz logowania zawierający pola username oraz password, który posiada przekierowanie na www.xxx.pl/login i wtedy jest uruchamiana klasa Login
  6. ?>
  7. </body>
  8. ...


klasa Login.php lub LoginController mogłaby wtedy wyglądać jakoś tak?
  1. class Login
  2. {
  3. public function __construct()
  4. {
  5. //pobranie danych z $_POST
  6. // $this->username = $_POST['username']; (IMG:style_emoticons/default/questionmark.gif)
  7. $this->validate();
  8. }
  9.  
  10. private function validate()
  11. {
  12. //sprawdzenie pobranych wyżej danych z danymi z bazy
  13. //jakis if, ktory porówna dane
  14. }
  15.  
  16. private function doLogin()
  17. {
  18. //stworzenie sesji, jesli validate na to pozwala
  19. }
  20. }



EDIT:
Pisząc tego posta doszedłem do wniosku, że mogę przesłać dane z formularza do klasy Login.php, ale zostaje jeszcze kwestia czy jest to dobre i bezpieczne?

Ten post edytował Szymciosek 28.01.2013, 22:34:35
Go to the top of the page
+Quote Post
Crozin
post
Post #9





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
Czyli wg. Twojej teorii Crozin, klasa, która będzie obierała dane z formularza, następnie te dane sprawdzała z danymi z bazy i na koniec w przypadku zgodności tworzyła sesję, w której będę trzymał informację o zalogowaniu jest przykładem na poziomie zasady pojedynczej odpowiedzialności?
Napisałem, że jeżeli jesteś wstanie wymienić kilka zadań stawianych przed obiektem to "jest źle". Tutaj podałeś cały szereg zadań i pytasz się "czy tak jest dobrze". Nie, tak nie jest dobrze.
Go to the top of the page
+Quote Post
Szymciosek
post
Post #10





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Tylko czy jest sens rozbijać taką klasę? Przecież wszystkie te metody są ze sobą połączone.
Go to the top of the page
+Quote Post
!*!
post
Post #11





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

Ostrzeżenie: (0%)
-----


Odpowiedz sobie na pytanie czy jest Ci to w ogóle potrzebne. IMO jest to sztuka dla sztuki.
Jeśli myślisz na poważnie o OOP, to zrezygnuj z czegoś takiego:

  1. <?php
  2. //tutaj sprawdzam czy jest sesja, jesli nie, to uruchamiam widok login.html
  3. include_once 'login.html'; // ogólnie ładowane w ten sposób będą widoki w zależności od podstrony //tutaj jest formularz logowania zawierający pola username oraz password, który posiada przekierowanie na www.xxx.pl/login i wtedy jest uruchamiana klasa Login
  4. ?>


To jest źle. I jeśli uczysz się o OOP, to zabrałeś się nieco od złej strony. Przeczytaj cały wątek http://pl.wikibooks.org/wiki/PHP/Czym_jest...ie_obiektowe%3F jak to opanujesz, zaimplementuj MVC (lub cokolwiek co jest jego odłamem) i dopiero później kombinuj jaki wzorzec wybrać.
Teraz jak to zaimplementujesz, to w którymś momencie stwierdzisz że to głupota i będziesz musiał przepisać 90% kodu.

A jeśli już mówimy o rozbiciu odpowiedzialności, to Login, Rejestracja i Walidacja są osobnymi klasami, czyli na przykładzie:

  1. class Login
  2. {
  3. public function __construct()
  4. {
  5. //pobranie danych z $_POST
  6. // $this->username = $_POST['username'];
  7.  
  8. }
  9.  
  10. private function next()
  11. {
  12. $v = new Validation();
  13. $v -> addValid($this->username);
  14. if($v->ok) // jesli walidacja jest poprawna
  15. {
  16. return true;
  17. }
  18. return false;
  19. }
  20.  
  21. public function costam()
  22. {
  23. if($this->next()) {return true} //jesli metoda next() zwraca true to znaczy że mozna sie zalogowac itd.
  24. }
  25. }
  26.  
  27. $l = new Login;
  28. if($l->costam())
  29. {
  30. // moge sie zalgoowac
  31. }
  32. else
  33. {
  34. // wyswietl bledy formularza
  35. }


Ten post edytował !*! 29.01.2013, 11:02:12
Go to the top of the page
+Quote Post
LSM
post
Post #12





Grupa: Zarejestrowani
Postów: 64
Pomógł: 6
Dołączył: 20.03.2011
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Wszystkie zasady jak SRP, prawo Demeter itp. oczywiście są super jednak należy do nich dążyć, a nie bezwzględnie ich przestrzegać. Często nie ma takiej potrzeby. Nie ma co na siłę wdrażać wszystkich fajnych zasad, bo można sobie pofolgować i w ekstremalnym przypadku SRP - jedna klasa będzie zawierać tylko jedną metodę. Także spokojnie z tymi wytycznymi. ;-) Każdy sam powinien znać moment aby powiedzieć: stop, dalej nie refaktoryzuję!
Go to the top of the page
+Quote Post
Szymciosek
post
Post #13





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Już to zrozumiałem i wiem, że wiele przychodzi z czasem czyt. w trakcie pisania kodu, gdzie w końcu dostrzegasz jakieś zależności między A i B i możesz sobie to zrobić inaczej, prościej.
Go to the top of the page
+Quote Post
pyro
post
Post #14





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


!*!, ja rozumiem, że to miał być tylko orientacyjny punkt odniesienia, ale ten kod co podałeś to zwykła maniana, a początkującym to nie służy, więc może na następny raz jakiś lepszy przykład?

// ADD

A nie. Ty po prostu najzwyczajniej w świecie klepiesz bzdury.

Cytat(!*! @ 28.01.2013, 17:11:21 ) *
Nie słyszałem, choć ma to nawet sens o ile ktoś lubi się rozdrabniać. Uważam że jeśli Twoja klasa ma więcej niż 300 linijek kodu, to robisz coś źle, ale to tylko moje zdanie i całkowicie się z nim zgadzam ;)

Go to the top of the page
+Quote Post
!*!
post
Post #15





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

Ostrzeżenie: (0%)
-----


pyro - dużo wniosłeś do tematu, rozumiem że śnieg za oknem, ale mimo wszytko jest już koniec marca, nie stycznia.
A teraz to uzasadnij, skoro już zacząłeś. Miałem tu napisać cały mechanizm? Jeśli Ty upychasz wszytko w jednym pliku, który ma po kilka tysięcy linijek kodu, to Twoja sprawa (IMG:style_emoticons/default/smile.gif) co zresztą zaznaczyłem.
Go to the top of the page
+Quote Post
pyro
post
Post #16





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(!*! @ 26.03.2013, 14:51:32 ) *
pyro - dużo wniosłeś do tematu, rozumiem że śnieg za oknem, ale mimo wszytko jest już koniec marca, nie stycznia.
A teraz to uzasadnij, skoro już zacząłeś. Miałem tu napisać cały mechanizm?


Dobrze, uzasadnię. Po pierwsze nie mówię o napisaniu całego mechanizmu. Mówię że kod, który przedstawiłeś tutaj w tym temacie jest beznadziejny, a nie kod którego nie ma lub jeszcze nie ma.

Przykładowe błędy:
1. Odwoływanie się do danych w konstruktorze, brak możliwości ich ustawiania.
2. Brak jakiejkolwiek hermetyzacji.
3. Nic nie mówiące nazwy, a wręcz mylące (przypomina to metody Iteratora)
4. Wielokrotne tworzenie tego samego obiektu wewnątrz jednej metody.
5. Nieprawidłowa (nieprawidłowa to pojęcie względne - po prostu słaba) implementacja walidacji
6. Niepotrzebna zależnośc od innych klas.


To tylko przykładowe błędy dla tych 30 linijek kodu.

Cytat(!*! @ 26.03.2013, 14:51:32 ) *
Jeśli Ty upychasz wszytko w jednym pliku, który ma po kilka tysięcy linijek kodu, to Twoja sprawa (IMG:style_emoticons/default/smile.gif) co zresztą zaznaczyłem.


Równie dobrze mogłeś powiedzieć, że jestem chamem, bo kupuję zbożowe batoniki za 1,20zł zamiast za 1,00zł. Widzisz, żebym gdzieś coś wspominał o pakowaniu kilku tysięcy linijek kodu do jednego pliku? Bo ja nie za bardzo. Wyraziłeś się dośc precyzyjnie - "więcej niż 300 linijek" kodu i nie, nie brałem tego dosłownie, że już 305 linijek to źle. Prawidłowość i funkcjonalność klasy nie ma w ogóle nic wspólnego z ilością kodu w niej zawartego, ale od implementacji kodu. Istnieje ogrom plików tworzonych przez profesjonalistów (mówię o takich z prawdziwego zdarzenia), których klasy sięgają grubo ponad 1000 linijek. Przykład: Twig (od twórcy Symfony) albo nawet Symfony. W obu istnieje wiele plików, których ilośc kodu to ponad 1000 linijek. Przecież to kilkukrotnie ponad Twoją granicę! Czyli wszyscy Ci programiści są tacy beznadziejni (IMG:style_emoticons/default/sad.gif) ?
Go to the top of the page
+Quote Post
Szymciosek
post
Post #17





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Możesz napisać taki mały pliczek biorąc pod uwagę błędy, które wytknąłeś? Czyli te 6 punktów.
Go to the top of the page
+Quote Post
!*!
post
Post #18





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

Ostrzeżenie: (0%)
-----


pyro = cham! a nawet burżuj kupujący batoniki za 1,20zł! (IMG:style_emoticons/default/tongue.gif)

Cytat
Przykładowe błędy:
1. Odwoływanie się do danych w konstruktorze, brak możliwości ich ustawiania.
2. Brak jakiejkolwiek hermetyzacji.
3. Nic nie mówiące nazwy, a wręcz mylące (przypomina to metody Iteratora)
4. Wielokrotne tworzenie tego samego obiektu wewnątrz jednej metody.
5. Nieprawidłowa (nieprawidłowa to pojęcie względne - po prostu słaba) implementacja walidacji
6. Niepotrzebna zależnośc od innych klas.


1. Nie uwierzysz, ale nie o to chodziło
2. patrz punkt 1
3. tu się zgodzę, sam nie wiem co mną kierowało, zdarza się.
4. to nie błąd, choć można by to upchnąć w zmiennej, jak tak bardzo Cie to razi, tym bardziej że nie odwołujesz sie w Loginie w nieskończenie wiele razy.
5. to już tylko Twoje zdanie.
6. patrz punkt 5

Cytat
Czyli wszyscy Ci programiści są tacy beznadziejni ?

W dużym skrócie... Tak. Choć to ni jak ma się do tematu... A jeśli uznasz, że uznałem ich za beznadziejnych, to przeczytaj jeszcze raz pierwszą część zdania (IMG:style_emoticons/default/wink.gif)

Cytat
Możesz napisać taki mały pliczek biorąc pod uwagę błędy, które wytknąłeś? Czyli te 6 punktów.

Dobry pomysł.
Pyro odnieś się do tematu, popraw mój kod lub napisz własny. Tylko ładnie, bo po kilku miesiącach przyjdzie ktoś z batonikami za 1,60zł i będzie dym.

Ten post edytował !*! 26.03.2013, 16:16:06
Go to the top of the page
+Quote Post
pyro
post
Post #19





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(!*! @ 26.03.2013, 16:09:54 ) *
1. Nie uwierzysz, ale nie o to chodziło
2. patrz punkt 1


Zdaje sobie sprawę, że nie o to chodziło, dlatego mój pierwszy post wyglądał dokładnie tak:

Cytat(pyro)
!*!, ja rozumiem, że to miał być tylko orientacyjny punkt odniesienia, ale ten kod co podałeś to zwykła maniana, a początkującym to nie służy, więc może na następny raz jakiś lepszy przykład?


Ale skoro widzę, że nie rozumiesz tych prostych słów, sformułuję to inaczej:

Ktoś zadał pytanie propo OOP, bo go nie do końca rozumie, inaczej by chyba nie było pytania. Chyba trudno się z tym nie zgodzić? Ty podajesz swój prototyp, który jest błędny z w/w powodów. Ja sobie zdaję z tego sprawę, że to miał być wzór, ale ktoś mający z tym problemy widząc takie coś może zapożyczyć te błędne rzeczy w swoim kodzie. A Ty nigdzie nie napisałeś w komenatarzach nic w stylu "Nie powinieneś tak robić", "to tylko wzór, ale normalnie powinieneś zrobić to tak i tak" itp, więc ktoś może uznać, że takie praktyki są dobre, a nie są. Chciałbym Ci przypomnieć, że pisałeś tego posta dla innych (bo nie jedna osoba zajrzy do tego tematu), a nie dla siebie. No chyba że prowadzisz monolog... (IMG:style_emoticons/default/smile.gif)

Cytat(!*!)
4. to nie błąd, choć można by to upchnąć w zmiennej, jak tak bardzo Cie to razi, tym bardziej że nie odwołujesz sie w Loginie w nieskończenie wiele razy.


To jest błąd. To coś jak napisanie czegoś w stylu:

  1. // ŹLE
  2. $aArr = array_fill(0, 10000, '!*! robi podstawowe błędy programistyczne!');
  3. for($i=0; $i < count($aArr); $i++)
  4. {
  5. echo $aArr[$i].PHP_EOL;
  6. }


zamiast:

  1. // DOBRZE
  2. $aArr = array_fill(0, 10000, '!*! robi podstawowe błędy programistyczne!');
  3. $iArrCount = count($aArr);
  4. for($i=0; $i < $iArrCount; $i++)
  5. {
  6. echo $aArr[$i].PHP_EOL;
  7. }


Cytat
5. to już tylko Twoje zdanie.
6. patrz punkt 5


Nie. To nie jest Tylko moje zdanie. To wbrew zasadom OOP. Polecam Tobie lekturę do poduszki "Rusz głową! Wzorce projektowe", gdzie są poruszane nie tylko wzorce projektowe, ale także zasady dobrej implementacji kodu, a to co Ty uważasz za moją opinię jest tam uznane za błąd. No chyba, że masz zamiar dodać również tych programistów do Twojej listy "kiepskich programistów" (IMG:style_emoticons/default/smile.gif) .

Przykładowa sensowna implementacja poniżej, bo nie wiem czy się zmieści w jednym poście:
Go to the top of the page
+Quote Post
!*!
post
Post #20





Grupa: Zarejestrowani
Postów: 4 298
Pomógł: 447
Dołączył: 16.11.2006

Ostrzeżenie: (0%)
-----


Cytat
Zdaje sobie sprawę, że nie o to chodziło, dlatego mój pierwszy post wyglądał dokładnie tak:

Chodziło o to że wypisałeś "błędy" które nie miały sensu, a odniosłem się do punktów jakie wymieniłeś, już rozumiesz?

  1. To jest błąd. To coś jak napisanie czegoś w stylu:

Kompletnie nie trafiony przykład, szczególnie że w przypadku Loginu nie ma to znaczenia, chyba że piszesz jakieś kompletne bzdury, odwołując się więcej niż raz, do metody. Weź poprawkę na to, że cały czas mowa o klasie Login.
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 22:05