Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: ActiveRecord bez metod statycznych
Forum PHP.pl > Forum > PHP > Object-oriented programming
adbacz
Jak stworzyć ActiveRecord bez udostępniania połączenia z bazą danych za pomocą statycznej metody innej klasy?

Przykład wykorzystania AR:
  1. $post = new Post;
  2. $post->title = 'przykładowy post';
  3. $post->content = 'zawartość postu';
  4. $post->save();

Aby wykonać taki kod, muszę w klasie Post zrobić dziedziczenie po klasie, np. ActiveRecord, i w tej klasie, a konkretnie w konstruktorze, pobrać połączenie z bazą danych, z jakiejś statycznej metody, która ją udostępnia. Czyli na przykład klasy APP i metody getDatabaseConnection():
  1. class APP
  2. {
  3. private static $db;
  4.  
  5. // static setter...
  6.  
  7. public static function getDatabaseConnection()
  8. {
  9. return self::$db;
  10. }
  11. }


Ale czy jest możliwość stworzenia obiektów ActiveRecord bez pobierania połączenia z DB za pomocą innej metody statycznej? Robi się tutaj bezpośrednie powiązanie, nie tylko metody, ale i nazwy klasy, a to totalnie nie współgra z zasadami SOLID.

A może zamiast tworzyć obiekt normalnie (new Post), robić to za pomocą innej metody, na przykład klasy ActiveRecordFactory, i w niej, po utworzeniu obiektu Post, wstrzyknąć obiekt bazy danych i zwrócić obiekt Post?
Crozin
1. ActiveRecord sam w sobie jest sprzeczny z zasadami SOLID, chociażby poprzez fakt łamania zasady pojedynczej odpowiedzialności obiektu.
2. Jedyne rozwiązanie to wymuszenie by wszystkie obiekty AR implementowały jakiś interfejs, a ich tworzenie przerzucić do jakiejś dodatkowej metody-fabryki, czyli coś w stylu:
  1. interface ActiveRecordEntity {
  2. public function setEverythingNeededForAR(DatabaseInterface $db, ...);
  3. }
  4.  
  5. abstract class ActiveRecord implements ActiveRecordEntity {
  6. ...
  7. }
  8.  
  9. class ActiveRecordFactory {
  10. ...
  11.  
  12. public function create($class, array $args = []) {
  13. $ref = $this->getReflectionClass($class);
  14. $obj = $ref->newInstanceArgs($args);
  15.  
  16. if (!$obj instanceof ActiveRecordEntity) {
  17. throw new ...;
  18. }
  19.  
  20. $obj->setEverythingNeededForAR($this->db, ...);
  21.  
  22. return $obj;
  23. }
  24. }
adbacz
Staram się pisać aplikację, która nie używa metod statycznych i jest zgodna z zasadami SOLID. Dodatkowo chcę to pogodzić z możliwie jak najprostszym pisaniem kodu a ActiveRecord daje mi aż nad to co bym chciał - prościej się już chuba nie da, niż te 4 linijki. Ale czy warto babrać się w ActiveRecord biorąc pod uwagę ww. SOLID i w tym jednym miejscu psuć to wszystko, czy zastosować coś innego, co będzie zgodne z SOLID?
Crozin
Cytat
Staram się pisać aplikację, która nie używa metod statycznych i jest zgodna z zasadami SOLID.
Bardzo, bardzo dobrze.
Cytat
Dodatkowo chcę to pogodzić z możliwie jak najprostszym pisaniem kodu a ActiveRecord daje mi aż nad to co bym chciał - prościej się już chuba nie da, niż te 4 linijki.
Ilość linii kodu nie ma przełożenia na prostotę.
  1. $post = $someService->createNewPost();
  2. $post->setTitle('...');
  3. $post->setContent('...');
  4. $someService->persist($post);
Jest równie prostym kodem, a w jego wykonaniu mogą brać udział dziesiątki obiektów, odpalonych może być multum zdarzeń itp. itd.

Jeżeli chcesz pisać wysokiej jakości kod zainteresuj się jakimś rozwiązaniem bazującym w oparciu o DataMappera (nie ActiveRecord) - np. bardzo popularne Doctrine.
adbacz
Kurcze, nie chciałbym używać Doctrine ;/ Szybkość działania tego narzędzia, w połączeniu w szybkością Symfony mnie totalnie odrzuca.

Co do Twojego kodu. Nawet mam zaimplementowany już DI. A jakbyś wykonał, raczej od strony projektowania, by móc dostać się do tego obiektu tak jak Ty napisałeś, ale nie tworząc kolejnych serwisów ręcznie? Chcę to jak najbardziej uprościć. Liczy się u mnie szybkość działania aplikacji, oraz szybkość pisania kodu. Ma to być w maksymalnym stopniu zrzucone na aplikację (chodzi mi w tym przypadku o CRUD np.), by programista nie musiał pisać za każdym razem zapytań SQL, tworzyć jakiś niesamowicie zbędnych metod w modelach do CRUD itp.
Crozin
Cytat
Kurcze, nie chciałbym używać Doctrine ;/ Szybkość działania tego narzędzia, w połączeniu w szybkością Symfony mnie totalnie odrzuca.
1. Doctrine nie ma z Symfony za wiele wspólnego.
2. Przy odpowiedniej konfiguracji obydwa projekty są całkiem szybkie.
3. Ich celem jest skrócenie czasu pracy programisty i podniesienie jakości kodu, kosztem czasu wykonywania (nieduży).

Cytat
A jakbyś wykonał, raczej od strony projektowania, by móc dostać się do tego obiektu tak jak Ty napisałeś, ale nie tworząc kolejnych serwisów ręcznie?
Postaraj się utworzyć w miarę uniwersalne klasy dla obiektów typu DAO czy repozytorium. W PHP niestety stracisz wtedy dobrodziejstwa TypeHintingu (brak typów generycznych w języku) co w pewnym (niemałym) stopniu obniża jakość kodu. Piszesz, że korzystasz z IoC (w formie DI) więc nie będziesz miał problemów by typy uniwersalne zastąpić wyspecjalizowanymi w dowolnym momencie.
Cytat
Liczy się u mnie szybkość działania aplikacji, oraz szybkość pisania kodu.
Jeżeli zależy Ci na szybkości aplikacji zrezygnuj z SOLID-a czy ogólnie wielu dobrych praktyk. Będzie to oczywiście bardzo, bardzo złe rozwiązanie bo w obecnych czasach szybkość działania aplikacji najłatwiej i najtaniej jest poprawić lepszą maszyną czy większą ich ilością. Chcesz szybkości pisania przez programistę? Użyj możliwie wielu gotowych rozwiązań. Chcesz napisać coś dobrego? Postaw na jakość kodu - co automatycznie przekłada się na mały spadek wydajności maszyn/programistów.
adbacz
[cite]Jeżeli zależy Ci na szybkości aplikacji zrezygnuj z SOLID-a czy ogólnie wielu dobrych praktyk. Będzie to oczywiście bardzo, bardzo złe rozwiązanie bo w obecnych czasach szybkość działania aplikacji najłatwiej i najtaniej jest poprawić lepszą maszyną czy większą ich ilością.[/cite]
W takim razie porywam się na niemożliwe... Chcę zrobić szybką aplikację, łatwą do rozbudowy przez programistów, używając zasad SOLID wink.gif

Co masz na myśli pisząc "Postaw na jakość kodu"?
Crozin
Cytat
Co masz na myśli pisząc "Postaw na jakość kodu"?
Mam na myśli to byś pisał m. in. stosując się do wspomnianego SOLID-a, wykorzystywał sprawdzone, dobrej jakości biblioteki (np. Doctrine), a pisany kod był w miarę elastyczny. Siłą rzeczy przy tego typu założeniach Twoja aplikacja nieco zwolni, a programista będzie miał większą ilość kodu do ogarnięcia/napisania - ale przynajmniej przy pierwszej lepszej, nietrywialnej rzeczy nie będzie to wszystko rzucać mu kłód pod nogi, a pomagać.
adbacz
Dzięki Ci wielkie za pomoc. Poukładałem sobie to już w głowie.

Mam tylko jedno pytanie. Przeglądałem dokumentację frameworka Yii i jego kod, i tam jest wiele razy odwołanie do metod statycznych itp. Nie wiem, czy miałeś z tym styczność czy nie, ale czy oni to zrobili specjalnie, czy tak po prostu, bo tak byli nauczeni? W dokumentacji pisze, że jest to Framework szybki i elastyczny, ale to chyba przeczy temu, by nie używać metod statycznych i trzymać się SOLID-a...
by_ikar
Taa te wszystkie FW są super szybkie i elastyczne.. Jeżeli chcesz na prawdę szybkiego FW to polecam zainteresować się phalconem, który w szybkości deklasuje konkurencję o kilka rzędów. Ale czy wygodnie się w nim programuje to ci nie powiem, bo póki co nie miałem z tym styczności, poza odrobiną dokumentacji.
Crozin
Użycie odwołań statycznych z reguły uniemożliwia trzymanie się reguł SOLID, nie znam Yii ale stawiam na to, że nie jest ono pod tym względem wyjątkiem.

@by_ikar: Nie róby z tego kolejnego bezsensownego wątku w stylu FW A vs B vs C vs D.

PS. Na stronie każdego FW znajdziesz informację o tym jaki to on nie jest szybki, profesjonalny, wygodny, elastyczny i w ogóle nie wiadomo po co istnieją inne rozwiązania. wink.gif
by_ikar
Cytat(Crozin @ 29.07.2014, 20:34:16 ) *
Użycie odwołań statycznych z reguły uniemożliwia trzymanie się reguł SOLID, nie znam Yii ale stawiam na to, że nie jest ono pod tym względem wyjątkiem.

@by_ikar: Nie róby z tego kolejnego bezsensownego wątku w stylu FW A vs B vs C vs D.

PS. Na stronie każdego FW znajdziesz informację o tym jaki to on nie jest szybki, profesjonalny, wygodny, elastyczny i w ogóle nie wiadomo po co istnieją inne rozwiązania. wink.gif


Nie mam zamiaru tworzyć wątku FW vs FW. Chciałem zwrócić uwagę że one wszystkie są opisywane jako MVC, super lekkie, super szybkie etc. A prawda jest taka że z nich wszystkich na prawdę szybki jest phalcon, po mimo że niewiele w nim zrobiłem, bo tylko przebrnąłem przez quick tour, to no on musi być szybszy dlatego że jego klasy są modułami php i do czasu kiedy inne będą działały jako zwykłe pliki php, nie będą w stanie go przebić w szybkości.. Ale fajnie by było jakby można było instalować frameworki czy jakieś liby tak jak w node, a one same działały by na podobnej zasadzie jak moduł php.. No mogłoby to dość znacznie zmienić podejście do php biggrin.gif

Yii ma podobnie zrobioną logikę co laravel, klasy same w sobie są nie statyczne (nie wszystkie metody, raczej większość), ale istnieją inne klasy (fasady w laravel) które umożliwiają dostęp do tych klas poprzez __callStatic odwołują się do instancji tych klas z kontenera IoC. Sam aktualnie nie wiem co o tym myśleć w przypadku laravela, no ale póki co zobaczymy..
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.