设计模式记录3之“装饰者模式”
概念:
在软件中,对于功能的扩展,我们会有时候会使用继承来实现对象扩展功能。但是由于继承为类型引入的静态特质,所以缺乏灵活性并且随着功能的增多子类会膨胀。
我们如何避免这种情况呢?可以用到装饰者模式。
定义:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。
装饰者模式采用组合,非继承的方式,解决主体类在多个方向上的扩展功能。实现了在运行时动态的扩展对象的功能,根据需要扩展多个功能,避免了单独使用继承带来的"灵活性差"和"多子类衍生的问题",但是它并非是解决多子类衍生的继承问题。
场景:
比如手机可以有很多功能,有通话功能,拍照功能,短信功能,视频通话功能.... 而手机是分为很多中的,有的没有视频通话功能,只需要通话和短信功能,有的需要通话,短信功能和拍照功能。每种的手机功能是不同。在程序角度看,在此时我们就可以考虑使用"装饰者模式"。流程图是这样的:
现在开始实现步骤。
step 1:
建立一个手机抽象类类,其中定义了手机的品牌和型号,以及它所具有的功能抽象方法:
/// 手机抽象类
/// </summary>
public abstract class Phone
{
private string name; //手机的品牌
public string Name
{
get { return name; }
set { name = value; }
}
private string vevison;//手机型号
public string Vevison
{
get { return vevison; }
set { vevison = value; }
}
public abstract void Function(); //手机功能抽象方法
}
step 2,创建一个Decorator功能抽象类,继承Phone。作用:用于创建手机功能
/// 功能抽象类,继承Phone类
/// 只是一个接口继承不是类继承。
/// 注:接口继承只是继承了一合同,类继承是继承具体实现
/// </summary>
public abstract class Decorate:Phone
{
protected Phone phone;
public Decorate(Phone _pone)
{
this.phone=_pone; //构造器
}
public override void Function()
{
if(phone!=null)
{
phone.Function();
}
}
}
step 3,创建具体对象类PhoneSon,继承自Phone。作用:用于创建多个手机对象。
/// 具体手机对象,继承自Phone
/// </summary>
class PhoneSon:Phone
{
public PhoneSon(string name,string vevison)
{
this.Name = name;
this.Vevison = vevison;
}
public override void Function()
{
Console.WriteLine("这是一个品牌为{0}的手机,手机版本是{1}",this.Name,this.Vevison);
}
}
step 3,创建各个功能,比如拍照功能,通话功能... 继承自Decorate抽象类:
/// 功能扩展A
/// </summary>
public class DecoratorA:Decorate
{
public DecoratorA(Phone p)
: base(p)
{
}
public override void Function()
{
base.Function();
Console.WriteLine("A照相功能扩展");
}
}
/// <summary>
/// B功能扩展
/// </summary>
public class DecoratorB:Decorate
{
public DecoratorB(Phone p)
: base(p)
{ }
public override void Function()
{
base.Function();
Console.WriteLine("B聊天功能扩展");
}
}
/// B功能扩展
/// </summary>
: base(p)
{ }
public override void Function()
{
base.Function();
Console.WriteLine("C扩展了短信功能");
}
step 4,客户端动态的添加手机所需要的功能:
/// 客户端
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
//第一个手机
Phone p1 = new PhoneSon("诺基亚", "5230"); //实例化1个手机
DecoratorA A = new DecoratorA(p1); //装饰它的功能
A.Function();
Console.WriteLine();
//第二个手机
Phone p2=new PhoneSon("HTC","G7"); //实例化
DecoratorA A1 = new DecoratorA(p2); //装饰它的功能
DecoratorB b1 = new DecoratorB(A1);
DecorateC C1 = new DecorateC(b1);
C1.Function();
Console.ReadLine();
输出结果为:
从上面的输出结果,可以知道,PhoneSon抽象类创建具体的手机对象,而Decorator抽象类创建了手机的各个功能的对象。最后在客户端动态的根据需求组合出一部手机。
当我们需要增加功能,比如上网功能,那么我们就可以增加一个这个样的类:
{
public DecoratorD(Phone p)
: base(p)
{ }
public override void Function()
{
base.Function();
Console.WriteLine("C扩展了上网功能");
}
}
在客户端我们可以这样做:
/// 客户端
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
//具有上网功能的手机
Phone p3 = new PhoneSon("三星","S6480");//实例化第三个手机
DecoratorB b2 = new DecoratorB(p3);
DecoratorD d3 = new DecoratorD(b2);
d3.Function();
Console.ReadLine();
}
输出结果:
装饰者模式缺点:
由于使用装饰者模式,会产生比使用继承关系更多的对象。