2015-04-22 50 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"); 
     } 
    } 

如果這是裝飾者模式。裝飾者模式和構圖之間有什麼區別?我已經看到了使用繼承的這種模式的例子。例如維基百科上的Java示例。C#中沒有繼承的裝飾模式。它是否正確?

我沒有看到需要繼承,或者我錯過了什麼?

+0

'裝飾者模式和組成?'從概念上講,裝飾器修改它所包裝的(單個)對象的行爲,而複合(模式)具有基於它聚合的(多個)對象的組合的行爲。 – Fuhrmanator

回答

8

根據定義,Decorator模式將實現與正在裝飾的組件相同的界面。想法是客戶端代碼不需要改變。它可以依賴於它之前使用的相同抽象。

例如:

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

如果你注意NoisyMovable類,它是一個裝飾,因爲它實現了IMovable抽象和封裝相同。

就這樣,你沒有創造很多類,如NoisyVehicleNoisyTruckNoisyCar等就在CarTruck是不夠的;您可以使用單個裝飾器添加噪音。

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

另一方面,組合不需要包裝它實現的接口的相同實現。它可以實現一個接口幷包裝其他任何接口。

你有什麼錯的是你的Truck類需要Vehicle的實例。它不應該,而應該採取IMovable的任何實例。它應該適用於IMovable的任何實現。

+1

因此,如果我想讓NoisyMovable類成爲IUnloadable,那麼我會實現IUnloadable並將IUnloadable注入到其構造函數中?那麼兩個參數?或者我寧願創建一個裝飾NoisyMovable的新課程?但後來我不會注入一個接口,而是一個具體的類... – user1809104

+0

@ user1809104你可以在'NoisyMovable'中實現'IUnloadable',但這沒有用。因爲如果遵循鬆耦合,則可以將其存儲爲「IUnloadable」或「IMovable」。如果你需要修飾'IUnloadable',你需要包裝另一個'IUnloadable',或者你需要一個統一的接口,它是'IUnloadable'和'IMovable' –

1

裝飾模式和組成之間有什麼區別?

從概念上講,裝飾器修改它所包裝的(單個)對象的行爲,而複合(模式)具有基於它聚合的(多個)對象組合的行爲。

我沒有看到需要繼承,或者我錯過了什麼?

繼承是有用的,因此您可以擁有多個裝飾器並將它們嵌套。例如,一個SelfDriver包裝Truck包裝Vehicle。忽略IUnloadable,第二裝飾是 SelfDriver

Class diagram in PlantUML

的代碼看起來是這樣的:

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

的對象圖是這樣的:

Object diagram in PlantUML