Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> PHP5 i Singletony
Ozzy
post 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:

  1. <?php
  2. class Foo {
  3.  
  4.  
  5. private static $reference;
  6. private $test;
  7.  
  8.  
  9. private function __construct() {}
  10.  
  11.  
  12. public function bar() {
  13.  
  14. $this->test = 'test';
  15. $this->bar2();
  16.  
  17. }
  18.  
  19.  
  20. private function bar2() {}
  21.  
  22.  
  23. public static function getRef() {
  24.  
  25. if(self::$reference == null) {
  26. self::$reference = new Foo();
  27. }
  28.  
  29. return self::$reference;
  30.  
  31. }
  32.  
  33.  
  34. }
  35.  
  36. Foo::getRef()->bar();
  37. ?>


skoro to samo można osiągnąć w ten sposób?:

  1. <?php
  2. class Foo {
  3.  
  4.  
  5. private static $test;
  6.  
  7.  
  8. public static function bar() {
  9.  
  10. self::$test = 'test';
  11. self::bar2();
  12.  
  13. }
  14.  
  15. private static function bar2() {}
  16.  
  17.  
  18. }
  19.  
  20. Foo::bar();
  21. ?>


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?
Go to the top of the page
+Quote Post
Cudi
post 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 smile.gif


--------------------
"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
Go to the top of the page
+Quote Post
Ozzy
post 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?
Go to the top of the page
+Quote Post
Cudi
post 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 smile.gif 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 winksmiley.jpg 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 winksmiley.jpg


--------------------
"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
Go to the top of the page
+Quote Post
Ozzy
post 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?).
Go to the top of the page
+Quote Post
cichy
post 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
Go to the top of the page
+Quote Post
Ozzy
post 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.
Go to the top of the page
+Quote Post
Wankster
post 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:
Go to the top of the page
+Quote Post
cichy
post 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 tongue.gif

Pozdro
Go to the top of the page
+Quote Post
Cudi
post 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 winksmiley.jpg


--------------------
"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
Go to the top of the page
+Quote Post
Ozzy
post 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ę:)
Go to the top of the page
+Quote Post
Cudi
post 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 winksmiley.jpg)/


--------------------
"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
Go to the top of the page
+Quote Post
Ozzy
post 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]

:?:
Go to the top of the page
+Quote Post
Bora
post 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 questionmark.gif

[php:1:419528b488]<?php
$db = &staticInstance(DB);

class DB
{
public function __construct($server, $user, $password, $database, $debug)
{
........
}
}
?>[/php:1:419528b488]
Go to the top of the page
+Quote Post
Ozzy
post 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ć.
Go to the top of the page
+Quote Post
Cudi
post 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ą winksmiley.jpg).
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 winksmiley.jpg (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 winksmiley.jpg


--------------------
"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
Go to the top of the page
+Quote Post
Bora
post 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 questionmark.gif

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.
Go to the top of the page
+Quote Post
Ozzy
post 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:)
Go to the top of the page
+Quote Post
Cudi
post 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 smile.gif 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 smile.gif Oczywiście w php 5 jest to już zbędne, klasowe zmienne statyczne załatwiają sprawe smile.gif


--------------------
"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
Go to the top of the page
+Quote Post
Balin
post 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]
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 24.04.2024 - 20:46