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