![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 125 Pomógł: 9 Dołączył: 25.05.2013 Ostrzeżenie: (0%) ![]() ![]() |
Ogarnąłem już PDO i używam statycznej zmiennej do połączenia się z bazą. Tutaj przykładowa klasa: https://gist.github.com/mprz/6cce0e6dd51e4796209c
Tworząc kilka klas niejako uzależniam je od klasy odpowiedzialnej za tworzenie połączenia. Czy to na pewno idealne rozwiązanie? Druga sprawa: gdzie inkludować ową klasę DB? W każdej z klas która jej używa, czy w programie, który korzysta z obu klas (tak robię obecnie)? -------------------- |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
Nie wiem czy idealne ale takie rozwiązanie jest poprawne. Nie potrzebujesz w aplikacji webowej kilku połączeń do tej samej bazy danych. Gdybyś przez przypadek tworzył takowe np w jakiejś pętli to mogło by się to skończyć błedem ze strony serwera bazy danych (Too many connections). Dlatego potrzebujesz je sobie zachować i mieć do niego dostęp w całej aplikacji, singleton jak najbardziej tu pasuje. Przyjętym standardem jest używanie autoładowania klas więc zacznij go używać. Jeżeli nie to z formalnego punktu widzenia powinna być includowana w każym pliku który go używa
![]() Ten post edytował vincent vega 17.08.2013, 12:12:00 |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
@vincent vega: Jak najbardziej można korzystać w jednej aplikacji webowej z wielu połączeń do baz(y) danych, więc nie wprowadzaj w błąd.
@dżozef: Użycie tutaj singletonu to jedno z najgorszych możliwych rozwiązań. Zwyczajnie przekaż obiekt PDO (czy tam DB) jako argument konstruktora. |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
@crozin Nie napisałem że nie możesz mieć kilku połączeń - przytoczyłem nawet błąd jaki może się z tym wiązać. Napisałem że nie potrzebujesz tworzyć kilku połączeń, zazwyczaj wystarczy jedno. Dlaczego singleton jest tu niby nie na miejscu? Przekazywanie takowego połączenia jest niepraktyczne. Czy zauwazyłeś aby tak zachwywało się Doctrine, Hibernate czy SQLAlchemy ? Całość można podciąnąć nawet wyżej, zazwyaczaj będziesz chciał mieć jedego entity managera na wątek.
Ten post edytował vincent vega 18.08.2013, 18:54:32 |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Napisałem że nie potrzebujesz tworzyć kilku połączeń, zazwyczaj wystarczy jedno. Zazwyczaj... a gdy w końcu przychodzi konieczność skorzystania z kolejnego jest ogromny problem ze zrobieniem tego w cywilizowany sposób. Nie wspominając już o tak trywialnych rzeczach jak chociażby próba napisania testów pod taki kod.Cytat Dlaczego singleton jest tu niby nie na miejscu? Bo Singleton tworzy "twardą", ukrytą zależność pomiędzy kompletnie różnymi obiektami, a to bardzo utrudnia pracę nad kodem i niweczy większość zalet OOP.Cytat Czy zauwazyłeś aby tak zachwywało się Doctrine, Hibernate czy SQLAlchemy ? Co do SQLAlchemy się nie wypowiadam bo nie znam, ale dwa pierwsze robią dokładnie to o czym wspomniałem.Cytat Całość można podciąnąć nawet wyżej, zazwyaczaj będziesz chciał mieć jedego entity managera na wątek. Trochę sobie tutaj pomieszałeś. EntityManager znany z JPA/Hibernate nie jest thread safe dlatego też powinieneś mieć osobnego EM-a dla każdego z wątków* Nie ma natomiast absolutnie żadnego przeciwwskazania by jeden wątek posiadał kilka EM-ów. To jednak już wątek z zagadnienia wielowątkowości z którą bezpośrednio w PHP właściwie nie mamy do czynienia, więc pomińmy ten temat.* nic nie stoi też na przeszkodzie by używać jednego EM-a równocześnie przez wiele wątków, trzeba tylko samemu zatroszczyć się o odpowiednią synchronizację. |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
Cytat Zazwyczaj... a gdy w końcu przychodzi konieczność skorzystania z kolejnego jest ogromny problem ze zrobieniem tego w cywilizowany sposób Próbujesz rozwiązać problem który jeszcze nie istnieje. Jak się pojawi taka konieczność to trzeba będzie kod przebudować, ot nowa funkcjonalność/wymagania. https://github.com/doctrine/doctrine1/blob/...anager.php#L262 http://docs.jboss.org/hibernate/orm/3.3/re...irstapp-helpers Wyglądają na singletony ? Nie przypominam sobie też jakichś większych problemów w pisaniu testów pod te ormy. Znowu nie pisałem że nie możesz mieć kilku EMów na wątek, tylko że zazwyczaj będziesz potrzebował jednego. Wygląda jak byś upierał się ze singelton z zasady jest zły, może i jest ale są miejsca w których jego zastosowanie jest praktyczne. Ten post edytował vincent vega 18.08.2013, 23:36:47 |
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Próbujesz rozwiązać problem który jeszcze nie istnieje. Jak się pojawi taka konieczność to trzeba będzie kod przebudować, ot nowa funkcjonalność/wymagania. Masz świadomość istnienia problemu i wiesz że w momencie gdy on wystąpi będziesz musiał mocno ingerować w całą masę kodu uzależnionego od bazy danych. Problemu, który wcale nie jest jakimś skrajnym przypadkiem. Mimo wszystko nie widzisz głupoty w korzystaniu tutaj z tak kulawego rozwiązania, szczególnie gdy wdrożenie normalnego nie stanowi żadnego problemu? Nie mówiąc już o tym, że autor wątku szuka "idealnego" rozwiązania.Cytat https://github.com/doctrine/doctrine1/blob/...anager.php#L262 Pierwsze to bardzo przestarzały Doctrine w wersji pierwszej - słabo napisany. W dodatku to co podałeś to Singleton dla menadżera/fabryki połączeń, a nie bezpośrednio połączenia, więc jeszcze sytuacja nie jest tak tragiczna.http://docs.jboss.org/hibernate/orm/3.3/re...irstapp-helpers Drugie to również fabryka połączeń (sesji), w dodatku jest to jedynie "śmieciowa" klasa na potrzeby tutoriala o ile mnie pamięć nie myli. W normalnym kodzie (niezależnie czy używanym przez interfejs JPA czy Hibernate'a) nie używa się takiej konstrukcji. Raczej wszędzie spotkasz się z jakąś formą wstrzykiwania EM-a/EMF-a jako zależności. Cytat Wygląda jak byś upierał się ze singelton z zasady jest zły, może i jest ale są miejsca w których jego zastosowanie jest praktyczne. Singleton z zasady nie jest zły, ale bardzo często próbuje się go wykorzystać tam gdzie nie ma to najmniejszego sensu i powoduje jedynie problemy. Akurat użycie Singletonu do uzyskania połączenia z bazą danych jest obok "moja pierwsza klasa - połączenie z bazą danych" najczęściej wałkowanym tematem na forum z tej kategorii, gdzie początkujący w kółko powtarzają te same błędy.
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 1 168 Pomógł: 126 Dołączył: 5.02.2010 Skąd: Świdnica Ostrzeżenie: (0%) ![]() ![]() |
Crozin możesz coś więcej powiedzieć o błędach powtarzanych w kółko przy stosowaniu Singletonu przy połączeniu z bazą?
|
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
Nie ma idealnych rozwiązań. Napisałem że takie rozwiązanie jest poprawne i powszechnie stosowane. Dla purystów OOP wiele rozwiązań może być kulawych ale bezwzględne stosowanie się do wytycznych skutkuje skomplikowanym kodem. Aplikacje są zwyczajnie przeprojektowane bo próbują wyjść na wyższy poziom abstrakcji niż rzeczywisty problem który mają rozwiązywać.
W tych managerach/sesjach zaszyte jest połączenie albo namiar na pule połączeń ale dostęp jest tu statyczny i globalny. Nie poszedłbym też tak daleko i nazwał Doctrine przestarzałym. To bardzo dobry przykład ActiveRecodu, i nie wydaje mi się abyś potrafił to lepiej zaimplementować. Tutorial też śmieciowy, autorzy na starcie zachęcają do stosowania złych praktyk. Piszesz o wstrzykiwaniu zależności, które nie następuje z kosmosu, tu też masz najczęściej statyczny rejestr dostepnych usług i musisz kombinować żeby był dostepny praktycznie z każdego miejsca aplikacji. A potem na dobrą sprawę nie wiadomo gdzie które usługi są wykorzystywane i tu pojawia się problem w testowaniu. Przyłączam się do powyższego pytania, pokaż nam jak prawidłowo to zakodzić ? Ten post edytował vincent vega 19.08.2013, 08:58:19 |
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Głownie są te błędy wynikające z użycia singletonu samego w sobie:
1. Tworzenie twardych, ukrytych zależności pomiędzy obiektami. To niesie za sobą cały szereg konsekwencji, na czele z utratą korzyści płynących ze stosowania IoC czy interface-driven design. 2. Globalny dostęp do obiektu. Singleton to nic innego jak global w otoczce OOP, a jak złą praktyką jest stosowanie zmiennych globalnych nie trzeba chyba nikomu mówić. Singleton służy wymuszeniu istnienia co najwyżej jednej instancji danego obiektu, a nie dostępowi do niego zewsząd. Innymi słowy chodzi o uniemożliwienie utworzenia następującej konstrukcji: Sytuacje, gdzie istnienie dwóch obiektów tego samego typu nie miałoby najmniejszego sensu czy wręcz mogłoby prowadzić do błędów i/lub zagrożeń są bardzo rzadkie w środowisku PHP. Ja sam nie pamiętam kiedy musiałem skorzystać z Singletonu w swoim kodzie (czy to w PHP czy Javie) - nie jestem nawet pewien czy kiedykolwiek musiałem. EDIT: @vincent vega: Odchodzisz od tematu. Autor pyta konkretnie o przekazywanie surowego połączenia z bazą danych (PDO), nie fabryk czy rejestrów. Co do tego - jak to prawidłowo zrobić - szału to tutaj nie będzie, ale nie wiem czego się spodziewasz:
Ten post edytował Crozin 19.08.2013, 09:39:56 |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
No spodziewałem się całej otoczki OOP
![]()
Ten post edytował vincent vega 19.08.2013, 10:30:28 |
|
|
![]()
Post
#12
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Zacznijmy od tego, że w tym wątku rozmawiamy o Singletonie w sensie wzorca projektowego, nie zasięgu typu singleton (czy jakkolwiek to nazwać) znanego ze wszelkich DIC-ów czy przytoczonego przez Ciebie kodu. W tych dwóch kontekstach "singleton" oznacza coś zupełnie innego.
Przykład demonstrujący "zasięg typu singleton": Jak widać klasa Config nie jest singletonem sama w sobie. Co do kodu, który podałeś: 1. W metodzie getConfig() tworzysz obiekt-usługę o zasięgu typu "singleton", jednak sam obiekt singletonem nie jest. Takie rozwiązanie jest jak najbardziej poprawne. 2. Zarówno obiekt konfiguracji jak i połączenia z bazą danych powinien zostać utworzony poza obiektem DomainsController i do niego wstrzyknięty. Podstawa pisania poprawnego kodu: IoC. Unikniesz w ten sposób dziwnych problemów typu // Konfiguracja polaczenia, w kazdym z kontrolerow osobno ?. 3. Obiekt typu Domains posiada zwykłą zależność, która powinna być wstrzyknięta. Możesz zrobić to tak jak pokazałeś, tj. ręcznie, możesz też użyć do tego jakiegoś DIC-a. Ten post edytował Crozin 19.08.2013, 12:08:34 |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
No właśnie chciałem zobaczyć całą infrastrukturę zwiazaną z wstrzykiwaniem. Mój przykład był w miarę najprostszy, ale już widzimy że nie spełnia paradygmatów IoC. Zastanawiam się ilu finalnie potrzebowałbyś klas i obiektów aby osiągnąć cel, i czy rzeczywiście obszedłbyś się bez singletonów.
|
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Przykładowa implementacja dosyć rozbudowanego kontenera zależności: https://github.com/symfony/DependencyInjection - raptem kilka klas od faktycznego kontenera, nieco więcej "śmieci" od kompilatora (XML/YAML/PHP). I tak, można spokojnie odejść od singletonów, co więcej można spokojnie odejść od elementów statycznych, które również najczęściej są złym rozwiązaniem.
|
|
|
![]()
Post
#15
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
Dla mnie to astronautyka, uważam że jeżeli można użyć prostszego rozwiązania singleton/fabryka to nie ma sensu zamieniać wszystkiego na usługi i ich wstrzykiwanie http://www.martinfowler.com/articles/injection.html . Niedługo już nie będzie można z czystym sumieniem użyć funkcji mail czy curl żeby nie narazić sie na krytykę. A może za trzy czy cztery lata gdy symfony zostanie ponownie przepisane tym razem w duchu DDD, zaczną się pojawiać głosy tym razem że nie, że IoC nie przystaje do nowoczesnego świata. Strasznie skomplikowana rzecz to łączenie się z bazą danych
![]() |
|
|
![]()
Post
#16
|
|
![]() Grupa: Zarejestrowani Postów: 879 Pomógł: 189 Dołączył: 14.06.2006 Skąd: Bytom Ostrzeżenie: (0%) ![]() ![]() |
Można korzystać z podanych funkcji tylko powstaje pytanie czy łatwo taki kod jest utrzymywać.
Co do przepisywania symfony "w duchu DDD" to kompletnie nie wiem o czym piszesz. DDD dotyczy jak wynika z nazwy domeny a symfony nie ma żadnych aspiracji dotykać tej części aplikacji. Zobacz co dostarcza symfony i zauważ, że nie ma w nim żadnego kodu związanego z modelem czy utrwalaniem danych. Posiada tylko i wyłącznie wsparcie dla innych bibliotek (m. in. za pomocą kontenera DI). IoC nie wyklucza się z DDD. Nie rozumiem jak może to do siebie nie przystawać skoro implementacje DDD wykorzystują IoC. |
|
|
![]()
Post
#17
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
Może faktycznie trochę się zapędziłem z DDD, sam jeszcze nie miałem okazji w tym duchu aplikacji napisać. jedynie z tego co czytałem to daje się dosłyszeć głosy że IoC prowadzi czasami do anemicznego modelu co dla purystów jest nie do przyjęcia
![]() |
|
|
![]()
Post
#18
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat W tej chwili forsowany jest DIC jak by miał tu rozwiązać nasze problemy z utrzymaniem kodu. Ale w mojej opinii tak naprawdę tego typu podejście pasuje może do 20% projektów, DDD pewnie do jeszczej mniejszej ich częśći. 1. DI© ≠ IoC.2. IoC nie jest złotym środkiem na wszystkie problemy związane z utrzymaniem kodu. Jest to jednak jeden z elementów, który pomaga rozwiązać te problemy. 3. Nie wiem skąd wziąłeś liczbę 20% ale to podejście da się wdrożyć w niemal wszystkim - nie przychodzi mi do głowy nic, gdzie skorzystanie z tego miałoby być niemożliwe albo miało by być problemem. Cytat Naprawdę uważacie że użycie tu singletona jest jakimś karygodnym błędem, jest to niepoprawne ? W momencie kiedy autor wątku pyta o rozwiązanie idealne, tj. takie, które nie będzie rzucało kłód pod nogi w nietrywialnych zastosowaniach, tak jest to karygodnym błędem. |
|
|
![]()
Post
#19
|
|
Grupa: Zarejestrowani Postów: 15 Pomógł: 1 Dołączył: 30.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
Tak stricte to nie są te same rzeczy, czasami tylko te kwestie są ze sobą powiązane. Pozostaje więc mieć nadzieję że autor wątku nastepną swoją aplikację zamodeluje już z użyciem DI.
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 19.07.2025 - 14:49 |