2015-04-22 23 views
8
public interface IMovable 
    { 
     void Move(); 
    } 

    public interface IUnloadable 
    { 
     void Unload(); 
    } 

    public class Vehicle : IMovable 
    { 
     public void Move() 
     { 
      Console.Write("moving"); 
     } 
    } 

    public class Truck : IMovable, IUnloadable 
    { 
     private Vehicle Veh; 

     public Truck(Vehicle veh) 
     { 
      this.Veh = veh; 
     } 

     public void Move() 
     { 
      Veh.Move(); 
      Console.Write("reverse with beepy noise as well"); 
     } 

     public void Unload() 
     { 
      Console.Write("Unload"); 
     } 
    } 

Se questo è il motivo decoratore. Qual è la differenza tra il pattern decoratore e la composizione? Ho visto esempi di questo modello in cui viene utilizzata l'ereditarietà. Ad esempio l'esempio Java su Wikipedia.Motivo decoratore in C# senza ereditarietà. È corretto?

Non vedo la necessità di utilizzare l'ereditarietà o mi manca qualcosa?

+0

'Qual è la differenza tra il modello decoratore e composizione?'Concettualmente, un decoratore modifica il comportamento dell'oggetto (singolo) che avvolge, mentre il composito (modello) ha un comportamento basato sulla combinazione degli (multipli) oggetti che aggrega. – Fuhrmanator

risposta

8

Il motivo decorativo per definizione implementerà la stessa interfaccia del componente che sta decorando. L'idea è che il codice cliente non ha bisogno di cambiare. Può fare affidamento sulla stessa astrazione che stava usando in precedenza.

Ad esempio:

public interface IMovable 
{ 
    void Move(); 
} 

public class Truck : IMovable 
{ 
    public void Move() 
    { 
     Console.Write("moving"); 
    } 
} 

public class NoisyMovable : IMovable //1.Implement same interface 
{ 
    private IMovable movable; 
    public NoisyMovable(IMovable movable)//2.Wrap same interface 
    { 
     this.movable = movable; 
    } 

    public void Move() 
    { 
     movable.Move();    
     Console.Write("Make noise"); 
    } 
} 

Se si nota la classe NoisyMovable, è un decoratore perché implementa la IMovable astrazione e avvolge lo stesso.

Con questo, non c'è bisogno di creare molte classi come NoisyVehicle, NoisyTruck, NoisyCar ecc Basta il Car, Truck sono abbastanza; puoi aggiungere il rumore usando il singolo decoratore.

IMovable movable = new NoisyMovable(new Truck());//Noisy Truck 
IMovable movable = new NoisyMovable(new Car());//Noisy car 
//etc 

La composizione, d'altro canto, non ha bisogno di avvolgere la stessa implementazione dell'interfaccia implementata. Può implementare un'interfaccia e avvolgere qualsiasi altra.

Quello che hai sbagliato è la tua classe Truck prende l'istanza di Vehicle. Non dovrebbe, invece dovrebbe prendere qualsiasi istanza di IMovable. Dovrebbe funzionare con qualsiasi implementazione di IMovable.

+1

Quindi, se volessi che la classe NoisyMovable fosse IUnloadable, implementerei IUnloadable e inserirò IUnloadable nel suo costruttore? Quindi due parametri? O preferirei creare una nuova classe che decori NoisyMovable? Ma poi non vorrei iniettare un'interfaccia ma una classe concreta ... – user1809104

+0

@ user1809104 Si potrebbe implementare 'IUnloadable' in' NoisyMovable', ma non è utile. Perché puoi archiviarlo come "IUnloadable" o "IMovable" se segui un accoppiamento lento. Se hai bisogno di decorare 'IUnloadable', devi unire un altro' IUnloadable' o hai bisogno di un'interfaccia unificata che sia 'IUnloadable' e anche' IMovable'. –

1

Qual è la differenza tra il motivo decorativo e la composizione?

Concettualmente, un decoratore modifica il comportamento dell'oggetto (singolo) che avvolge, mentre il composito (modello) ha un comportamento basato sulla combinazione degli (multipli) oggetti che aggrega.

Non vedo la necessità di utilizzare l'ereditarietà o mi manca qualcosa?

L'ereditarietà è utile per poter disporre di più decoratori e annidarli. Ad esempio, un SelfDriver che include uno Truck che include uno Vehicle. Ignorando IUnloadable, il secondo decoratore sarebbe SelfDriver:

Class diagram in PlantUML

Il codice sarà riportato:

IMovable sd = new SelfDriver(new Truck(new Vehicle()))); 

Il diagramma oggetto sarebbe simile a questa:

Object diagram in PlantUML