Domanda

La mia precedente comprensione del motivo del decoratore era che hai ereditato Window con WindowDecorator , quindi nei metodi sovrascritti, fai qualche lavoro aggiuntivo prima di chiamare la Window implementazione di detti metodi. Simile al seguente:

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

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

Tuttavia, in sostanza, questo decodifica la decorazione, quindi come potrebbe essere refactored per usare la composizione invece dell'eredità?

È stato utile?

Soluzione

Siamo spiacenti, il mio C # è un po '(OK, molto) arrugginito, quindi potrebbero esserci alcuni errori di sintassi, ma l'idea di base è corretta.

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();
    }
}

La cosa fondamentale da notare è la nuova interfaccia IWindow ; questo è ciò che ti consente di continuare a usare il polimorfismo.

Altri suggerimenti

Lo scopo del motivo Decorator è migliorare un oggetto con alcune funzionalità (ad esempio aggiungendo il buffering a uno stream) in modo trasparente per il chiamante. Per utilizzarlo nel modo più efficace, si desidera poter scambiare l'implementazione decorata senza il codice di refactoring, il che implica sostanzialmente che è necessario mantenere la gerarchia dell'ereditarietà.

Qual è la tua reale preoccupazione, ovvero cosa significa "codifica la decorazione" veramente meschino? Che tipo di problemi prevedi di voler risolvere? Può darsi che la decorazione non sia proprio l'approccio giusto ...

Devi semplicemente definire LockableWindow un costruttore che prende un'istanza del tipo, Window, che decorerà. Puoi anche farlo tramite le proprietà.

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();    
  }
}

La mia comprensione del motivo del decoratore è che ha lo scopo di consentire un miglioramento runtime delle capacità di un oggetto. Nella spiegazione di Wikipedia, si concentrano su uno stack di componenti per questo scopo.

Non parlo affatto C #, quindi questo è (ovviamente) php-ish. Sembra che l'idea corretta sarebbe:

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 ragazzi esperti, per favore spiegate la disconnessione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top