Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rejestr vs Singleton vs global
Forum PHP.pl > Forum > PHP > Pro
LEW21
Singleton to takie zmienne superglobalne, utrudniające dodatkowo podmianę pojedynczego komponentu systemu na inny. Jeżeli po prostu użyć zmiennych globalnych (albo nawet rejestru) można przypisać do danej zmiennej/pozycji instancję dowolnej klasy o dowolnej nazwie która ma po prostu określony API współpracujący z danym komponentem. Jeżeli jednak system używa Singletonu to nie jest to możliwe - konieczna jest albo modyfikacja danego komponentu albo utworzenie nowej klasy o nazwie takiej, jakiej rząda ten komponent.

Rejestr działa identycznie jak zmienne globalne, ale jest dużo mniej wygodny w obsłudze i na dodatek jest wolniejszy niż wbudowane w PHP zmienne globalne.

Zmienne globalne też jakimś idealnym rozwiązaniem nie są, ale lepszego po prostu w PHP nie ma. Dlatego właśnie ich używam.

@bim2 @BTW: tak
Cysiaczek
@LEW21 - Odnoszę wrażenie, że nie widzisz zalet rejestru, bo mówisz jedynie o transportowaniu obiektów, czy innych danych (np. konfiguracyjnych). Rejestr ma tą przewagę nad gołymi zmiennymi globalnymi, ze można skutecznie zwiększyć jego funkcjonalność. Można np. składować obiekty jakiegoś konkretnego typu i nie trzeba za każdym razem sprawdzać - poprzez np. instanceof -, czy obiekt jest żadanego typu, czy nie. Tak samo z dodawaniem obiektów do rejestru - metoda dodająca (setter) może automatycznie sprawdzać typ przekazanego obiektu i umieścić w odpowiedniej kolekcji (zyskujemy kategoryzację), albo wręcz go wymusić w swojej definicji i wypluć wyjątek, gdy spróbujemy wprowadzić zły obiekt. Łatwo też sobie wyobrazić, że możemy kontrolować dostęp do obiektów, a nawet możemy filtrować, logować i wykonywac dziesiątki innych operacji, których nie zrobimy w podobnie łatwy i intuicyjny sposób z użyciem globali. Co do API; dlaczego uważasz, że rejestr nie jest przenośny? Ja uważam wręcz odwrotnie - bez rejestru ciężko utrzymac spójność interfejsu - np.
  1. <?php
  2. $registry->get('userAccountInfo', $user)->getAccountExpireDate(); // przekazujemy nazwę klucza i obiekt klasy User, //który posłuży do naszej identyfikacji
  3. ?>

Jako, że rejestr może z powodzeniem byc singletonem (bo jest wzorcem o szerszej defnicji, więc może składać się z innych wzorców), musisz jedynie pobrać jego instancję i wywołać określoną metodę. W Świecie, w którym niemal każda poważna aplikacja to swego rodzaju instancja jakiegoś frameworka - nie jest to wada, bo uczestniczy się w pewnej konwencji, więc dwie akcje nie będą używały róznych interfejsów - każda pobierze instancję rejestru i zrobi swoje.

Pozdrawiam.
LEW21
Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
Można np. składować obiekty jakiegoś konkretnego typu i nie trzeba za każdym razem sprawdzać - poprzez np. instanceof -, czy obiekt jest żadanego typu, czy nie.

Tylko... po co to sprawdzać? Robiąc to z góry zakładasz że nigdy nikt nie będzie chciał po prostu podmienić tej klasy inną klasą o identycznym API, ale innej nazwie (żeby nie trzymać dwóch różnych klas pod tą samą nazwą).

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
Tak samo z dodawaniem obiektów do rejestru - metoda dodająca (setter) może automatycznie sprawdzać typ przekazanego obiektu i umieścić w odpowiedniej kolekcji (zyskujemy kategoryzację), (...)

Tylko... po co kategoryzować obiekty w ten sposób? Nie potrzebujesz przecież kategorii np. "Klasy od sesji" bo z zasady używasz tylko jednej, a na pewno nie będziesz przez nie iterował i używał każdej z nich. A jeżeli chcesz np. kategoryzować w stylu "Użytkownicy, czyli instancje klasy User", "Moduły, czyli instancje klasy Module" itp. to dużo lepiej jest zrobić do tego dodatkowe klasy - Users i Modules - dzięki temu będziesz mógł za ich pomocą wygodnie pobierać danego usera/moduł/coś.

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
(...) albo wręcz go wymusić w swojej definicji i wypluć wyjątek, gdy spróbujemy wprowadzić zły obiekt.

I w ten sposób uniemożliwić to o czym napisałem wcześniej (inna nazwa klasa, to samo API). No i przy okazji takie rozwiązanie zmusza programistę do zakodowania wszystkich typów klas i w rejestrze i w klasie głównej (tworzącej instancje tych klas).

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
Łatwo też sobie wyobrazić, że możemy kontrolować dostęp do obiektów, (...)

Prawdę mówiąc nie wiem po co chcesz kontrolować dostęp do obiektów - jeżeli przypadkiem uruchomiony zostanie jakiś złośliwy kod to tak czy siak, niezależnie od tego typu kontroli, zrobi on spustoszenia. A po co kontrolować co może normalny kod?

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
(...) a nawet możemy filtrować, logować i wykonywac dziesiątki innych operacji, których nie zrobimy w podobnie łatwy i intuicyjny sposób z użyciem globali.

Co ty znowu chcesz filtrować? tongue.gif A logowanie - to fakt, nie możesz przy użyciu globali logować gdzie klasa została użyta, ale prawdę mówiąc nie widzę w takim działaniu sensu tongue.gif Loguje się gdy coś się stanie, np. gdy zostanie coś zmienione w bazie danych, ale nie np. pobranie klasy tylko po to żeby coś odczytać!

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
Co do API; dlaczego uważasz, że rejestr nie jest przenośny?

A czy ja mówiłem coś na temat przenośności rejestru? Mówiłem tylko że nie widzę różnicy między globalami a rejestrem.

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
Ja uważam wręcz odwrotnie - bez rejestru ciężko utrzymac spójność interfejsu - np.
  1. <?php
  2. $registry->get('userAccountInfo', $user)->getAccountExpireDate(); // przekazujemy nazwę klucza i obiekt klasy User, //który posłuży do naszej identyfikacji
  3. ?>

Dodajmy jeszcze że ten kod wygląda strasznie, w przeciwieństwie do:
  1. <?php
  2. global $user;
  3. $user->getAccountExpireDate();
  4. ?>

(zakładając że zrozumiałem o co Ci chodziło - nie jestem pewien, bo nie rozumiem co właściwie zrobiłeś, co dodatkowo pokazuje że użycie rejestru jest niezrozumiałe tongue.gif)

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
Jako, że rejestr może z powodzeniem byc singletonem (bo jest wzorcem o szerszej defnicji, więc może składać się z innych wzorców), musisz jedynie pobrać jego instancję i wywołać określoną metodę.

... co nie zmienia faktu że nie cierpię singletonów...

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
W Świecie, w którym niemal każda poważna aplikacja to swego rodzaju instancja jakiegoś frameworka - nie jest to wada, bo uczestniczy się w pewnej konwencji, więc dwie akcje nie będą używały róznych interfejsów - każda pobierze instancję rejestru i zrobi swoje.

No tak, wrzućmy do aplikacji najlepiej dziesięć rejestrów i wogóle dziesięć zestawów frameworków, wtedy wszystko będzie idealnie działać!

Zakładając że się chce napisać w miarę szybki skrypt, widzę jedyne wyjście w ujednoliconym API a nie w kilku rejestrach.

Cytat(Cysiaczek @ 21.07.2007, 22:54:22 ) *
Pozdrawiam.

Również pozdrawiam smile.gif
x3m
Cytat
Dodajmy jeszcze że ten kod wygląda strasznie, w przeciwieństwie do:
  1. <?php
  2. global $user;
  3. $user->getAccountExpireDate();
  4. ?>

Może to będzie pomocne:
  1. <?php
  2. global $user;
  3. $user->getAccountExpireDate();
  4.  
  5.  
  6. $user = 'udaje obiekt';
  7. $user.= 'i obsluguje publiczna metode "fatal error"';
  8. $user->getAccountExpireDate();
  9. /*
  10. Fatal error: Call to a member function getAccountExpireDate() on a non-object
  11. */
  12. ?>
menic
A nie lepiej po prostu przekazywać to co nam potrzebne jako parametr funkcji tongue.gif
LEW21
x3m, jeżeli programista zna kod skryptu, to nie zrobi czegoś takiego. A jeżeli nie zna, to niech nie próbuje go edytować tylko się z nim zapozna tongue.gif

menic, nie tongue.gif Musiałbym przekazać $filesystem (moja klasa dzięki której zabawa z systemem plików jest obiektowa i banalna tongue.gif), $activeUser, $output, $db (to taki przykład, osobiście z tego nie korzystam - trzymam dane w plikach XML) i jeszcze całą masę innych klas, a jak bym się pomylił w kolejności to skutki byłyby opłakane tongue.gif
Turgon
LEW21, takie pomyłki wynikają bardzo często... bardzo często. Zwłaszcza kiedy kod pisze kilka osób.
kwiateusz
Lew przy Twoim założeniu każdy programista pracujący nad projektem musiałby znać cały projekt na wylot, a przy dużych projektach gdzie linie kody liczy się w tysiacach albo lepiej to wdrożenie programisty trwałoby bardzo długo i było mało opłacalne bo zanim by sie nauczył wszystkich globali których nie może zakryć to jednak by trwało. A przy singletonie (nie jestem zwolennikiem rejestru do przekazywania instancji obiektu tylko do trzymania konkretnych danych) to bez problemu w każdym miejscu kodu moze stworzyć nowy obiekt bez zastanawiania i wtedy musi tylko znać klasy które sa mu potrzebne (jakie mają, api itp) i od razu może pisać, a nie sie zastanawiać czy nie zakrył globala czy nie, a przy błędach spowodowanych podmianą globala to już masakra doszukać się co spowodowało błąd bo te błędy nie są tak oczywiste jak inne... No i to pokazuje ze wystarczy ze zna tylko kawałek projektu nad którym pracuje a nie całość co przyspiesza wdrażanie nowych osób
LEW21
Kwiateusz, bo wygenerowanie jakiejś listy globali których nie wolno nadpisać to tak wielki problem że aż trzeba się uciekać do innych, gorszych rozwiązań tongue.gif
thornag
Hmm niedawno zaczalem pracowac w zespole gdzie poprzedni programisci doslownie wszystko robili na globalach.[ Teraz nawet jesli mialbytm liste na ktorej byloby powiedzmy tysiace globali myslisz ze sprawdzalbym takowa za kazdym razem gdy chce uzyc jakiejs zmiennej ?

Pozatym obecnie pracuje nad projektem ktory rozwijany jest juz od czterech lat (inna sprawa ze trzeba by go bylo poprostu przepisac) i widze w tym kodzie ktory uprzednio robilo n developerow setki globali wszedzie do wszystkiego. To jest niesamowicie trudne do wykrycia i ujarzmienia przy czym przez sprawdzanie co gdzie i jak zostalo zadeklarowane moja wydajnosc spada o jakies 80%

Global jak eval zly i koniec. Singleton jest juz lepszy aczkolwiek zdaniem wielu ostatnio jest to poprostu global w obiektowej panierce.

Registry wydaje sie najbardziej odpowiednim rozwiazaniem, chociazby dla tych samych argumentow ktore zostaly uprzednio wytoczone, mozna sledzic logowac debugowac o wiele wydajniej. I nie przemawia do mnie argument ze to debugowanie to mi jest potrzebne tylko w fazie dev. Co jesli klient sobie zarzyczy zmian ? Wtedy zaprzegam swoj zespol do wprowadzania tych zmian, jesli nie mieli by debuggowania juz jakos ogarnietego musieli by to robic jeszcze raz. A tak lekko i przyjemnie zmiana jednej flagi moga sobie wlaczyc i pomagac (ku uciesze naszej testerki tongue.gif).

Ogolnie uwazalem ze uzywanie globali umarlo wraz z php3, widac nie.

Dowodow na to ze global zly jest duzo wystarczy tylko poszukac i poczytac. Gdyby byl fajny to tak ogromny procent spolecznosci nie narzekalby na niego.

Dla mnie osobiscie (podejscie czysto pragmatyczne) argumenty za rozwiazaniami typu registry czy nawet singleton, i argumenty przeciw globalom sa oczywisne i jasne, jak najbardziej do mnie przemawiajace.

Tyle smile.gif
UDAT
Najpierw chwila polemiki:
@LEW21
Cytat
Musiałbym przekazać $filesystem (moja klasa dzięki której zabawa z systemem plików jest obiektowa i banalna tongue.gif ), $activeUser, $output, $db (to taki przykład, osobiście z tego nie korzystam - trzymam dane w plikach XML) i jeszcze całą masę innych klas, a jak bym się pomylił w kolejności to skutki byłyby opłakane tongue.gif

Od czego jest type hinting?

@Cysiaczek
Cytat
Rejestr ma tą przewagę nad gołymi zmiennymi globalnymi, ze można skutecznie zwiększyć jego funkcjonalność. Można np. składować obiekty jakiegoś konkretnego typu i nie trzeba za każdym razem sprawdzać - poprzez np. instanceof -, czy obiekt jest żadanego typu, czy nie. Tak samo z dodawaniem obiektów do rejestru - metoda dodająca (setter) może automatycznie sprawdzać typ przekazanego obiektu i umieścić w odpowiedniej kolekcji (zyskujemy kategoryzację), albo wręcz go wymusić w swojej definicji i wypluć wyjątek, gdy spróbujemy wprowadzić zły obiekt. Łatwo też sobie wyobrazić, że możemy kontrolować dostęp do obiektów, a nawet możemy filtrować, logować i wykonywac dziesiątki innych operacji, których nie zrobimy w podobnie łatwy i intuicyjny sposób z użyciem globali. Co do API; dlaczego uważasz, że rejestr nie jest przenośny? Ja uważam wręcz odwrotnie - bez rejestru ciężko utrzymac spójność interfejsu - np.

  1. <?php
  2. $registry->get('userAccountInfo', $user)->getAccountExpireDate(); // przekazujemy nazwę klucza i obiekt klasy User, //który posłuży do naszej identyfikacji
  3. ?>

A skąd pobierzesz instancję rejestru - z innego rejestru? Tworzenie specjalizowanych getterów i setterów spowoduje powstanie God Object(antywzorzec) i nie poprawia architektury aplikacji. Także zrobienie Fabryki rejestrów wydaje się trochę poronione, z których pobierałbyć odpowiedni rejestr.

Czyli coś takiego:
  1. <?php
  2. RegistryFactory::createRegistry()->getUserAccountInfo();
  3. ?>



Natomiast umożliwienie korzystania z setterów powoduje że mogę np. jakiejś klasie niechcący ustawić inny obiekt, który będzie miał to samo API, ale będzie to inna zupełnie instancja niezwiązana z poprzednią. Pomyśl np. o zmianie obiektu klasy MySQLSession na XMLSession (czy cokolwiek) w trakcie realizacji żądania.

Cytat
Ja uważam wręcz odwrotnie - bez rejestru ciężko utrzymac spójność interfejsu - np.
  1. <?php
  2. $registry->get('userAccountInfo', $user)->getAccountExpireDate(); // przekazujemy nazwę klucza i obiekt klasy User, //który posłuży do naszej identyfikacji
  3. ?>


Podejście dobre jedynie do uzyskiwania customizowanych obiektów, jedakże do samego rejestru jako takiego w rozumieniu podanym przez M.Fowlera w PoEAA już nie.



----------------------------------
Teraz moja propozycja:

Czy ten temat nie powinien nazywać się "Sposoby realizacji DI"?
Jeśli nie to nie ma chyba o czym rozmawiać:
global -> zło, Java, C# itd. radzą sobie dobrze bez.
singleton -> brak prawa bytu przy użyciu DI / lub rejestru
rejestr -> użycie jako prymitywny kontener DI (patrz komentarze powyżej) - nie należy mieszać konfigów z DI. Zamiast rejestru można użyć kontenera DI. Statyczne metody nie są rozszerzalne ( przed PHP6 i __callStatic). SingletonRegistry też nie jest rozwiązaniem, lepsza jest statyczna metoda fabryczna, jednak nie jestem zwolennikiem takiego rozwiązania.

W kolejnej odsłonie mojego frameworka chcę użyć normalnego kontenera DI w połączeniu z programowaniem aspektowym i adnotacjami - coś podobnego jak DI w EJB3:
  1. <?php
  2. class Foo {
  3. /**
  4.    * @Inject(type='Typ podstawowy', name='identyfikator')
  5.    */
  6.  private $injectedProperty;
  7.  
  8. /**
  9.    * @Inject(type='Typ podstawowy', name='identyfikator')
  10.    */
  11.  private function injectedSetter( $a ) {
  12.  
  13. }
  14. }
  15. ?>


Podobne podejście (annotacje) wykorzystywane jest, o ile pamiętam w PHP'owym frameworku Stubbles, jednak wymaga specjalnego tworzenia obiektów. Moja implementacja pozwalać będzie na transparentne użycie mechanizmu DI - parz. EJB3 - jednak jest to jeszcze kwestia dopracowania.
LEW21
thornag, nie można przesadzać ani w jedną ani w drugą stronę tongue.gif Używanie globali wszędzie gdzie się da nie ma najzwyklejszego sensu - po co mi w mojej klasie xnOutput jakiś formularz stworzony przez jakiś kontroler. Trzeba używać ich z głową - wrzucić w nie najważniejsze komponenty, używane tak często że przekazywanie ich jako parametry nie ma sensu. (Chce Ci się przekazywać np. 10 dodatkowych parametrów każdej funkcji, szczególnie że nie koniecznie będzie z nich korzystać? Bo mi raczej nie. A natomiast zapamiętanie ich nazw żeby ich nie nadpisać to już nie jest problem.)

UDAT, prawdę mówiąc nie rozumiem tego co wymyśliłeś tongue.gif Po za tym chcę (i pewnie nie tylko ja) żeby moje skrypty działały na każdym hoście z PHP 5.2 i nie mam (tu też pewnie nie tylko ja) ochoty na prekompilację, więc AOP odpada.
thornag
Cytat(LEW21 @ 23.07.2007, 20:21:20 ) *
[...](Chce Ci się przekazywać np. 10 dodatkowych parametrów każdej funkcji, szczególnie że nie koniecznie będzie z nich korzystać? Bo mi raczej nie. [...]


No wlasnie po to sa takie wzorce jak rejestr zeby nie trzeba bylo do metody przekazywac miliona argumentow.

Co do globali jeszcze to popatrz na to z innej strony, mamy zmienne superglobalne POST, GET, i teraz np ja zwyklem dodawac do propjektow komponent ktory na forum najczesciej nazywany jest HttpRequestem. Pelni on role swoistego proxy.

Zamiast bezposrednio odwolywac sie do tablic superglobalnych moge to zrobic poprzez metody dostepowe owego proxy, przy czym od razu moge sobie zazyczyc dane przefiltrowane, wyciapkowane czy jeszcze jakie tam sobie zazycze.

Sytuacja podobna jest przy rejestrze i zmiennych globalnych. Przyklad kompletnie wyssany z palca.

Powiedzmy ze mam ten sobie rejest i jakas metode dostepowa typu getObject, takze...

  1. <?php
  2. $oRegistry->getObj('DB', 'Interface_DB');
  3. ?>


I tutaj wlasnie zachodzi owo filtrowanie/sprawdzanie/etc zwracanych wartosci. Jesli np obiekt o ktory prosze zostal nadpisany przez jakis inny ktory w kolekcji siedzi pod tym samym kluczem i nie jest to instancja klasy implementujacej okreslony interfejs to od razu sie o tym dowiem, wyjatek, error cokolwiek.

Pewnie ze zaargumentujesz ze mozesz zrobic cos jak...
  1. <?php
  2. global $oDB;
  3. if(!$oDB instanceof Interface_DB) throw new Exception();
  4. ?>


Ale ja zasadniczo nie widze sensu powtarzania tych samych lini co chwile.

Biorac pod uwage ze i tak wiekszosc ubolewa nad brakiem kontroli typow zwracanych ktorej w phpie raczej nie bedzie, wzorce typu rejestr pomagaja w jakis sposob bardziej skonkretyzowany niz instrukcja warunkowa na jakas tam kontrole nad tymi typami.

Pozatym rozumiem stwierdzenie sztuka dla sztuki czy przerost formy nad trescia. Jesli buduje cos oparte na wzorcu np MVC i wykonuje to tak ze jak to ktos zauwazyl struklturalne kodowanie konczy sie na bootstrapie to nie widze sensu rezygnowac z obiektowych konwencji na rzecz na pierwszy rzut oka wygodniejszego globala.

Argument tutaj moze byc taki ze bede robil rejest tylko po to by zachowac wszystko w klasach i zeby pokozaczyc party.gif Otoz nie, dla mnie globale to zlamanie podstawowych zasad OOP jak chociazby oslabianie sprzegania czy hermetyzacja.

Podoba mi sie jeszcze jeden argument przytoczony powyzej, inni daja sobie rade bez globali wiec dlaczego w PHP ma byc inaczej ?

Global jak safe_mode czy register_globals wlasnie to jak dla mnie protezy niesione jeszcze z 3, to to co wyrabia PHP opinie jezyka w ktorym nie da sie porzadnie programowac, i ktorego uzywaja sami amatorzy, bo fakt jest faktem dla amatorow czy tzw 'bedroom warriors' uzycie globala jest po prostu szybsze i wygodniejsze, a jak pisalem amator taki nigdy nie bedzie mial stycznosci z projektem nad ktorym pracuje zespol powiedzmy 40 developerow.

Tyle uff ! :roll2:
EuReKa
Cytat(thornag @ 24.07.2007, 09:38:08 ) *
Ale ja zasadniczo nie widze sensu powtarzania tych samych lini co chwile.

A ja zasadniczo nie widzę sensu sprawdzania tego w ogóle. Jeśli ktoś chce zepsuć program to zrobi to i z rejestrem, czy każdą inną niepotrzebnie przekomplikowaną metodą.
Cytat(thornag @ 24.07.2007, 09:38:08 ) *
Global jak safe_mode czy register_globals wlasnie to jak dla mnie protezy

global jest wymagane, gdyż w PHP zwraca zmienne tylko z obecnego zasięgu a nie z najbliższego jak ma to miejsce w C/C++.
Pomijam sens porównania dwóch nierozłącznych wzorców (w sensie możliwości ich jednoczesnego użycia) i części składni języka.
Sedziwoj
Cytat(EuReKa @ 24.07.2007, 15:28:17 ) *
A ja zasadniczo nie widzę sensu sprawdzania tego w ogóle. Jeśli ktoś chce zepsuć program to zrobi to i z rejestrem, czy każdą inną niepotrzebnie przekomplikowaną metodą.


Nie chodzi o psucie, ale o kontrolę, aby nie musieć ciągle czegoś sprawdzać, czy to jest to to, czy można z tego korzystać itp.
Takie struktury same pilnują raz się napisze, a potem jak wpadnie jakiś błąd (niechcący) to wiadomo gdzie i dlaczego.
LEW21
Cytat(Sedziwoj @ 24.07.2007, 21:06:45 ) *
Nie chodzi o psucie, ale o kontrolę, aby nie musieć ciągle czegoś sprawdzać, czy to jest to to, czy można z tego korzystać itp.

Powtarzam jeszcze raz: po co cokolwiek sprawdzać tongue.gif


Cytat(Sedziwoj @ 24.07.2007, 21:06:45 ) *
Takie struktury same pilnują raz się napisze, a potem jak wpadnie jakiś błąd (niechcący) to wiadomo gdzie i dlaczego.

Nadpisanie globala niechcący? Niechcący to można pomylić literę w jakiejś nazwie a nie nadpisać coś czego się wszędzie używa.
Sedziwoj
@LEW21
Nie będę Cię przekonywał, życie to zrobi jak zaczniesz coś większego robić.
Bo mam rażenie, że tego nie robiłeś.
Jeszcze tylko może apropo sprawdzania, bo to się robi aby działało tak jak się zakłada, czyli od tego aby działało, do tego aby ktoś coś nie kombinował (mówię teraz bardziej ogólnie).
Do tego jak coś zmieniasz, czy dopisujesz nowego nie trzeba ciągle czegoś sprawdzać, a to przyspiesza pisanie.
Turgon
Ja sam doszedłem do wniosku. Mam gdzieś wszystkie rejestry! To co trzeba przekazuje bezpośrednio do obiektu. Nie bawię się w takie rzeczy tongue.gif Trzeba wtedy pisać aplikację z pomysłem smile.gif Np. zrobić settera do fronta i ten doda to w postaci tablicy akcji. Kwestia gustu smile.gif
Kodie
Osobiście wydaje mi się, że używanie zmiennych globalnych _zwykle_ jest bezcelowe, poza tym zaczernia cały projekt aplikacji (wyjątki się zdarzają, ale rzadko). To czy użyć wzorca rejestru czy singletona czy choćby IoC (czy czy któryś dwóch) jest zależne od tego co dany obiekt ma robić, za co odpowiadać. Nie można z góry powiedzieć, że registry jest lepsze od singletona i odwrotnie (choćby dlatego, że dają różne możliwości i mają różne cechy). Wszystkich wzorców trzeba używać z rozwagą (choć zgodze się, że signleton jako jeden z najprostszych jest nadużywany), ale nie zgodzę się, że singleton sam w sobie jest czymś złym, bo widzę dla niego zastosowania, w których sprawdzi się doskonale.
Athlan
Registry to swego rodzaju singletony zrobione z innych klas smile.gif Kiedyś o tym dość wyczerupjąco pisałem.

http://athlan.vgroup.pl/singleton-registry-map/
zimi
zaczęło mnie ostatnio dręczyć jedno pytanie,
jaka jest przewaga (anty)wzorca (zależy od punktu siedzenia) Singleton od klasy z atrybutami i metodami statycznymi, że używany jest Singleton
efekty można uzyskać w sumie podobne
NuLL
A wiesz jaka jest roznica pomiedzy metodami statycznymi a dynamicznymi ? Toc to podstawy programowania obiektowego a Ty z czyms takim na Pro wyjezdzasz wacko.gif
msulik
Myślę, że zimiemu chodziło o Paamayim Nekudotayim - ja dołączam się do jego rozterek:

  1. <?php
  2.  
  3. AntySingleton :: init();
  4. class AntySingleton
  5. {
  6. private static $a = array();
  7. private static $o = null;
  8.  
  9. private function __construct()
  10. {
  11. // Zamiast $this -> a
  12. self :: $a = array(201 => 101, 202 => 102, 203 => 103);
  13. }
  14.  
  15. public static function init()
  16. {
  17. self :: $o || self :: $o = new self();
  18. }
  19.  
  20. public static function getA($i)
  21. {
  22. return self :: $a[$i];
  23. }
  24.  
  25. public function __destruct()
  26. {
  27. // Sprzatanie, zamykanie polaczen itp.
  28. foreach (self :: $a as $i => $v) { unset(self :: $a[$i]); }
  29. }
  30. }
  31.  
  32. echo AntySingleton :: getA(201) . '<br />';
  33. echo AntySingleton :: getA(203) . '<br />';
  34.  
  35. ?>


Aktualnie pracuję w kodzie, w którym używanych jest kilkanaście singletonów i za każdym razem, gdy chcę użyć choć jednej metody z jakiejś klasy, muszę najpierw załadować sobie obiekt:
Kod
$this -> objJakisObiekt = JakasWspanialaKlasa :: getInstance();
a potem używać tego obiektu:
Kod
$this -> objJakisObiekt -> getCostam();


W skrócie: mnóstwo niepotrzebnego pisania! Moim zdaniem singleton to marnotrawstwo czasu i kodu. Może kiedyś singleton był jazzy, ale nie widzę przeszkód, by używać powyższej postaci. Czy ktoś mógłby mnie naprostować? smile.gif
Cysiaczek
@msulik - to zależy, co kto woli. Nic jednak nie stoi na przeszkodzie, aby singleton podpiąć pod składową - wtedy masz dalej singleton, a np. w jakiejś klasie bazowej ładujesz go do zmiennej i pochodne używają sobie $this->singleton->costam. Grunt, że bazowa może go sobie pozyskać, a My nieco jeszcze odtłuszczamy singletona i zyskujemy w ten sposób elastyczność kodu.

Pozdrawiam.
zimi
@NuLL: ogólnie pojęcie "dynamiczne metody" nie jest chyba powszechnie przyjętym albo je przeoczyłem, ale nieważne, tak znam tą różnicę ale chyba nie do końca mnie zrozumiałeś...
@msulik
Cytat
Myślę, że zimiemu chodziło o Paamayim Nekudotayim

tego zdania nie bardzo rozumiem, z tego co mi wiadomo to "Paamayim Nekudotayim" jest jedynie śmieszną nazwą dla tego podwójnego dwukropka którego się używa przed metodami statycznymi (i nie tylko), ale może się mylę
no ja myślałem nawet bez konstruktorów i desktruktorów bo miałem chwilowo jeszcze mniejsze potrzeby, ale na przykład zastosowanie kodu podobnej konstrukcji jak ten @msulika zamiast jakiegoś Singletona do obsługi bazy danych wydaję mi się bardzo dobrym pomysłem

swoją drogą jest dla mnie niezrozumiałe stworzenie operatora :: przez twórców PHP do metod statycznych, w Javie do jednego i drugiego używa się kropki i wszystko jest w porządku... wg mnie :: jedynie utrudnia :/ no ale to taki OT

@Cysiaczek:
Cytat
a My nieco jeszcze odtłuszczamy singletona i zyskujemy w ten sposób elastyczność kodu.

mógłbyś rozwinąć? nie bardzo rozumiem... na czym miałaby polegać ta elastyczność?

czyli nikt nie widzi przeciwwskazań dla takich "statycznych klas", zastanawia mnie tylko po co wymyślali Singleton skoro taka klasa statyczna wydaję się prostsza...
MalCom
Cytat(zimi @ 28.08.2007, 22:22:54 ) *
swoją drogą jest dla mnie niezrozumiałe stworzenie operatora :: przez twórców PHP do metod statycznych, w Javie do jednego i drugiego używa się -> i wszystko jest w porządku... wg mnie :: jedynie utrudnia :/ no ale to taki OT

w cpp jest ., -> i ::, i nikt nie narzeka ;p
wrzasq
@zimi: w Javie nie ma zadnych przedrostkow przed zmiennymi typu $ zeby odroznic, czy dany identyfikator jest nazwa klasy czy zmiennej, po prostu dana nazwa musi byc unikalna i na podstawie tego do czego sie odnosci wykonuje sie kod. w PHP musi byc wyraznie powiedziane, czy odwolujesz sie do klasy, czy do obiektu.

co do samych metod statycznych - glowna przeszkoda bylo to, ze we wczesnych wersjach PHP 5 wywolania statyczne byly znacznie wolniejsze od dynamicznych przez co o wiele lepiej bylo nawet za kazdym razem pobierac singleton i wykonywac operacje na instancji, a nie statycznymi metodami klasy.

@MalCom: ale w C++ (i C, bo tam tez sa skladowe struktur) sytuacja jest diametralnie inna >.<. tam zarowno oepratory . jak i -> odnosza sie do dynamicznych skladowych, tylko zaleznie od tego czy istancji, czy wskaznika.
MalCom
@wrzasq: Ale jakby nie patrzec sa az 3 operatory dla obiektow, w tym osobny dla statycznych i nikt nie narzeka na to winksmiley.jpg
Ja sie boje tego, aby php zbytnio nie upodabnialo sie do javy ;p
zimi
Cytat
w PHP musi byc wyraznie powiedziane, czy odwolujesz sie do klasy, czy do obiektu

no i przedrostek $ o którym wspomniałeś Ci nie wystarczy? odwołujesz się do klasy masz T_STRING, do obiektu masz T_VARIABLE a za nim mogłoby być -> no i spoko ja nie widzę problemu

Cytat
glowna przeszkoda bylo to, ze we wczesnych wersjach PHP 5 wywolania statyczne byly znacznie wolniejsze od dynamicznych

no to już ma jakiś sens, niemniej Singleton również propagowany jest w innych językach programowania np. we wspomnianej przeze mniej Javie gdzie podobno wywoływanie metod statycznych jest krótszym procesem...
Cysiaczek
Cytat
mógłbyś rozwinąć? nie bardzo rozumiem... na czym miałaby polegać ta elastyczność?
Jeżeli sam singleton to taka dana globalna, to wypada, aby programista zminimalizował ilość odwołań poprzez getInstance().Jeśli wyprowadzasz 5 klas z jednej bazowej i wiesz, że każda wykorzysta w którymś momencie obiekt singletona, to w klasie bazowej przypisujesz go do składowej, co może (choć nie musi) wpływać pozytywnie na hermetyzację zestawu klas.

Pozdrawiam.
msulik
Cytat(zimi @ 28.08.2007, 22:22:54 ) *
@msulik
z tego co mi wiadomo to "Paamayim Nekudotayim" jest jedynie śmieszną nazwą dla tego podwójnego dwukropka którego się używa przed metodami
No to "Scope Resolution Operator", jak wolisz winksmiley.jpg Ale dokładnie o to mi chodziło smile.gif Nie byłoby tej dyskusji, gdyby twórcy PHP od początku zaprojektowali ten język jako obiektowy i użyli kropki jako separatora, a nie jako konkatenacji.


Czy ktoś może wie, jak się nazywa konstrukcja przedstawiona przeze mnie powyżej? Bo to jest taka hybryda: niby singleton, ale nie do końca, bo nie pobieramy instancji; niby klasa tylko z metodami statycznymi, ale nie do końca, bo posiada instancję.
Sh4dow
Cytat
...
Czy ktoś może wie, jak się nazywa konstrukcja przedstawiona przeze mnie powyżej? Bo to jest taka hybryda: niby singleton, ale nie do końca, bo nie pobieramy instancji; niby klasa tylko z metodami statycznymi, ale nie do końca, bo posiada instancję.


Gdyby nie ta instancja to wyglada jak zbiur funkcji w "panierce obiektowej". Z tym nie wiele da sie zrobic, bo dostepu do instancji nie ma wiec ciezko to gdzies zapisac, serializowac, czy zrobic klona. Wiec raczej okreslil bym to tworem mało określonym albo nie wiem Mało sprytnym(bez urazy, ale mowie o tej klasie co napisales wczesniej) ?
Cos takiego mozna wykozystac jako magazyn, ale i tak jest wtedy zbedna instacja.
zimi
Cytat
Cos takiego mozna wykozystac jako magazyn, ale i tak jest wtedy zbedna instacja.

po to jest destruktor żeby sam po sobie sprzątał to jest wg mnie jedyny cel egzystencji tej instancji, ale nie można powiedzieć że jest ona bezcelowa
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-2019 Invision Power Services, Inc.