Question

Ma compréhension précédente du modèle de décorateur était que vous héritez de Window avec WindowDecorator , puis dans les méthodes remplacées, effectuez un travail supplémentaire avant d'appeler le Window 'implémentation desdites méthodes. Semblable à ce qui suit:

public class Window
{
    public virtual void Open()
    {
        // Open the window
    }
}

public class LockableWindow : Window // Decorator
{
    public virtual void Open()
    {
        // Unlock the window
        base.Open();
    }
}

Cependant, cela consiste essentiellement à coder en dur la décoration, alors comment serait-il remanié pour utiliser la composition au lieu de l'héritage?

Était-ce utile?

La solution

Désolé, mon C # est un peu (très, très) rouillé. Il peut donc y avoir quelques erreurs de syntaxe, mais l’idée de base est la bonne.

public interface IWindow
{
    void Open();
}

public class Window : IWindow
{
    public virtual void Open()
    {
        // Open the window
    }
}

public class LockableWindow : IWindow
{
    private IWindow _wrappedWindow;

    public LockableWindow(IWindow wrappedWindow)
    {
        _wrappedWindow = wrappedWindow;
    }

    public virtual void Open()
    {
        // TODO Unlock window if necessary
        _wrappedWindow.open();
    }
}

Le point clé à noter est la nouvelle interface IWindow . c'est ce qui vous permet de continuer à utiliser le polymorphisme.

Autres conseils

Le motif Decorator a pour objectif d'améliorer certaines fonctionnalités d'un objet (par exemple, l'ajout d'une mémoire tampon à un flux) de manière transparente pour l'appelant. Afin de l'utiliser au mieux, vous voulez pouvoir basculer dans l'implémentation décorée sans refactoriser le code, ce qui implique en principe que vous devez conserver la hiérarchie des héritages.

Quelle est votre préoccupation actuelle, c’est-à-dire que "ceci code la décoration" Vraiment méchant? Quel genre de problèmes envisagez-vous vouloir résoudre? Il se peut que la décoration ne soit pas tout à fait la bonne approche ...

LockableWindow définit simplement un constructeur qui prend une occurrence du type Window qu’elle décorera. Vous pouvez également le faire via les propriétés.

public class Window
{    
  public virtual void Open()    
  {        
   // Open the window    
  }
}

public class LockableWindow // Decorator
{    
  private Window window;

  public LockableWindow(Window w)
  {
     window = w;
  }      

  public virtual void Open()    
  {        
    // Unlock the window        
    window.Open();    
  }
}

D'après ce que je comprends, le motif de décorateur est destiné à permettre une amélioration, au moment de l'exécution, des capacités d'un objet. Dans l'explication wikipedia, ils se concentrent sur une pile de composants à cette fin.

Je ne parle pas du tout C #, c'est donc (évidemment) php-ish. Il semble que la bonne idée serait:

class image{

     function open(){ ... }

} //end of class

class decoratedImage extends image{

     private goodies=array(); //the alleged 'component stack'

     function addGoodie($item){
          $this->goodies[]=$item;
     }

     function open()}{

          parent::open();
          foreach ($this->goodies as $componentClassName){

               $component=new $componentClassName();
               $component->apply($this);

          }

     }

} //end of class

Oh, expérimentés, veuillez expliquer la déconnexion.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top