PHP5 i Singletony |
PHP5 i Singletony |
17.03.2004, 16:15:13
Post
#1
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
Może mnie ktoś oświecić dlaczego używa się singletonów? np:
skoro to samo można osiągnąć w ten sposób?:
Widze jakie są różnice, jednak nie rozumiem dlaczego singletony są stosowane skoro zapis Foo::bar(); jest wygodniejszy i kod klasy krótszy... Czy za pomocą singletonów można zrobić coś, o czym nie wiem? |
|
|
17.03.2004, 16:22:25
Post
#2
|
|
Administrator planeta/IRC Grupa: Przyjaciele php.pl Postów: 385 Pomógł: 0 Dołączył: 19.04.2003 Skąd: Zabrze Ostrzeżenie: (0%) |
Sigleton pozwala Ci działać na jednej instancji danej klasy, i w pewien sposob uniezależnia Cię od zmiennych globalych. Z każdego miejsca w kodzie możesz pobrać instancję klasy przez klasa::GetInstance(), i masz pewność (o ile dobrze skonstruujesz metode GetInstance) że zawsze otrzymasz referencję do tego samego obiektu. Takie jest głowne załorzenie signletonu
-------------------- "Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog |
|
|
17.03.2004, 18:24:14
Post
#3
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
tak, ale w php5 nie musze używać zmiennych globalnych:) więc czy dalej jest sens używania singletonów?
|
|
|
17.03.2004, 18:32:08
Post
#4
|
|
Administrator planeta/IRC Grupa: Przyjaciele php.pl Postów: 385 Pomógł: 0 Dołączył: 19.04.2003 Skąd: Zabrze Ostrzeżenie: (0%) |
Singletony są zastępstwem dla obiektów globalnych (tak sie przyjeło w php 4 ), i zapewniam Cie że pojęcie to nie wzieło się z php, i w każdym obiektowym jezyku programowania ono występuje. Zapewniam również że znajdzie sie kiedyś sytuacja w której użycie singletonu będzie konieczne (lub bardziej praktyczne), więc to że używasz php 5 nie jest żadnym argumentem przeciw singletonom Oczywiście jeśli można przekazać instancję w inny sposób (np. jako referencja w parametrze jakiejś metody) to warto skorzystać z tego rozwiązania, a nie pchać się wszędzie z singletonami Wszystko zależy od tego jak zbudujesz swoją aplikację, jeśli będziesz potrzebował w którymś miejscu singletonu (np. dwie zupełnie nie powiązane ze sobą klasy, ale jednej nagle sie zachce skorzystać z danych drugiej, ale ciężko będzie utworzyć powiązanie by je sobie przekazać) użyjesz go, jeśli nie to nie musisz sobie zawracać tym głowy
-------------------- "Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog |
|
|
17.03.2004, 18:38:44
Post
#5
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
Ja cię rozumiem, ale w php5 nie ma takiej potrzeby, np Foo::bar(); dostępne jest z każdego miejsca w dokumencie(i będzie to zawsze ten sam obiekt), a te dwie klasy które sa w przykładzie mają to samo działanie(czyli singleton nie jest potrzebny?).
|
|
|
17.03.2004, 18:44:15
Post
#6
|
|
Grupa: Przyjaciele php.pl Postów: 197 Pomógł: 0 Dołączył: 9.09.2003 Skąd: z Marsa Ostrzeżenie: (0%) |
Cytat Ja cię rozumiem, ale w php5 nie ma takiej potrzeby, np Foo::bar(); dostępne jest z każdego miejsca w dokumencie(i będzie to zawsze ten sam obiekt), a te dwie klasy które sa w przykładzie mają to samo działanie(czyli singleton nie jest potrzebny?).
Ale Foo::bar to jest dospet do konkretnej funkcji bez inicjowania klasy w ktorej sie znajduje. A co jesli zainicjowałeś jakaś klase i w tej klasie znajduja sie zmienne ktore sa Ci potrzebne ? Tu własnie przydaje sie singleton, bo nie dość że masz dostęp do wszystkich funkcji to jeszcze masz dostep do wartosci zmiennych w tej klasie. Pozdro |
|
|
17.03.2004, 18:50:55
Post
#7
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
Cytat w tej klasie znajduja sie zmienne ktore sa Ci potrzebne
No właśnie nie ma z tym problemu:) przypatrz się dokładnie, metody statyczne mają dostęp do pól statycznych (które mogą być nawet prywatne), więc ten sposób w niczym nie ustępuje singletonom. |
|
|
17.03.2004, 18:51:45
Post
#8
|
|
Grupa: Zarejestrowani Postów: 208 Pomógł: 0 Dołączył: 19.04.2003 Ostrzeżenie: (0%) |
Simpson: Ozzy mówił o PHP5, a tam możesz się odwoływać do zmiennych klasowych poprzez Foo::$bar :wink:
|
|
|
17.03.2004, 18:53:10
Post
#9
|
|
Grupa: Przyjaciele php.pl Postów: 197 Pomógł: 0 Dołączył: 9.09.2003 Skąd: z Marsa Ostrzeżenie: (0%) |
a no to chyba ze tak. Nie znam aż tak dokłądnie php5
Pozdro |
|
|
17.03.2004, 18:59:16
Post
#10
|
|
Administrator planeta/IRC Grupa: Przyjaciele php.pl Postów: 385 Pomógł: 0 Dołączył: 19.04.2003 Skąd: Zabrze Ostrzeżenie: (0%) |
Tak czy siak singleton może być przydatny, nie będziemy przecież robili wszystkich właściwości i metod w klasie na static. Czasem lepiej będzie zrobić jedną statyczną zmienną z referencją do $this i pobrać ją przez odpowiednią metodę używając operatora ::. Czasami takie rozwiązanie będzie poprostu wygodniejsze, efektywniejsze i bezpieczniejsze
-------------------- "Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog |
|
|
17.03.2004, 19:05:17
Post
#11
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
Cytat Tak czy siak singleton może być przydatny
przykład proszę:) |
|
|
17.03.2004, 19:55:29
Post
#12
|
|
Administrator planeta/IRC Grupa: Przyjaciele php.pl Postów: 385 Pomógł: 0 Dołączył: 19.04.2003 Skąd: Zabrze Ostrzeżenie: (0%) |
Potrzebna by była bardzo rozbudowana klasa, a Ty musiałbyś mieć dostęp do wielu jej właściwości z prawie każdej metody. Wtedy ustawianie wszystkiego na static troche miajałoby się z celem. Weźmy naprzykład parser szablonów. W całym kodzie chcesz używać tylko jednej isntancji (wiadomo, assign), ale ciężko dostarczyć referencje do niej każdemu innemu obiektowi. Ustawianie wszystkich zmiennych klasowych w parserze szablonów byłoby karkolomne, natomiast w każdym obiekcie który będzie go potrzebował możesz pobrać instancję przez wywołanie odpowiedniej metody poprzez oparator statyczny. Jeśli chodzi o przykłady kodu, to ciężko mi jest coś teraz napisać, ale myśle że pod tym adresem znajdziesz dość ciekawy przykład wraz z opisem (niestety wszystko to odnośnie php 4, jednak niektóre rzeczy sie nie zmieniałją, metody/zmienne statyczne nie zastąpią Ci wszystkiego )/
-------------------- "Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog |
|
|
17.03.2004, 20:28:38
Post
#13
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
z tym się zgodzę, bo sam używam takiego rozwiązania, jednak dalej nie daje mi to spokoju.
cytat z http://www.phppatterns.com/index.php/artic...icleview/6/1/1/ Cytat But first we have to overcome a small problem in php - the lack of static class variables (something that's coming in the Zend 2 engine)
[php:1:9bafc4226a]<?php // A generic function to create and fetch static objects function staticInstance($class) { // Declare a static variable to hold the object instance static $instance; // If the instance is not there, create one if(!isset($instance)) { $instance =& new $class; } return($instance); } ?>[/php:1:9bafc4226a] Co jeśli klasa wygląda np tak: [php:1:9bafc4226a]<?php final class Temp { private static $content; public static function add($content) { self::$content.= $content; } public static function get() { return self::$content; } public static function clear() { self::$content = ''; } } ?>[/php:1:9bafc4226a] Czy to też trzeba używać singletonu? Nie lepiej jest właśnie tak? Podobnie może wyglądać klasa do ubsługi bazy danych. Na przykład: [php:1:9bafc4226a]<?php class SQL { private static $conn; private static $result = array(); public static function connect($host, $user, $pass, $db) { self::$conn = @mysql_connect($host, $user, $pass); if (!self::$conn || !@mysql_select_db($db, self::$conn)) { trigger_error(mysql_error(), E_ERROR); } } public static function query($query, $label = 'default') { $result = @mysql_query($query, self::$conn); if(!$result) { trigger_error(mysql_error(), E_ERROR); } else { self::$result[$label] = $result; } } itd... ?>[/php:1:9bafc4226a] Nie lepiej używać: [php:1:9bafc4226a]<?php SQL::query('SELECT name FROM ...'); while($row = SQL::fetchArray()) { print $row['name']; } ?>[/php:1:9bafc4226a] niż np: [php:1:9bafc4226a]<?php $sql = SQL::getRef(); $sql->query('SELECT name FROM ...'); while($row = $sql->fetchArray()) { print $row['name']; } ?>[/php:1:9bafc4226a] :?: |
|
|
17.03.2004, 20:55:40
Post
#14
|
|
Grupa: Zarejestrowani Postów: 270 Pomógł: 0 Dołączył: 15.06.2003 Ostrzeżenie: (0%) |
z static nie można przesadzać bo przez nadmierne używanie mmogą sie pojawić dziwne błedy.
Mnie zastanbawia natomiast coś innego. [php:1:419528b488]<?php // A generic function to create and fetch static objects function staticInstance($class) { // Declare a static variable to hold the object instance static $instance; // If the instance is not there, create one if(!isset($instance)) { $instance =& new $class; } return($instance); } ?>[/php:1:419528b488] No i to działa pięknie ale co zrobić z klasami z parametrem [php:1:419528b488]<?php $db = &staticInstance(DB); class DB { public function __construct($server, $user, $password, $database, $debug) { ........ } } ?>[/php:1:419528b488] |
|
|
17.03.2004, 21:13:37
Post
#15
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
Cytat z static nie można przesadzać bo przez nadmierne używanie mmogą sie pojawić dziwne błedy.
Jakie? Bora: To jest przykład dla PHP4, w PHP5 nie trzeba tak robić. |
|
|
17.03.2004, 21:15:42
Post
#16
|
|
Administrator planeta/IRC Grupa: Przyjaciele php.pl Postów: 385 Pomógł: 0 Dołączył: 19.04.2003 Skąd: Zabrze Ostrzeżenie: (0%) |
Ja preferuję tworzenie wewnątrz klasy metodę która zwróci jej instancję. Dzięki temu moge przesłać parametry, ale jeśli instancja już istnieje to będą one zignorowane. Normalnie mają wartość ustawioną na null. Można też zrobić funkcję która będzie tworzyła hash wartości parametrów i wrzucała do tablicy statycznej z kluczem o wartości hasha i wartością elementu jako referencję do potrzebnej instancji. Dzieki temu będziemy mogli utowrzyć kilka globalnych instancji z różnymi parametrami (choć nie wiem czy podawanie parametrów przy każdym wywołaniu funkcji byłoby rzeczą przyjemną ).
Wracając do tematu signleton vs. static, uważam że nie powinno się nadużywać statica, nie potrafie tego niestety uzasadnić (może przyjdzie ktoś mądrzejszy i wytłumaczy), ale mam dziwne wrażenie że jednak coś jest nie tak z tymi staticami, że ich nadurzycie może powodować spadek efektywności lub błędy, bo inaczej wszyscy by się na to rzucili, a jakoś tak się nie stało (AFAIR). Zresztą nie widze żadnej zalety w korzystaniu z :: a -> jeśli chodzi o wygode, prawda, musze zadbać o ściągnięcie instancji w odpowiedni obszar zmiennych, ale jeśli pozwoli mi to zaoszczędzić troche czasu lub zbędnych kłopotów to wole jednak takie rozwiązanie. Musze przyznać że problem mnie zaintrygował, i teraz już sam jestem ciekaw jak to jest z tymi signletonami. Szkoda że nie mam większego doświadczenia z innymi językami obiektowymi, bo tak to cięzko mi cokolwiek powiedzieć aby nie być gołosłownym, same domysły -------------------- "Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog |
|
|
17.03.2004, 21:24:31
Post
#17
|
|
Grupa: Zarejestrowani Postów: 270 Pomógł: 0 Dołączył: 15.06.2003 Ostrzeżenie: (0%) |
Cytat Cytat z static nie można przesadzać bo przez nadmierne używanie mmogą sie pojawić dziwne błedy.
Jakie? Bora: To jest przykład dla PHP4, w PHP5 nie trzeba tak robić. hmm czyli w php5 nie trzeba korzystać z singleton bo można odwoiłąć sie przez class::var A co do korzystania z static może zbierać śmieci które spowodują błędne działanie. Np będziesz miał błąd np w twoim przypadku z sql static quote nie zostanie ustawione na nową. quote sie wykona bp bedzie mialo poprawną starą werjse. Przy takim bugu może być potem problem z znalezieniem. |
|
|
17.03.2004, 21:56:36
Post
#18
|
|
Grupa: Zarejestrowani Postów: 204 Pomógł: 0 Dołączył: 26.12.2003 Skąd: Rzeszów Ostrzeżenie: (0%) |
Bora: Foo::$bar do zmiennej i Foo::bar do stałej
Cudi: Mi też się wydaje, że powinno się używać singletonów, tylko zastanawiam się dlaczego:) W PHP4 było to uzasadnione, w PHP5 też musi się znaleźć jakiś powód;) Naturalnie czasem bez singletonów się nie obejdzie. Weźmy na przykład klasę Template, gdy chcemy mieć jeden główny szablon, do którego moglibyśmy odwołać się z każdej innej klasy, wtedy możemy napisać np: [php:1:71a7711270]<?php final class Page { private static $reference; private function __construct() {} public static function getRef() { if(self::$reference == null) { self::$reference = new Template('Main'); } return self::$reference; } } $main = Page::getRef(); $main->assign('title', 'Main'); $main->assign('css', 'file', 'main'); itd... ?>[/php:1:71a7711270] Ale co w przypadkach małych klas, np takich jak Temp, pokazana wcześniej. Nie ma sensu chyba tworzyć zmiennej referencji gdy zależy nam na wygodnym i szybkim dostępie do metod, np Temp::clear(), Temp::add('test'); Temp::get() itd... To samo tyczy się klasy SQL, nie zaobserwowałem gromadzenia się żadnych śmieci, nie wygląda też, żeby działała wolniej. Chyba faktycznie musimy poczekać na kogoś mądrzejszego:) |
|
|
18.03.2004, 17:38:42
Post
#19
|
|
Administrator planeta/IRC Grupa: Przyjaciele php.pl Postów: 385 Pomógł: 0 Dołączył: 19.04.2003 Skąd: Zabrze Ostrzeżenie: (0%) |
Myśle że właśnie sam sobie odpowiedziałeś na swoje pytanie Przy większych klasach singleton może być przydatny, ale w klasie np. Config, któtra ma za zadanie jedynie przechowywać dla nas jakieś informacje dużo wygodniejszym wyjściem będzie odowołanie się przez operator statyczny. Nie musimy się wtedy martwić o instancje, co byloby problemem jesli chcielibyśmy pobrać w jakiejś metodzie dane tylko w jednym miejscu. Zresztą ja próbowałem robić takie numery już w php 4, było to troche karkołomne ale działało. Otóż każda metoda klasy Klasa przy pierwszym wywołaniu wywoływala Klasa::GetInstance() i zapisywała referencje do zmiennej statycznej. Dane były umieszczone w zmiennych klasowych, ale ja miałem ten konfort że mogłem je pobierać przez Klasa::Get(), a sama metoda troszczyła sie o pobranie instancji odpowiedniego obiektu Oczywiście w php 5 jest to już zbędne, klasowe zmienne statyczne załatwiają sprawe
-------------------- "Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."
Cudi's devBlog |
|
|
18.03.2004, 19:07:33
Post
#20
|
|
Grupa: Zarejestrowani Postów: 27 Pomógł: 0 Dołączył: 14.05.2003 Ostrzeżenie: (0%) |
czy moglibyscie podac linki do artykulow omawiajacych szczegolowo temat singletonow ?
[sorry za maly ot] |
|
|
Wersja Lo-Fi | Aktualny czas: 10.06.2024 - 12:47 |