C#之装饰者模式(Decorator Pattern)

概述

装饰者模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。
例如:给小菜穿衣服,可以一件一件穿,先穿什么,后穿什么,都可以自己定义,需要加什么衣服,只需要再定义一个子类即可;给汽车装饰,给手机装饰等等,使用装饰模式更为方便。

基本类图为:

在这里插入图片描述
Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator类的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能!

特点

  • 装饰对象和真实对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。
  • 装饰对象包含一个真实对象的引用(reference)
  • 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
  • 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

应用范围

  • 需要扩展一个类的功能,或给一个类添加附加职责。
  • 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
  • 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
  • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
优点
  • Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

案例介绍

就以手机下载软件为例,可以使用装饰模式,假如手机需要下载游戏,支付宝,淘宝三个软件,下载顺序无所谓,则基本的设计类图为:

第一种:

在这里插入图片描述

  1. 定义一个抽象的对象接口smartPhone,并添加一个抽象的职责downLoad。
	//定义smartPhone对象接口
    public abstract class smartPhone
    {
        public abstract void downLoad();  //抽象的职责
    }
  1. 定义一个具体的对象,给这个具体的对象添加职责。
	//具体对象
    class concreateSPhone : smartPhone
    {
        public override void downLoad()
        {
            Console.WriteLine("iPhone Download is ready, Now let us download the software:");
        }
    }
  1. 定义一个装饰抽象类decorPhone,继承smartPhone,从外类来扩展smartPhone的功能,但是对于smartPhone来说,无需知道此装饰抽象类的存在。
	//装饰者抽象类
    abstract class decorPhone : smartPhone
    {
        protected smartPhone phone;
        public void setPhone(smartPhone phone)
        {
            this.phone = phone;
        }

        public override void downLoad()
        {
            if (phone != null)
            {
                phone.downLoad();
            }
        }
    }
  1. 定义具体装饰对象类conGOK,conTaoBao,conAliPay,给smartPhone添加职责。
	//具体对象的操作
    class conGOK : decorPhone
    {
        public override void downLoad()
        {
            base.downLoad();
            Console.WriteLine("GOK");
        }
    }

    class conTaoBao : decorPhone
    {
        public override void downLoad()
        {
            base.downLoad();
            Console.WriteLine("TaoBao");
        }
    }

    class conAliPay : decorPhone
    {
        public override void downLoad()
        {
            base.downLoad();
            Console.WriteLine("AliPay");
        }
    }
}
  1. 代码调用,若再想下载其他软件,只需要添加相应的职责。原则:对修改关闭,对扩展开放。
namespace SPhone
{
    class Program
    {
        static void Main(string[] args)
        {
            concreateSPhone phone = new concreateSPhone();

            conGOK GOK = new conGOK();
            conAliPay alipay = new conAliPay();
            conTaoBao taobao = new conTaoBao();

            GOK.setPhone(phone); //下载软件GOK
            alipay.setPhone(GOK); //下载软件AliPay
            taobao.setPhone(alipay); //下载软件TaoBao

            taobao.downLoad();
            Console.Read();
        }
    }
}
  1. 运行结果为:
    在这里插入图片描述
第二种:如果只有一个concreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类;如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。

类图:
在这里插入图片描述
实现代码为:
smartPhone类(ConcreteComponent)

	class smartPhone
	{
	    private string brand;
	    public smartPhone() { }
	    public smartPhone(string brand)
	    {
	        // TODO: Complete member initialization
	        this.brand = brand;
	    }
	
	    public virtual void show()
	    {
	        Console.WriteLine("My phone is:{0} \nNow the software are:", brand);
	    }
	}

phoneComponent类(ConcreteDecorator)

	class phoneComponent : smartPhone
	{
		protected smartPhone component;
		
		public void downLoad(smartPhone component)
		{
		    this.component = component;
		}
		public override void show()
		{
		    if (component != null)
		        component.show();
		}
	}

具体操作类:GOK,AliPay,TaoBao

	class GOK : phoneComponent
    {
        public override void show()
        {
            base.show();
            Console.Write("Glory_of_Kings  ");
        }
    }

    class Alipay : phoneComponent
    {
        public override void show()
        {
            base.show();
            Console.Write("Alipay  ");
        }
    }

    class TaoBao : phoneComponent
    {
        public override void show()
        {
            base.show();
            Console.Write("TaoBao  ");
        }
    }
}

代码调用

namespace smartPhone
{
    class Program
    {
        static void Main(string[] args)
        {
            smartPhone brand = new smartPhone("iPhone");

            GOK GOK = new GOK();
            Alipay Alipay = new Alipay();

            GOK.downLoad(brand);
            Alipay.downLoad(GOK);
            Alipay.show();
            Console.WriteLine("\n-------------------------------\n");

            smartPhone name = new smartPhone("Huawei");
            TaoBao TaoBao = new TaoBao();
            TaoBao.downLoad(name);
            Alipay.downLoad(TaoBao);
            GOK.downLoad(Alipay);
            GOK.show();
            Console.Read();
        }
    }
}

运行结果:
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值