petite précision sur le pattern Observer

Eléphant du PHP | 453 Messages

31 janv. 2013, 01:02

Bonjour/bonsoir tout le monde,

Je suis en train de voir les D patterns du gang. Il y en a un que j'aimerai avoir des précisions. Voilà le code :
class CD {
        public $title = "";
        public $band = "";
        protected $_observer = array();
        /*
         * __construct()
         * @param $title,$band
         */        
        function __construct($title,$band) {
            $this->title = $title;
            $this->band = $band;
        }
        
        public function attachObserver($type,$observer){
            $this->_observer[$type][] = $observer;
        }
        
        public function notifyObserver($type){
            if(isset($this->_observer[$type])){
                foreach($this->_observer[$type] as $observer){
                    $observer->update($this);
                }
            }
        }
        
        public function buy(){
            //actions of buying
            $this->notifyObserver('purchased');
        }
    }

class BuyCDNotifyStreamObserver {
        
        function update(CD $cd){
            $activity = "The CD named {$cd->title} by ";
            $activity .= "{$cd->band} was just purchased.";
            ActivityStream::addNewItem($activity);
        }
        public static function tempAddNewItem($item){
            echo $item;
        }
    }
class ActivityStream {
        
        public static function addNewItem($item){
            echo $item;
        }
    }
    function __autoload($class){
        require_once $class.".php";
    }
    
    $title = "Waste of a Rib";
    $band = "Never Again";
    
    $cd = new CD($title,$band);
    $observer = new BuyCDNotifyStreamObserver();
    $cd->attachObserver('purchased',$observer);
    
    $cd->buy();
1. L'auteur du livre utilise une 3e class pour l'affichage. Or je viens d'implémenter une méthode dans l'Observer. Je pense que c'est une erreur d'implémenter une telle méthode puisque la classe ne fait qu'observer (et elle doit le faire bien). Suis je dans la bonne direction ?

2. Pourquoi une méthode static pour l'affichage ?

3. Je suis pas très copain avec la déclaration static. Pouvez vous m'en dire un peu plus svp ?

En vous remerciant par avance, je vous souhaite à toutes et tous bon dev.

Bien à vous
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia

Eléphant du PHP | 453 Messages

31 janv. 2013, 21:20

up
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

01 févr. 2013, 10:28

J'ai prévu de te répondre, mais il faut que je prenne le temps, ce que je n'ai pas avant le week-end ;)
Ne t'impatiente pas !
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 453 Messages

01 févr. 2013, 20:09

Bonjour Zeus,

Je ne suis pas impatient (j'attends juste une réponse rapide :mrgreen: -> c'est de l'humour ). Je sais que sur le forum, il y a des membres qui connaissent bien le sujet et je pensais que pour certains c'est une réponse un peu basique. En tout cas, désolé si je fais une entrée un peu fracassante. C'était pas le but. Je préfère attendre et avoir une réponse de qualité afin de comprendre ces concepts de pattern. Je connais un peu la POO mais j'aimerai comprendre d'avantage. Aussi, cette partie là est un peu abstraite dans mon esprit.

Également, je te remercie infiniment du temps que tu passeras à me répondre à ce sujet. Au lieu de rééditer mon sujet initiale, j'ai une question complémentaire à ce sujet.

Ecrire un singleton, je n'ai vu qu'une seule manière de l'implémenter. Mais est ce que les autres patterns sont à peu près pareil. Je veux dire qu'il y a une seule manière de l'écrire ? Je pense que non puisque cela doit s'écrire suivant le contexte ?

Au plaisir de te lire,

bon dev :)
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

03 févr. 2013, 19:12

1. L'auteur du livre utilise une 3e class pour l'affichage. Or je viens d'implémenter une méthode dans l'Observer. Je pense que c'est une erreur d'implémenter une telle méthode puisque la classe ne fait qu'observer (et elle doit le faire bien). Suis je dans la bonne direction ?
De quelle 3eme classe parles-tu ?
Sur le fond, il ne faut pas prévoir des classes concrètes juste pour observer et notifier, mais plutôt intégrer ça dans ces classes métier existantes.
Est-ce que tu peux m'expliquer avec tes mots à quoi sert un observeur (autrement que "à observer" ;)) car je voudrais comprendre comment tu comptes l'utiliser.
2. Pourquoi une méthode static pour l'affichage ?
Effectivement, ce n'est pas indispensable. Sans en savoir plus, je dirais que l'auteur a dû se dire que n'ayant besoin d'aucun attribut de la classe, sa méthode pouvait être privée
3. Je suis pas très copain avec la déclaration static. Pouvez vous m'en dire un peu plus svp ?
Déclarer une méthode comme étant statique fait en sorte qu'il n'est pas nécessaire d'instancier une classe pour l'utiliser.

Habituellement, lorsque tu écris
class Foo {
  public function bar() {
    echo "foobar";
  }
}
Il faut instancier la classe pour foo appeler la méthode bar()
$instance = new Foo();
$instance->bar();
Maintenant, si tu reprends ta classe pour rendre la méthode statique, plus besoin d'instancier la classe
class Foo {
  static public function bar() {
    echo "toto";
  }
}

Foo::bar();
Cela est pratique quand tu veux une méthode "utilitaire" qui n'a pas besoin d'accèder à des attributs de la classe, et pour éviter l'empreinte mémoire de l'instanciation d'une classe
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 453 Messages

03 févr. 2013, 22:15

Bonsoir Zeus,
De quelle 3eme classe parles-tu ?
Arf, j'ai pas été explicite :oops: Je parlais de la classe : ActivityStream dans ma question.
L'auteur du livre utilise une 3e class (ActivityStream) pour l'affichage. Or je viens d'implémenter une méthode dans l'Observer (BuyCDNotifyStreamObserver::tempAddNewItem()). Je pense que c'est une erreur d'implémenter une telle méthode puisque la classe ne fait qu'observer (et elle doit le faire bien). Suis je dans la bonne direction ?
Avec ta citation ci-dessous (Sur le fond, il ne faut pas prévoir des classes concrètes ....), tu as répondu à ma question.
Sur le fond, il ne faut pas prévoir des classes concrètes juste pour observer et notifier, mais plutôt intégrer ça dans ces classes métier existantes.
C'est bien ce qu'il me semblait.
Est-ce que tu peux m'expliquer avec tes mots à quoi sert un observeur (autrement que "à observer" ;)) car je voudrais comprendre comment tu comptes l'utiliser.
Oui je crois avoir saisi le sens de ce pattern : Lorsque la class A envoi une info à la class B (observateur), la class B informe aux class C, D, E, etc. (class qui dépendent de la class B) de cette info. Les class C, D, E, etc. agiront en conséquence (mise à jour des class C, D, E, etc.).
Dans un MVC, le model peut être un observateur. Lorsque le user envoie une requête au controller depuis la vue, le controller informe le model de la demande. Le model envoi les informations au controller. Le controller finit de traiter les informations pour envoyées ces dernières à la vue finale. Ce qui veut dire aussi que le controller est un strategy alors ? Puisque ce dernier décide de qui fait quoi.
class ModelMeteo {
        
        function donneInfos($info){
            return ($info)? 'les temps est radieux. Température haute, vent doux, pression haute, etc.' : 'les temps est mauvais. Température basse, vent violent, pression basse, etc.' ;
        }
    }
    
    class ControllerMeteo{
        function traiteMeteo(ModelMeteo $observer){
            $infos = $observer->donneInfos(mt_rand(0,1));
            VueMeteo::afficheMeteo($infos);
            
        }
    }
    class VueMeteo{
        static function afficheMeteo($info){
            echo '<p>'.$info.'</p>';
        }
    }
    $meteo = new ControllerMeteo();
    $observer = new ModelMeteo();
    $meteo->traiteMeteo($observer);
Je te remercie pour le static. Depuis, je me suis documenté sur cette manière d'écrire. Je pense avoir compris.

En tout cas, je te remercie infiniment du temps que tu as consacré à me répondre. Si dans mes réponses, tu vois une grossière erreur, n'hésite pas à m'en faire part.

Bon dev :)
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia