Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: SOLID i Zasada jednej odpowiedzialności
Forum PHP.pl > Forum > PHP > Object-oriented programming
Nortonek
Witam

Mam prośbę o nakierowanie mnie na temat pierwszej zasady SOILID, jak można zastosować tą zasadę dla tych klas i takiego wywołania,

w pierwszej klasie odwołuję się do drugiej, jednak znając życie będzie taka sytuacja że będę musiał przekazać więcej parametrów a nie tylko ID książki

i będę musiał modyfikować 2 klasy.


  1. <?php
  2.  
  3.  
  4. class Ksiazki {
  5.  
  6. private $id_ksiazki;
  7.  
  8. function __construct($id){
  9. $this->id_ksiazki - $id;
  10. }
  11.  
  12. private function zapisz_oddanie_zniszczonej_ksiazki(){
  13. global $db, $table_ksiazki_oddane;
  14.  
  15. $result0 = $db -> Execute("UPDATE $table_ksiazki_oddane SET `oddana`= '1' WHERE `id_ksiazki`='".$this->id_ksiazki."' ");
  16.  
  17. $Ksiazki_Zniszczone = new Ksiazki_Zniszczone();
  18. $Ksiazki_Zniszczone-> insert_ksiazki_zniszczone($this->id_ksiazki);
  19. }
  20.  
  21. }
  22.  
  23.  
  24. class Ksiazki_Zniszczone{
  25.  
  26. public function insert_ksiazki_zniszczone( $id_ksiazki){
  27. global $db, $table_ksiazki_zniszczone;
  28.  
  29. $result0 = $db -> Execute("UPDATE $table_ksiazki_zniszczone SET `zniszczenie_ksiazki`= '5' WHERE `id_ksiazki`='$id_ksiazki' ");
  30. }
  31.  
  32. }
  33.  
  34. ?>
Crozin
Na sam początek: nie próbuj samemu robić mapowania bazy danych na model obiektowy (ORM). Jest to wbrew pozorom dosyć skomplikowane zadanie i bez odpowiedniej wiedzy ciężko Ci będzie zrobić cokolwiek co będzie miało jakieś zalety w porównaniu do "zwykłego klepania zapytań". Skorzystaj z Doctrine'a, w większości miejsc jest on całkiem dobrym przykładem zasad SOLID.

Co do Twojego kodu:
1. Powinieneś przekazywać obiekty jako argumenty, a nie ich wewnętrzne właściwości.
2. Jeżeli klasa ma za zadanie reprezentować pojedynczy obiekt (np. książkę) powinna nazywać się Książka, nie Książki.
3. Jedna klasa nie powinna zajmować się reprezentacją pojedynczej książki jak i operacjami bezpośrednio na bazie. Na dobrą sprawę powinieneś mieć tutaj kilka obiektów:
- Książka reprezentujący pojedynczą książkę,
- MenadżerKsiążek, którego metoda oddajZniszczonąKsiążkę przyjmie jako argument obiekt klasy Książka. Pojawienie się w nazwie klasy słowa "Menadżer" z reguły sugeruje jej zbyt szeroki zakres obowiązków, ale tutaj mamy tylko przykład,
- KsiążkaDAO - po prostu DAO dla typu Książka (czy jakiś bardziej generyczny), wykorzystywany przez menadżera.
4. Nie powinieneś korzystać z globali.
Nortonek
Wyeliminowałem globale, mam nadzieję że prawidłowo, zmieniłem nazewnictwo klas i dodałem Dependency injection w klasie Bibliotekarki

  1. <?php
  2.  
  3. $db = NewADOConnection('mysql');
  4. $Ksiazka= new Ksiazka();
  5. $Pani_Bibliotekarka = new Pani_Bibliotekarka($Ksiazka, $db);
  6.  
  7. $Ksiazka->set_id_ksiazki(1);
  8. $Pani_Bibliotekarka -> zapisz_oddanie_ksiazki();
  9.  
  10. $Ksiazka->set_id_ksiazki(2);
  11. $Pani_Bibliotekarka -> zapisz_oddanie_zniszczonej_ksiazki();
  12.  
  13.  
  14. class Tablica_SQL {
  15. static const tab_sql_ksiazki_oddane = 'tab_ksiazki_oddane';
  16. static const tab_sql_ksiazki_ozniszczone = 'tab_ksiazki_zniszczone';
  17. }
  18.  
  19. class Ksiazka {
  20. private $id_ksiazki;
  21. private $Ksiazka;
  22.  
  23. function set_id_ksiazki($id){
  24. $this->id_ksiazki = $id;
  25. }
  26.  
  27. }
  28.  
  29.  
  30. class Pani_Bibliotekarka{
  31. private $Ksiazka;
  32. private $db
  33.  
  34. function __construct(Ksiazka $Ksiazka, db $db){
  35. $this->Ksiazka = $Ksiazka;
  36. $this->db = $db;
  37. }
  38.  
  39. private function zapisz_oddanie_ksiazki(){
  40. $result0 = $this->db -> Execute("UPDATE ".Tablica_SQL::tab_sql_ksiazki_oddane." SET `oddana`= '1' WHERE `id_ksiazki`='".$this->Ksiazka->id_ksiazki."' ");
  41. }
  42.  
  43. private function zapisz_oddanie_zniszczonej_ksiazki(){
  44. $result0 = $this->db -> Execute("UPDATE ".Tablica_SQL::tab_sql_ksiazki_oddane." SET `oddana`= '1' WHERE `id_ksiazki`='".$this->Ksiazka->id_ksiazki."' ");
  45.  
  46. $Ksiazki_Zniszczone = new Ksiazki_Zniszczone();
  47. $Ksiazki_Zniszczone-> insert_ksiazka_zniszczona($this->Ksiazka->id_ksiazki);
  48. }
  49.  
  50. }
  51.  
  52.  
  53. class Ksiazka_Zniszczona{
  54.  
  55. public function insert_ksiazka_zniszczona( $id_ksiazki){
  56. $result0 = $this->db -> Execute("UPDATE ".Tablica_SQL::tab_sql_ksiazki_zniszczone." SET `zniszczenie_ksiazki`= '5' WHERE `id_ksiazki`='$id_ksiazki' ");
  57. }
  58.  
  59. }
  60.  
  61. ?>
Crozin
1. Stan zniszczenia książki to właściwość samej książki, po co Ci do tego osobna klasa?
2. PaniBibliotekara to właśnie taki menadżer z mojego wcześniejszego postu. Powinna mieć ona metodę przyjmijZwracanąKsiążkę, która powinna jako argumenty przyjąć obiekty typu Książka oraz OsobaWypożyczająca. Wewnątrz tej metody mogłaby porównać stan książki sprzed wypożyczenia i w momencie jej zwrócenia. Jednak samo zapisywanie danych w bazie nie powinno już leżeć w jej zakresie obowiązków.

PS. Tak jak mówiłem, zapoznaj się z jakimś gotowym ORM-em: będziesz tam miał przykłady jak poprawnie pisać kod. Zaoszczędzisz sobie masy czasu, wyrobisz zdecydowanie więcej dobrych nawyków, a przy okazji poznasz jakieś konkretne narzędzie.
Ormin
Pozwolę napisać sobie jak ja bym to zrobił i why:

  1. class Ksiazka {
  2. private $id;
  3. public function __construct($id) {
  4. $this->id = $id;
  5. }
  6.  
  7. public function getID() {
  8. return $this->id;
  9. }
  10.  
  11. }
  12.  
  13.  
  14. class Pani_Bibliotekarka {
  15.  
  16. private $db
  17.  
  18. public function __construct(db $db) {
  19. $this->db = $db;
  20. }
  21.  
  22. public function oddaj_ksiazke(Ksiazka $ksiazka) {
  23. $this->db->Execute("UPDATE tab_ksiazki_oddane SET `oddana`= '1' WHERE `id_ksiazki`='".$ksiazka->getID()."' ");
  24. }
  25.  
  26. public function oddaj_zniszczona_ksiazke(Ksiazka $ksiazka){
  27. $this->oddaj_ksiazke($ksiazka);
  28. $this->db->Execute("UPDATE tab_ksiazki_zniszczone SET `zniszczenie_ksiazki`= '5' WHERE `id_ksiazki`='".$ksiazka->getID()."' ");
  29. }
  30.  
  31. }
  32.  


Podział odpowiedzialności:
Ksiazka - reprezentuje obiekt domenowy ( naszą książkę )
Pani Bibliotekarka - reprezentuje repozytorium domenowe dla naszych książek i udostępnia API do zarządzania nimi ( w tym wypadku tylko oddawnaie zniszczonych / niezniszczonych książek )
em1X
Złota definicja: "Jeśli istnieje więcej niż jeden powód, żeby zmodyfikować klasę, to łamie ona zasadę SRP." Btw. słyszałem, że za używanie słowa kluczowego global mają ucinać ręce.
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.