装饰模式

装饰者模式(Decorator)http://s.click.taobao.com/t_8?e=7HZ5x%2BOzdswsVvyc5Jts79Au1Q%3D%3D&p=mm_24156262_0_0

1.装饰模式是动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

2.装饰模式是把已功能动态的添加更多功能的一种方式。

详细:Decorator装饰模式是一种结构型模式,它主要是解决:“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。继承为类型引入的静态特质的意思是说以继承的方式使某一类型要获得功能是在编译时。所谓静态,是指在编译时;动态,是指在运行时。GoF《设计模式》中说道:动态的给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。

 Decorator结构图

我就用Decorator模式实现一下对每种购物车的功能扩展。

代码如下:

  首先,我们需要一个购物车的接口或者是抽象类,我这里就用抽象类来实现,代码如下:

 

1 namespace DecoratorMode.Cart
2 {
3 public abstract class AbstractCart
4 {
5
6 /// <summary>
7 /// 存储商品编号或者名称
8 /// </summary>
9 /// <returns></returns>
10   public abstract string ProductName();
11 /// <summary>
12 /// 计算购物车总金额
13 /// </summary>
14 /// <returns></returns>
15   public abstract decimal SumMoney();
16 }
17 }

AbstractCart也就是结构图中的Component,然后,我再来实现GeneralCart和StageCart的购物类,这类要继承AbstractCart,也就是图中ConcreteComponent类要继承Component,实现代码如下:

using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DecoratorMode.Cart
{
public class GeneralCart : AbstractCart
{
private string name;
private int productCount;
private decimal sumMoney;
public GeneralCart(string name, int productCount, decimal sumMoney)
{
this.name = name;
this.productCount = productCount;
this.sumMoney = sumMoney;
}
public override string ProductName()
{
return "普通购物车商品";
}

public override decimal SumMoney()
{
return productCount * sumMoney;
}
}
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DecoratorMode.Cart
{
public class StageCart : AbstractCart
{
private string name;
private int productCount;
private decimal sumMoney;
public StageCart(string name, int productCount, decimal sumMoney)
{
this.name = name;
this.productCount = productCount;
this.sumMoney = sumMoney;
}
public override string ProductName()
{
return "分期购物车商品";
}

public override decimal SumMoney()
{
return productCount * sumMoney;
}
}
}

 

 接下来我需要一个Decorator接口或者抽象类,实现代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DecoratorMode.Cart
{
public class Decorator:AbstractCart
{
AbstractCart _cart;
public Decorator(AbstractCart cart)
{
_cart
= cart;
}
public override string ProductName()
{
return _cart.ProductName();
}

public override decimal SumMoney()
{
return _cart.SumMoney();
}
}
}
正如结构图中,这个Decorator即继承了AbstractCart,又包含了一个私有的AbstractCart的对象。这样做的意义是:Decorator类又使用了另外一个Component类。我们可以使用一个或多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。在下来,我要实现普通购物车和分期购物车的功能扩展,它们要继承自Decorator,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DecoratorMode.Cart
{
public class DecoratorGeneralCart:Decorator
{
public DecoratorGeneralCart(AbstractCart cart) : base(cart) { }
public override string ProductName()
{
return base.ProductName();
}
public override decimal SumMoney()
{
return base.SumMoney();
}
}

}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DecoratorMode.Cart
{
public class DecoratorStageCart:Decorator
{
public DecoratorStageCart(AbstractCart cart) : base(cart) { }
public override string ProductName()
{
return base.ProductName();//对基类进行扩展
}
public override decimal SumMoney()
{
return base.SumMoney();//对基类进行扩展
}
}
}
执行代
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace DecoratorMode.DecoratorAbstract
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
AbstractCart cart
= new AbstractCart();
Response.Write(cart.ProductName());
Response.Write(cart.SumMoney());

DecoratorGeneralCart
general= new DecoratorGeneralCart(cart);
Response.Write(general.ProductName());
Response.Write(general.SumMoney());

DecoratorStageCart s
tageCart= new DecoratorStageCart(general);
Response.Write(stageCart.ProductName());
Response.Write(stageCart.SumMoney());

}
}
}
http://s.click.taobao.com/t_8?e=7HZ5x%2BOzdswsVvyc5Jts79Au1Q%3D%3D&p=mm_24156262_0_0

从执行的结果不难看出扩展功能已被添加。最后再说说Decorator装饰模式的几点要点:

1、通过采用组合、而非继承的手法,Decorator模式实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。

2Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明——换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。

3Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。(在这里我想谈一下我的理解:当我们实例化一个Component对象后,要给这个对象扩展功能,这时我们把这个Component对象当作参数传给Decorator的子类的构造函数——也就是扩展方法的功能类。对于引用类型传参时,实际上只是传递对象的地址,这样,在功能扩展是,操作的应该是同一个对象)

 4Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。Decorator是在运行时对功能进行组合。

http://s.click.taobao.com/t_8?e=7HZ5x%2BOzdswsVvyc5Jts79Au1Q%3D%3D&p=mm_24156262_0_0


posted @ 2011-01-20 18:35  向——丁——丁  阅读(316)  评论(0编辑  收藏  举报