Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> EventListener, Czekam na opinie ;)
serafin
post 11.07.2005, 18:26:16
Post #1





Grupa: Zarejestrowani
Postów: 56
Pomógł: 0
Dołączył: 23.11.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Jak w temacie, czy myslicie ze tworzenie specjalnej grupy obiektow do obslugi roznorodnych zdarzen: informacji debug, wyjatkow, bledow jest dobrym pomyslem?

W praktyce wygladaloby to tak:

$events = new EventListener();
$events->registerHandler('Exception', new ExceptionHandler());

// Zlapany w bloku catch() wyjatek:
$events[] = $e;

Powiadamiamy w ten sposob EventListenera o zajsciu nowego zdarzenia. Nastepnie zostaje wykonany lancuszek klas odpowiedzialnych za obsluge danego typu zdarzenia.

Co sadzicie o tym?

Pozdrawiam,


--------------------
Making IT works
Go to the top of the page
+Quote Post
Vengeance
post 11.07.2005, 23:23:43
Post #2





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Czy nie chodzi ci o to samo, czym było by wykorzystanie funkcji set_exception_handler() ?


--------------------
Go to the top of the page
+Quote Post
serafin
post 12.07.2005, 00:53:51
Post #3





Grupa: Zarejestrowani
Postów: 56
Pomógł: 0
Dołączył: 23.11.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Nie, bo imho zdarzenia nie musza miec nic wspolnego z wyjatkami...


--------------------
Making IT works
Go to the top of the page
+Quote Post
Vengeance
post 12.07.2005, 00:59:40
Post #4





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


A może wzorzec Observer ? Sama nazwa, jak i zastosowanie spełnią chyba twoje wymagania.


--------------------
Go to the top of the page
+Quote Post
NuLL
post 13.07.2005, 11:33:41
Post #5





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


Serafin - podoba mi się to rozwiązanie smile.gif


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post
hawk
post 13.07.2005, 19:37:19
Post #6





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

Ostrzeżenie: (0%)
-----


Kilka luźnych uwag:

1) To jest chyba wykorzystanie interfejsu ArrayAccess?

2) Jak Observer, to warto (jeżeli się da) wykorzystać kod z SPL. Nic odkrywczego nie wymyślili, ale może uda się wypracować jakiś standard/

3) Bardzo by się przydał lazy loading, bo przecież ExceptionHandler przeważnie nie będzie wywoływany. Albo handle/proxy (jak w WACT lub phiend.handle), albo delegate/invoker (jak w WACT lub niepublikowanej jeszcze części phiend.handle).

4) Zmieniłbym nazewnictwo, bo EventListener sugeruje, że jest to Observer, a tymczasem jest to drugi element tego wzorca - Observable. Robiony przeze mnie pakiet phiend.logger ma klasę Logger, którza przyjmuje wiadomości/zdarzenia i kieruje do listenerów. Efekt jest chyba podobny...
Go to the top of the page
+Quote Post
NuLL
post 13.07.2005, 23:51:51
Post #7





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


@Hawk Wątpię aby to byl ArrayAccess. Ja osobiscie tez wykorzystuje statyczny rejestr w ktorym zapisuje komunikaty -np. nie mozna sie polaczyc z baza i jechac tylko na cache o ile sie da.

Co handlerow - tez mam swoje - inicjowane wraz z jadrem systemu - choc zastanawiam sie czy jest jakas metoda ktora pozwoli na to aby ominac wywolanie handler jesli w aplikacji nie zajdzie zaden wyjatek cool.gif Logger tez jest a majac do dyspozycji Reflection Class mozna robic naprawde fajne rzeczy smile.gif


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post
jaco
post 13.07.2005, 23:57:57
Post #8





Grupa: Zarejestrowani
Postów: 115
Pomógł: 1
Dołączył: 15.01.2003

Ostrzeżenie: (0%)
-----


@NuLL: Twoje watpliwosci sa nieuzasadnione - chyba nie uwazasz na lekcji tongue.gif

  1. <?php
  2.  
  3. $events = new EventListener();
  4. $events->registerHandler('Exception', new ExceptionHandler());
  5. $events[] = $e;
  6.  
  7. ?>


Ciekawe jak inaczej? winksmiley.jpg
Go to the top of the page
+Quote Post
NuLL
post 14.07.2005, 00:06:59
Post #9





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


Ale ja nie chce rejestrowac tego handlera dopoki nie jest mi potrzebny - ba, najlepiej zadnego handlera nie inicjowac. Tu robisz wywolanie jawnie inicjujac aplikacje - ja chce tego uniknac. Pomysl juz mam smile.gif
Pozatym pomysl z tablica jest poroniony. Lepiej wg mnie.
  1. <?php
  2.  
  3. Logger::Register(&#092;"/e NoSuchComponent\");
  4.  
  5. ?>

Przelaczniki ala DOS i to mi sie podoba smile.gif


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post
serafin
post 14.07.2005, 08:18:15
Post #10





Grupa: Zarejestrowani
Postów: 56
Pomógł: 0
Dołączył: 23.11.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Zmienilem nieco idee. Pokazuje wiec kod:

  1. <?php
  2.  
  3. // Prosty obserwator;)
  4. final class DebugPrint implements Observer {
  5.  
  6. private $subject;
  7.  
  8. public function register(Subject $s) {
  9. $this->subject = $s;
  10. $s->attach($this);
  11. }
  12.  
  13. public function unregister(Subject $s) {
  14. if($this->subject) {
  15. $this->subject->detach($this);
  16. }
  17. }
  18.  
  19. public function update(Subject $s) {
  20. $this->subject = $s;
  21.  $call = debug_backtrace();
  22.  $call = $call[2];
  23.  echo '<p style=\"font-family: Verdana; font-size: 10px; padding: 0px; margin: 0px;\"><b style=\"color: red\">Debug</b>: ' . $this->subject->getMsg() . ' <!--<a href=\"source.php?file='.$call['file'].'&line='.$call['line'].'\" target=\"_blank\">'.basename($call['file']) . ' @ line '.$call['line']. '</a>--></p>';
  24. }
  25. }
  26. // Obserwowane zdarzenie
  27. class Debug implements Subject, ISingleton {
  28. protected $msg;
  29. private $observers;
  30.  
  31. public function attach(Observer $o) {
  32. $this->observers[] = $o;
  33. }
  34.  
  35. public function detach(Observer $o) {
  36. foreach($this->observers as &$observer) {
  37. if($observer === $o) {
  38. unset($observer);
  39. }
  40. }
  41. }
  42.  
  43. public function notify() {
  44. if(count($this->observers)) {
  45. foreach($this->observers as $observer) {
  46. $observer->update($this);
  47. }
  48. }
  49. }
  50.  
  51. public static function &singleton() {
  52. static $instance;
  53.  
  54. if(!($instance instanceof Debug)) {
  55. $instance = new Debug();
  56. }
  57. return $instance;
  58. }
  59.  
  60. public function getMsg() {
  61. return $this->msg;
  62. }
  63.  
  64. public function info($msg) {
  65. $this->msg = $msg;
  66. $this->notify();
  67. }
  68. }
  69.  
  70. // ErrorHandler;)
  71. final class ErrorHandler extends Debug {
  72.  
  73. public function __construct() {
  74. }
  75.  
  76. public static function &singleton() {
  77. static $instance;
  78.  
  79. if(!($instance instanceof ErrorHandler)) {
  80. $instance = new ErrorHandler();
  81. }
  82.  
  83. return $instance;
  84. }
  85.  
  86. public function info($errno, $errstr, $errfile, $errline) {
  87. $this->msg = 'PhpError: ' . $errstr . ' [<u>' . basename($errfile) . '</u> at line <u>' . $errline . '</u>]';
  88. $this->notify();
  89. }
  90. }
  91. // Inicjacja wszystkiego
  92.  
  93. $debug = Debug::singleton();
  94. $ehandle = ErrorHandler::singleton();
  95.  
  96. set_error_handler(array($ehandle, 'info'));
  97.  
  98. /* Debug print to output */  
  99. $d = new DebugPrint();
  100. $d->register($debug);
  101. $d->register($ehandle);
  102.  
  103. /* Debug logging into file observer */
  104. $f = new FileLog();
  105. $f->register($debug);
  106.  
  107. $debug->info(&#092;"Application start\");
  108.  
  109. ?>


Jak widac skorzystalem z wzorca Obserwator. To rozwiazanie jest teraz w miarę szybkie i dosyc skuteczne. Postaram sie zaimplementowac cos jeszcze.

Pozdrawiam,

// Edit

Hawk: Co do lazy loading, masz racje obserwatorzy czy tez exceptionhandler nie zawsze beda potrzebni, w takim razie mozna nieco zmodyfikowac cala idee by zamiast obiektow przekazywac tylko nazwy odpowiednich obserwatorow.

Ten post edytował serafin 14.07.2005, 08:32:03


--------------------
Making IT works
Go to the top of the page
+Quote Post
dasko
post 14.07.2005, 09:06:20
Post #11





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 9.11.2004

Ostrzeżenie: (0%)
-----


@NuLL: Reflection API sprawdziłoby się raczej tylko w przypadku statycznych handlerów klas - tzn jesli masz handler np. XYZ::onDoSomething(). W tym wypadku moznaby albo za kazdym razem leciec reflectionem po klasachw wposzukiwaniu obsługi zdarzeń, albo (tylko raz) stworzyć mapę klas z danymi handlerami.

Ale co jeśli obiektów danego typu jest dużo? Na dodatek lokalnych w jakiejś funkcji? W tym wypadku chyba właśnie lepiej zastosować obserwatorów(chyba nawet trzeba) i po kolei ich rejestrować, tak jak zrobił serafin. Chyba nie ma innego wyjścia smile.gif

Może się mylę, poprawcie jakby co tongue.gif
Go to the top of the page
+Quote Post
Nievinny
post 14.07.2005, 09:15:39
Post #12





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

Ostrzeżenie: (0%)
-----


hymm..., ja myślę, żę obserwator nie jest tu niezbędny, ale bardzo ułatwia pracę. Choć sam debug zrobił bym inaczej (wyświetlanie komunikatów na końcu) i oddzielny obserwator dla wyjątków i błędów. Ogólnie myślę, że jest wiele sposobów prowadzenia debugera i jeżeli chodzi o uniwersalność "statyczne klasy", które mają metody i właściwości statyczne są lepsze i nie trzeba znać wzorca obserwatora. Aczkolwiek eventy mi się podobają, proste i w miarę skuteczne.


--------------------
Go to the top of the page
+Quote Post
Vengeance
post 14.07.2005, 12:22:56
Post #13





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


serafin: zastanawiam się po co te register() i unregister() w Obserwatorze. Chyba przejrzyściej by wyglądało, gdybyś to w obiekcie obserowanym registrował obserwator, a nie odwrotnie.


--------------------
Go to the top of the page
+Quote Post
serafin
post 14.07.2005, 13:24:09
Post #14





Grupa: Zarejestrowani
Postów: 56
Pomógł: 0
Dołączył: 23.11.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Vengeance: rejestrujesz w Obserwatorze Podmiot ktory ma obserwowac. Wiec logiczny jest taki kierunek rejestracji winksmiley.jpg


--------------------
Making IT works
Go to the top of the page
+Quote Post
Vengeance
post 14.07.2005, 13:38:11
Post #15





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


A co logicznego jest w tym, że w Obserwatorze rejestruje Podmiot do obserwacji... z czego ten Obserwator tak na prawde potem rejestruje się w Podmiocie :]

Nie wydaje ci sie to drogą "na około" ?


--------------------
Go to the top of the page
+Quote Post
Nievinny
post 14.07.2005, 16:51:38
Post #16





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

Ostrzeżenie: (0%)
-----


Możesz wyciąć w tych metodach dodawanie do stosu podmiotów, choć ich rejestrowanie jest pomocne. A jak rejestruje się wiele podmiotów pod jednym obserwatorem to jest po prostu zbawienie.


--------------------
Go to the top of the page
+Quote Post
hawk
post 14.07.2005, 17:32:09
Post #17





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

Ostrzeżenie: (0%)
-----


Reflection API jest fantastyczne w przypadku wywalania na ekran informacji o błędzie. Ja np. wyciągam definicję każdej metody z backtrace, włącznie z wszystkimi przełącznikami (final, static, itd), z nazwami i typami argumentów itd. W wolnym czasie chciałem zrobić parsowanie phpdoc w celu wyciągnięcia dodatkowych informacji o argumentach i zwracanym typie (i oczywiście opisu). Jak zrobię, będę mógł zaprezentować phiend.logger biggrin.gif. Chyba że ktoś chce się tym za mnie pobawić...
Go to the top of the page
+Quote Post
serafin
post 14.07.2005, 22:49:37
Post #18





Grupa: Zarejestrowani
Postów: 56
Pomógł: 0
Dołączył: 23.11.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


hawk: przejrzalem twojego phienda2. I'm quite impressed.

Bardzo spodobal mi sie plugin loader i sposob w jaki go zaimplementowales (zwlaszcza Handles i Lazy Loading)

P.S. Nie obrazisz sie jak skorzystam z kilku twoich pomyslow ;> ?


--------------------
Making IT works
Go to the top of the page
+Quote Post
Vengeance
post 14.07.2005, 22:54:09
Post #19





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Czy czasem Lazy Loader nie odnosił się bardziej to logiki biznesowej niż zarządzaniem obiektami ?!


--------------------
Go to the top of the page
+Quote Post
serafin
post 14.07.2005, 23:15:47
Post #20





Grupa: Zarejestrowani
Postów: 56
Pomógł: 0
Dołączył: 23.11.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Lazy loading odnosi sie do zarzadzania obiektami. Obiekt tworzony jest wylacznie wtedy kiedy jest potrzebny, nie wczesniej. Podobnie dziala chyba mechanizm dynamicznego wiazania w javie, obiekt tworzony jest w momencie kiedy jego instancja jest potrzebna.

pozdrawiam,


--------------------
Making IT works
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: 8.07.2025 - 17:12