Ocena podejścia do Dependency Injection, PDO + OOP + Dependency injection |
Ocena podejścia do Dependency Injection, PDO + OOP + Dependency injection |
5.01.2015, 20:54:55
Post
#1
|
|
Grupa: Zarejestrowani Postów: 6 Pomógł: 0 Dołączył: 21.01.2013 Ostrzeżenie: (0%) |
Witam, uczę się OOP, zacząłem dla testów pisać klasę obsługująca bazę na podstawie PDO ( Trudno to nazwać DIC ). I proszę Was o ocenę czy w dobrą stronę to zmierza czy może podejście mam złe i później sobie skomplikuje życie ?
"Klasa DIC"
Pomijając kwestię iż trzymam dane do połączenia w klasie, czy ma mniej więcej tak to wyglądać ? Ciekawi mnie dlaczego musiałem zdefiniować funkcję prepare ... jak jej nie dopiszę to wywala mi później że nie istnieje ;x Klasa User:
Kod napisany tylko żeby sprawdzić czy się uruchamia. A wywołuje metody tak:
Ogólnie działa, no chyba że skasuje metode prepare w klasie DataBaseConnection to wtedy już nie ;p Tylko pytanie jak już wcześniej napisałem czy dobrą drogą idę ? |
|
|
5.01.2015, 21:38:56
Post
#2
|
|
Grupa: Zarejestrowani Postów: 4 291 Pomógł: 829 Dołączył: 14.02.2009 Skąd: łódź Ostrzeżenie: (0%) |
Pokaż var_dump($baza) w konstruktorze klasy User. Siłą rzeczy nie powinieneś mieć dostępu do własności $pdo klasy DataBaseConnection bo jest ona chroniona
|
|
|
5.01.2015, 21:45:58
Post
#3
|
|
Grupa: Zarejestrowani Postów: 2 355 Pomógł: 533 Dołączył: 15.01.2010 Skąd: Bydgoszcz Ostrzeżenie: (0%) |
Takie trochę na siłę to DI. Do każdego obiektu będziesz musiał przekazywać to połączenie, wg mnie bez sensu. A to raczej sam model sobie powinien dziedziczyć po DataBaseConnection i tyle.
|
|
|
5.01.2015, 22:00:21
Post
#4
|
|
Grupa: Zarejestrowani Postów: 6 Pomógł: 0 Dołączył: 21.01.2013 Ostrzeżenie: (0%) |
Pokaż var_dump($baza) w konstruktorze klasy User. Siłą rzeczy nie powinieneś mieć dostępu do własności $pdo klasy DataBaseConnection bo jest ona chroniona
Takie trochę na siłę to DI. Do każdego obiektu będziesz musiał przekazywać to połączenie, wg mnie bez sensu. A to raczej sam model sobie powinien dziedziczyć po DataBaseConnection i tyle. Chciałem sobie uprościć... W tym przypadku extend rozumiem. Ale dajmy na to, chciałbym stworzyć klasę rejestracyjną, logowanie, obsługa profilu klienta, panel admina ... etc. Miałbym je po prostu dziedziczyć po klasie obsługującej bazę ? Bo chyba nie Sigleton'em miałbym to rozwiązać ? Broń Boże się nie wymądrzam, po prostu nie jestem pewien jak najlepiej rozwiązać operacje na bazie ... Albo inaczej, jak najszybciej załapać. Ten post edytował marcinq123 5.01.2015, 22:01:49 |
|
|
5.01.2015, 22:02:23
Post
#5
|
|
Grupa: Zarejestrowani Postów: 4 291 Pomógł: 829 Dołączył: 14.02.2009 Skąd: łódź Ostrzeżenie: (0%) |
Właśnie Singleton się do tego nadaje.
|
|
|
5.01.2015, 22:08:22
Post
#6
|
|
Grupa: Zarejestrowani Postów: 6 Pomógł: 0 Dołączył: 21.01.2013 Ostrzeżenie: (0%) |
No właśnie, ogólnie sobie poczytałem ... i w sumie zdania są podzielone ... sporo osób odradza singletona ... albo odradza używania źle napisanego singletona ;p
Pomyślałem nad właśnie DI ... |
|
|
5.01.2015, 22:22:01
Post
#7
|
|
Grupa: Zarejestrowani Postów: 2 355 Pomógł: 533 Dołączył: 15.01.2010 Skąd: Bydgoszcz Ostrzeżenie: (0%) |
Jeżeli to jest po prostu zwykły model, to musisz mieć połączenie z bazą, więc po wymuszać przekazywanie czegoś, bez czego jak nie przekażesz to nie będzie działać? A skoro musisz to przekazać to takie użycie DI, jest wg mnie średnim pomysłem.
Dokładnie, miałbyś je po prostu dziedziczyć, użyć Singleton i tyle. Czasami ludzie próbują na siłę doszukiwać się problemów, z tymi wadami Singleton. Ten post edytował Damonsson 5.01.2015, 22:23:45 |
|
|
6.01.2015, 12:41:19
Post
#8
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) |
Z Twoim kodem wszystko jest źle i nie ma to wiele wspólnego z Dependency Injection - niestety podobnie jest z późniejszymi postami w tym wątku.
1. Po co istnieje klasa DataBaseConnection skoro nie robi ona absolutnie nic poza obcięciem możliwości "surowego" PDO? Przecież możesz bezpośrednio korzystać z obiektu PDO w swoim kodzie - nie musisz tego robić przez obiekt pośredniczący. 2. Jak już, to konstruktor klasy DataBaseConnection powinien przyjąć obiekt PDO w swoim argumencie, a nie tworzyć go samemu - wtedy mielibyśmy do czynienia właśnie z DI. 3. Jeżeli nie jesteś wstanie zrobić nic z wyjątkiem, to go nie wyłapuj. 4. Musiałeś zdefiniować dla klasy DataBaseConnection metodę prepare bo dlaczego niby miałaby ona istnieć sama z siebie? Obiekt PDO udostępnia prepare(), query(), beginTransaction() i masę innych, nie DataBaseConnection. 5. W klasie User już poprawnie przekazałeś obiekt połączenia z zewnątrz. Jedynie niepotrzebnie na siłę wykorzystujesz właściwości login czy query bo tam możesz skorzystać ze zwykłych zmiennych lokalnych. Czyli generalnie powinno to wyglądać to mniej-więcej tak: Pomijam tutaj już fakt, że wybieranie danych z bazy i ich reprezentacja w formie jednego obiektu klasy User jest bardzo złym podejściem. Powinieneś mieć raczej jeden obiekt przeznaczony do reprezentowania użytkownika (User) i drugi do wybierania takowych np. z bazy danych, czyli tzw. "model" (UserRepository). Jeszcze co do bzdur wypisanych w postach: 1. W żadnym wypadku klasa typu user nie powinna dziedziczyć po połączeniu z bazą danych, bo: (a) nie jest takowym, ( dojdzie do tego że będziesz miał otwartych po kilka połączeń na raz - kompletnie niepotrzebnie. 2. Jeżeli w jakiejś klasie potrzebujesz mieć dostęp do bazy danych to obiekt PDO powinieneś właśnie przekazać w konstruktorze. 3. Użycie Singetonu dla "klasy od bazy danych" to idiotyzm: (a) przecież może istnieć wiele równoległych połączeń do różnych baz danych(!), ( niweczysz tym wszelkie zalety płynące z IoC (DI) 4. Model nie jest synonimem operacji na bazie danych. Ta ostatnia jest w ogóle nie potrzebna. Przecież dane mogą pochodzić z dziesiątek innych źródeł, a tak w ogóle to model nie oznacza tylko wybierania danych, ale również i ich przetwarzanie. |
|
|
6.01.2015, 13:16:13
Post
#9
|
|
Grupa: Zarejestrowani Postów: 2 148 Pomógł: 230 Dołączył: 26.03.2008 Ostrzeżenie: (0%) |
@Crozin, +1 . Miałem to samo wymienić, ale nie chciało mi się tyle pisać
-------------------- ET LINGUA EIUS LOQUETUR IUDICIUM
|
|
|
6.01.2015, 14:01:38
Post
#10
|
|
Grupa: Zarejestrowani Postów: 6 Pomógł: 0 Dołączył: 21.01.2013 Ostrzeżenie: (0%) |
Prawdę mówiąc, po cichu liczyłem na Twoją odpowiedź Crozin ;]
Z racji tego iż chcę nabrać dobrych nawyków, spróbuje podejść kompleksowo. Cytat 4. Musiałeś zdefiniować dla klasy DataBaseConnection metodę prepare bo dlaczego niby miałaby ona istnieć sama z siebie? Obiekt PDO udostępnia prepare(), query(), beginTransaction() i masę innych, nie DataBaseConnection. No właśnie zdefiniowałem tylko prepare() a np. execute(), bindParam() już nie musiałem bo działało ... i dlatego nie rozumiem czemu. Cytat Pomijam tutaj już fakt, że wybieranie danych z bazy i ich reprezentacja w formie jednego obiektu klasy User jest bardzo złym podejściem. Powinieneś mieć raczej jeden obiekt przeznaczony do reprezentowania użytkownika (User) i drugi do wybierania takowych np. z bazy danych, czyli tzw. "model" (UserRepository). Cenna uwaga, ale napisałem przykład z pierwszego postu tylko żeby sprawdzić czy w ogóle to działa.
Czyli teraz odwołuje się tak ?:
Moje pytanie brzmi, dajmy na to miałbym klasy User ... Admin, Auth, etc. ( nie wiem co tam jeszcze wymyśle ) Każdy obiekt generuje ( w razie potrzeby połączenia z bazą) poprzez
A czy takie podejście żeby się nie powtarzać ma sens?
A do reszty się nie ustosunkuje bo ze wstydu nie wiem nawet co powiedzieć |
|
|
6.01.2015, 14:14:06
Post
#11
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) |
Cytat No właśnie zdefiniowałem tylko prepare() a np. execute(), bindParam() już nie musiałem bo działało ... i dlatego nie rozumiem czemu. Twoja metoda DataBaseConnection::prepare() zwraca na dobrą sprawę to co zwraca PDO::prepare() czyli nowy obiekt, klasy PDOStatement - to on zawiera metody execute(), bindParam() i inne. Nie ma on już kompletnie nic wspólnego z Twoim kodem.Cytat A czy takie podejście żeby się nie powtarzać ma sens? Tak, ma to sens - tak właśnie powinno to wyglądać. Bo tutaj nie chodzi nawet o powtarzanie się, a o jednokrotne nawiązanie połączenia i wykorzystywanie go w wielu różnych miejscach, czyli:
|
|
|
6.01.2015, 14:33:51
Post
#12
|
|
Grupa: Zarejestrowani Postów: 6 Pomógł: 0 Dołączył: 21.01.2013 Ostrzeżenie: (0%) |
Na tą chwile zostały rozwiane moje wątpliwości ;]
Dziękuje wielkie za pomoc panowie. |
|
|
6.01.2015, 15:54:44
Post
#13
|
|
Grupa: Zarejestrowani Postów: 2 355 Pomógł: 533 Dołączył: 15.01.2010 Skąd: Bydgoszcz Ostrzeżenie: (0%) |
1. W żadnym wypadku klasa typu user nie powinna dziedziczyć po połączeniu z bazą danych, bo: (a) nie jest takowym, ( dojdzie do tego że będziesz miał otwartych po kilka połączeń na raz - kompletnie niepotrzebnie. 2. Jeżeli w jakiejś klasie potrzebujesz mieć dostęp do bazy danych to obiekt PDO powinieneś właśnie przekazać w konstruktorze. 3. Użycie Singetonu dla "klasy od bazy danych" to idiotyzm: (a) przecież może istnieć wiele równoległych połączeń do różnych baz danych(!), ( niweczysz tym wszelkie zalety płynące z IoC (DI) 4. Model nie jest synonimem operacji na bazie danych. Ta ostatnia jest w ogóle nie potrzebna. Przecież dane mogą pochodzić z dziesiątek innych źródeł, a tak w ogóle to model nie oznacza tylko wybierania danych, ale również i ich przetwarzanie. 1. Jeżeli to jest zwykły model do połączenia z bazą danych to jest takowym i w każdym obiekcie i tak będzie się łączył z bazą danych i duplikował przekazywanie połączenia w konstruktorze przecież. Po to ma użyć Singleton, żeby nie miał kilku otwartych połączeń. 2. Jasne. 3. Tak sobie przeglądam klasy Doctrine zawierające własnie Singleton np w getInstance i nie widzę idiotyzmu. 4. Jasne, jeżeli zakładamy, że to ma być uniwersalny model, zgadzam się. Tutaj było pytanie o PDO. Nie piszę po złości, masz wiedzę większą ode mnie i chętnie poczytam, dlaczego się mylę. Choć te różnice nie są duże, głównie chodzi o to, że moje założenie jest takie, że zawsze będzie się łączył z tą bazą danych, więc może dziedziczyć, a Ty dajesz większą uniwersalność, w zamian za duplikowanie kodu (przekazywanie połączenia za każdy razem, przy tworzeniu obiektu). Pytanie, co jest poprawniejsze? |
|
|
6.01.2015, 19:29:22
Post
#14
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) |
Cytat 1. Jeżeli to jest zwykły model do połączenia z bazą danych to jest takowym i w każdym obiekcie i tak będzie się łączył z bazą danych i duplikował przekazywanie połączenia w konstruktorze przecież. Po to ma użyć Singleton, żeby nie miał kilku otwartych połączeń. Co to jest "zwykły model"? Jeżeli przekazuje za każdym razem to samo połączenie to nie nawiąże mu się nagle kilka.Cytat 3. Tak sobie przeglądam klasy Doctrine zawierające własnie Singleton np w getInstance i nie widzę idiotyzmu. A jakoś dokładniej? Bo na pewno nie jest to obiekt połączenia z bazą danych.Cytat [...] w zamian za duplikowanie kodu (przekazywanie połączenia za każdy razem, przy tworzeniu obiektu) Ale tu nie ma żadnego duplikowania kodu.
|
|
|
6.01.2015, 20:46:10
Post
#15
|
|
Grupa: Zarejestrowani Postów: 2 355 Pomógł: 533 Dołączył: 15.01.2010 Skąd: Bydgoszcz Ostrzeżenie: (0%) |
1. Metody, które i tak zawsze pobierają coś z bazy danych, nie wyobrażam tam sobie nagle czegoś niezwiązanego z bazą danych. Wtedy trzeba by to rozdzielić. No tak, a jeżeli będę dziedziczył (wg mojej teorii), to muszę sprawdzić czy już nie istnieje połączenie dlatego Singleton.
2. Dalej w związku z tym jest tworzenie połączenia itd. ale właśnie samo getInstance to zwykły Singleton.
3. Za każdym razem musisz się martwić, żeby przekazać to połączenie do obiektu. Tworząc odpowiednio skonkretyzowany model, wiem, że będzie on korzystał z bazy danych i w konstruktorze, tworzę sobie to połączenie od razu. Tworząc obiekt nie muszę pamiętać, aby przekazać tam połączenie z bazą. |
|
|
7.01.2015, 00:20:07
Post
#16
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) |
Doctrine 1? Ale mamy 2015 rok, środowisko PHP już znormalniało...
O niczym nie musisz pamiętać, IDE/PHP samo Ci podpowie, że robisz coś nieprawidłowego. |
|
|
Wersja Lo-Fi | Aktualny czas: 26.09.2024 - 09:46 |