slevinkelevra Δημοσ. 18 Σεπτεμβρίου 2017 Δημοσ. 18 Σεπτεμβρίου 2017 Καλησπερα Καταλαβαινω στη θεωρια το Observer Pattern της PHP , αλλά δεν καταλαβαινω στη πράξη πως ακριβως δουλευει το παραδειγμα που διαβαζω. Το παραδειγμα το βρηκα Site: εδω . Το context ειναι το εξης. Εχεις ενα site και ενα φορουμ. Εχουν διαφορετικο συστημα Login το καθενα και θες με το που γινετε Login στο site να κανει login τον χρηστη και στο φορουμ. Οποτε χρησιμοποιει Observer Pattern. Οριζει abstract classes abstract class Observer { public function __construct($subject = null) { if (is_object($subject) && $subject instanceof Subject) { $subject->attach($this); } } public function update($subject) { // looks for an observer method with the state name if (method_exists($this, $subject->getState())) { call_user_func_array(array($this, $subject->getState()), array($subject)); } } } //============ abstract class Subject { protected $observers; protected $state; public function __construct() { $this->observers = array(); $this->state = null; } public function attach(Observer $observer) { $i = array_search($observer, $this->observers); if ($i === false) { $this->observers[] = $observer; } } public function detach(Observer $observer) { if (!empty($this->observers)) { $i = array_search($observer, $this->observers); if ($i !== false) { unset($this->observers[$i]); } } } public function getState() { return $this->state; } public function setState($state) { $this->state = $state; $this->notify(); } public function notify() { if (!empty($this->observers)) { foreach ($this->observers as $observer) { $observer->update($this); } } } public function getObservers() { return $this->observers; } } Οριζει το class Auth που κανει extend το Subject. Αυτο αλλαζει state καθε φορα που κανεις Login ή logout στο site. Ετσι, θα ειδοποιηθει γ αυτο το state και το Login system του φορουμ κ θα πραξει αναλογα. class Auth extends Subject //site { function login() { // existing code to perform login authentication //signal any observers that the user has logged in $this->setState("login"); } function logout() { // existing code to perform some operation when user logs out // signal any observers that the user has logged out $this->setState("logout"); } } Το Auth_ForumHook κανει extend το Observer και υλοποιει το login ή logout στο φορουμ class Auth_ForumHook extends Observer //forum { function login($subject) { // call the forum's API functions to log the user in } function logout($subject) { // call the forum's API functions to log the user out } } Και μετα αρχικοποιει $auth = new Auth(); $auth->attach(new Auth_ForumHook()); Λαμπρά! Για να καταλαβω : [1] Εδω $ auth - > attach ( new Auth_ForumHook( ) ) ; Πρωτα πρεπει να φτιαχτει το Auth_ForumHook γιατι αλλιως δεν θα εχει τι να κανει attach. To Auth_ForumHook κατασκευαζεται συμφωνα με τις οδηγιες της construct στην Observer η οποια...???Περνει το Auth_ForumHook και το κανει null (?) και μετα τσεκαρει αν ειναι object (μα ειναι null) και αν ειναι instanceof του Subject (ψηλε, ειναι null). Και μετα εκτελει την attach. Η οποια δεν οριζεται πουθενα αλλου, παρα μονο μεσα στην Subject. Αρα χρησιμοποει την attach της Subject, επειδη στον ορισμο της εκει, εχει αναφορα στην Observer public function attach(Observer $observer) { Δεν καταλαβα την υπαρξη του null. Ουτε τη σχεση με την attach της Subject και της Observer. Κανονικα θα πρεπει να πιανει το Auth_ForumHook και να το πεταει στην attach της Observer η οποια εκτελει την attach της Subject ? Αρα γιατι να ξανακαλεσεις την attach εδω : $ auth - > attach ( new Auth_ForumHook( ) ) ; ??? Για την attach της Observer σχολιαζει οτι "accepts an instance of an observable subject and attaches itself to the subject". Ε ναι με ποιο τροπο λοιπον το κανεις attach? [2] Επισης το Auth_ForumHook ειναι instance της Observer, οχι της Subject. Αρα γιατι στον ελεγχο της attach της Observer εχει subject instanceof Subject [3] Επισης στο update της Observer, στο if (method_exists($this, $subject->getState())) { ειναι προφανες οτι αναφερεται στο getState της Subject. Αυτη η σχεση πως προεκυψε παλι? Το μονο που μπορω να σκεφτω ειναι η αναφορα της Observer στην Subject , στο public function attach(Observer $observer) { Ειλικρινα δεν εχω καποιον αλλο να ρωτησω, το χωριο κ την επαρχια μου μεσα. Η κυρια Ευτέρπη δεν ξέρει PHP. Μόνο Javascript. Ευχαριστω πολυ.
defacer Δημοσ. 18 Σεπτεμβρίου 2017 Δημοσ. 18 Σεπτεμβρίου 2017 Disclaimer: το implementation που βλέπεις είναι για το πέος, οπότε κινήσου ανάλογα. WAY too much magic and assumptions being made. if (method_exists($this, $subject->getState())) { // 1 call_user_func_array(array($this, $subject->getState()), array($subject)); // 2 } Το (1) κοιτάει αν ο observer έχει μια method με όνομα ίδιο με αυτό της επιστρεφόμενης τιμής της $subject->getState() και το (2) την καλεί. Το subject έχει περάσει τον εαυτό του στον observer εκεί που κάνει $observer->update($this).
slevinkelevra Δημοσ. 19 Σεπτεμβρίου 2017 Μέλος Δημοσ. 19 Σεπτεμβρίου 2017 Ναι, εχεις δικιο. Νομιζω οτι αυτος εδω τα καταφερνει καλυτερα να εξηγησει τι παιζει, με πιο μαζεμενο κωδικα https://sourcemaking.com/design_patterns/observer/php
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα