今日学习心得——装饰模式
今天學習了大話設計模式中的裝飾模式,對這個模式的理解是在手動敲了代碼之后第三遍看代碼的時候才懂得的。我的心得就是,裝飾模式===>包裹模式。呵呵,包裹模式是我起的名字,我的理解是裝飾模式就是一層一層不斷地往被裝飾的對象上包裹上新的東西。
好了,現在說說裝飾模式,并來印證一下我的“包裹模式”的說法,哈哈。
裝飾模式的(Decorater):動態的給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更靈活。【DP】這是從大話上抄的定義。下面是抄的類圖:
加上注釋的代碼
?
代碼 using System;using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 裝飾模式
{
/// <summary>
/// 定義一個對象接口,規定這些對象都要有Operation()方法
/// </summary>
abstract class Component
{
public abstract void Operation();
}
/// <summary>
/// 具體的對象類
/// </summary>
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("具體對象的操作");
}
}
/// <summary>
/// 裝飾抽象類,繼承自對象接口
///
/// 裝飾者類與Component類既是繼承關系,又是聚合關系
///
/// 在這個類中重寫Operation(),實際上還是執行傳入的Component對象的Operation(),
/// 這樣才能實現一層一層的包裝傳入的Component,賦予其新功能
/// </summary>
abstract class Decorator : Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
//在這個類中重寫Operation(),實際上還是執行傳入的Component對象的Operation()
public override void Operation()
{
if (component != null)
{
component.Operation();
}
}
}
/// <summary>
/// 具體的裝飾類
/// </summary>
class ConcreteDecoretorA : Decorator
{
private string addedstate;
/// <summary>
///重寫Operation()
//首先調用父類的Operation(),然后增加新的內容(功能),------->也可以先進行增加新的內容的操作,再調用父類的Operation()
/// </summary>
public override void Operation()
{
base.Operation();
addedstate = "New State";
Console.WriteLine("具體裝飾對象A的操作");
}
}
class ConcreteDecoretorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("具體裝飾對象B的操作");
}
private void AddedBehavior()
{
Console.WriteLine("具體修飾類B獨有的方法");
}
}
/// <summary>
/// 客戶端使用方法
/// </summary>
class Program
{
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();//實例化一個具體的對象,這就是要被裝飾的原始對象
ConcreteDecoretorA d1 = new ConcreteDecoretorA();//實例化一個具體裝飾類A
ConcreteDecoretorB d2 = new ConcreteDecoretorB();//實例化一個具體裝飾類B
d1.SetComponent(c);//將c賦予d1的component字段,完成d1對c的包裝
d2.SetComponent(d1);//將d1賦予d2的component字段,完成d1對c的第二次包裝,此處有為重要,不能傳c
d2.Operation();//執行最后進行包裝工作的對象的Operation()方法,這里的執行順序是理解這個模式的關鍵,最好使用f11跟一下。
Console.Read();
}
}
}
?
下載版:http://files.cnblogs.com/yuanyuan/%e8%a3%85%e9%a5%b0%e6%a8%a1%e5%bc%8f.rar
執行結果:
?
這個的示例的執行過程用文字描述如下:
首先是對象實例化和具體裝飾類內部字段的賦值:
?
代碼 ConcreteComponent c = new ConcreteComponent();//實例化一個具體的對象,這就是要被裝飾的原始對象ConcreteDecoretorA d1 = new ConcreteDecoretorA();//實例化一個具體裝飾類A
ConcreteDecoretorB d2 = new ConcreteDecoretorB();//實例化一個具體裝飾類B
d1.SetComponent(c);//將c賦予d1的component字段,完成d1對c的包裝
d2.SetComponent(d1);//將d1賦予d2的component字段,完成d1對c的第二次包裝,此處尤為重要,不能傳c
?
?
經過兩次包裝,可以用如下示意圖表示:
下面開始執行具體的顯示命令
?
d2.Operation();//執行最后進行包裝工作的對象的Operation()方法,這里的執行順序是理解這個模式的關鍵,最好使用f11跟一下。?
當執行d2.Operation()時執行的是ConcreteDecoretorB中的如下代碼:
?
public override void Operation(){
base.Operation();
AddedBehavior();
Console.WriteLine("具體裝飾對象B的操作");
}
?
?
?
首先執行父類Decorator的Operation(),即如下代碼:
?
public override void Operation(){
if (component != null)
{
component.Operation();
}
}
?
這個過程首先找到b2的component字段,執行它的Operation()
b2的component是b1,于是執行b1的Operation(),即如下代碼:
?
代碼 /// <summary>///重寫Operation()
//首先調用父類的Operation(),然后增加新的內容(功能),------->也可以先進行增加新的內容的操作,再調用父類的Operation()
/// </summary>
public override void Operation()
{
base.Operation();
addedstate = "New State";
Console.WriteLine("具體裝飾對象A的操作");
}
?
b1的Operation()也是首先找到b1的component字段c,然后執行c的Operation()
?
public override void Operation(){
Console.WriteLine("具體對象的操作");
}
?
于是輸出第一行文字:具體對象的操作。
然后,為b1的私有字段賦了值,并輸出:具體裝飾對象A的操作。
至此,完成了b1的Operation()。
繼續執行b2的Operation(),執行的是b2的私有方法:AddedBehavior(),輸出了:具體修飾類B獨有的方法。
最后輸出:具體裝飾對象B的操作。
?
由此可見,裝飾模式的裝飾過程是通過將被裝飾對象賦給具體裝飾類實例的內部字段component,實現對被裝飾對象一層一層包裝的。而顯示過程是通過具體裝飾類對抽象裝飾父類的Operation()方法的類似遞歸引用(而這種類似遞歸的過程是通過引用內部字段component的Operation()實現的,所以Decorator與Concrete Compnent類必須繼承自一個父類,或者Decorator直接繼承ConcreteCompnent)的方式,實現一層一層的顯示出具體裝飾類對被修飾對象的包裝結果的。
?
做一下總結:
1.ConcreteComponent與Decorator類必須繼承自同一抽象父類,或讓ConcreteCompnenet直接作為Decoratior的父類。
2.Decorator類中有ConcreteComponent類型的字段
3.ConcreteDecorator類中重寫父類Operation()時需要使用base.Operation()調用父類的Operation()。
?
?
本文的一些心得為作者原創,希望能給你幫助,大家共同進步。雖然不是高深見解,也是費了作者一番心血,希望您在轉載的時候能夠保留原文鏈接。
轉載于:https://www.cnblogs.com/yuanyuan/archive/2010/07/06/1772148.html
總結
以上是生活随笔為你收集整理的今日学习心得——装饰模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 读excel图片到数据库和上传图片到数据
- 下一篇: 解决英文版Windows 2003中文乱