1. 程式人生 > >裝飾模式(Decorator)

裝飾模式(Decorator)

created ase 執行 span blog generic 新功能 運行時 add

一、概念:

  動態的給一個對象添加一些額外的職責,就增加的功能來說,裝飾模式比生成子類更為靈活。【DP】

二、通俗的理解;

  裝飾模式是利用其中的方法為來對對象進行包裝的,這樣每個包裝對象的事項就和如何使用這個對象分離了,

每個對象只關心自己的功能,不需要關心如何添加到對象鏈中去。

三、附加類圖;

技術分享圖片

四、對類圖的解釋;

  Component是定義一個對象接口,可以給這些對象動態的添加職責,ConcreateComponent是定義了一個具體的對象,

也可以給這個對象添加 一些職責。Decorator,裝飾抽象類,繼承了Componet,從外類來擴展Component類的功能,

但對於Component來說,是無需知道Descorator的存在的。至於ConcreteDescorator就是具體的裝飾對象,起到給Component添加職責的

功能。

五、類圖代碼的附加;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Decorator
{
//Component類;

public abstract class Component
{
public abstract void Operation(); //定義的接口中的實現方法
}

public class ConcreteComponent : Component


{
public override void Operation()
{
Console.WriteLine("具體對象的實現操作");
}
}

public class Decorator : Component
{
protected Component component;

public void SetComponent(Component component)
{
//設置Component
this.component = component;

}

public override void Operation()
//重寫Operation(),實際是執行的是Component的Operation()
{
if (component != null)
{
component.Operation();
}
}
}

public class ConcreteDecoratorA : Decorator
{
public override void Operation()
{
base.Operation(); //關鍵的一步
SubedBehavior();
Console.WriteLine("具體裝飾對象A的操作");
}
public void SubedBehavior()
{
//用來區別ConcreateDecoratorA和 ConcreateDecoratorB的區別
}
}


public class ConcreteDecoratorB : Decorator
{

public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("具體裝飾對象B的操作");
}
public void AddedBehavior()
{
//用來區別ConcreateDecoratorA和 ConcreateDecoratorB的區別
}
}

//客戶端代碼的實現;
class Program
{
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();

d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
//裝飾的方法是:首先用ConcreteComponent實例話對象c,然後用ConcreteDecorateA的實例化對象d1來包裝c,在用ConcreteDecoratorB的對象d2來包裝d1,最終執行d2的Operation()

Console.ReadKey();
}
}

}

結果;

技術分享圖片

六、案例的使用;

  在生活中我們時刻個電腦打交道,那麽電腦就是我們補課或缺的一部分,那麽我們肯定會給電腦進行添加東西,進行裝飾了,有外觀上的裝飾,同樣也有內在的性能改變,這就用到了裝飾模式了。

對於電腦我們可以以性能的裝飾來進行實例的演習。性能中,我們可以加固態硬盤、內存條等。那麽進行演示:

代碼的附加:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_01
{

public abstract class Computer
{
public abstract void Show();
}


public class HPComputer:Computer
{
public override void Show()
{
Console.WriteLine("以下是對惠普電腦的一系列操作");
}
}


public class Decorator:Computer
{
protected Computer computer;

public void SetCompueter(Computer computer)
{
this.computer = computer;
}

public override void Show()
{
if(computer!=null)
{
computer.Show();
}
}
}


public class SSD:Decorator
{
public override void Show()
{
base.Show();
Console.WriteLine("我的電腦加裝了固態硬盤");
}
}


public class Memory : Decorator
{
public override void Show()
{
base.Show();
Console.WriteLine("我的電腦加裝了內存條");
}
}


class Program
{
static void Main(string[] args)
{
HPComputer decorator = new HPComputer();
SSD ssd = new SSD();
Memory memory = new Memory();

ssd.SetCompueter(decorator);
memory.SetCompueter(ssd);
memory.Show();
Console.ReadKey();
}
}
}
運行結果;

技術分享圖片

結語:到底在什麽地方使用裝飾模式;

   當系統需要新功能的時候,是向舊的類中添加新的代碼,這些新加的代碼通常裝飾了原有類的核心職責或主要行為。裝飾模式是提供了一個非常好的解決方案,他把每個要裝飾的功能放在單獨的類中,並讓這個類包裝他所要裝飾的對象,因此當需要執行特殊操作行為時,客戶代碼就可以在運行時根據需要有選擇的,按順序的使用裝飾功能 包裝對象了【DP】

優點

1、裝飾者模式比繼承更靈活

2、可以通過一種動態的方式來擴展一個對象的功能,在運行時選擇不同的裝飾器,從而實現不同的行為。

3、通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合。

缺點

1、會產生很多小對象,增加了系統的復雜性。

2、更加易於出錯,排錯也很困難,較為煩瑣。

所以,使用裝飾模式一定要小心小心再小心,萬不可出錯,不然BUG不斷了。

裝飾模式(Decorator)