装饰者模式
来源:互联网 发布:java super.m = 10 编辑:程序博客网 时间:2024/06/03 23:10
装饰者模式的主要功能是通过对象组合的方式来拓展对象的具体功能,通过装饰者模式,可以让对象脱离继承的束缚。
装饰者模式的框架类图如下:
由图中可以看出:装饰者(Decorator)和被装饰者(ConcreteComponent)都继承自同一个接口/抽象类。这也是装饰者模式的特点,通过这种方式可以更方便后面装饰者和被装饰者之间的组合。
其实所谓的组合,更形象点说是用装饰者把被装饰者给包装起来(把被装饰者的对象引用加到装饰者的对象中去)。下面我们来看一下具体的实现代码。
1:首先我们要创建Component抽象类/接口(本实例中用的是接口)
interface Beverage { double Kosten { get; set; } String Description { get; set; } String GetDescription(); double Cost(); }
设计模式中有一个重要原则就是:把要变化的行为和属性分离出来。这里我们把一些装饰者和被装饰者所应该共有的方法和属性加入公共的接口中。
2:然后我们来写Decorator的抽象类
abstract class Decorator:Beverage { protected Beverage beverage; public double Kosten { get; set; } public string Description { get; set; } public abstract string GetDescription(); public virtual double Cost() { return beverage.Cost() + Kosten; } }
此类中把 Cost实现了,并且设为virtual是为了让继承它的所有子类可以直接调用Cost()方法,如果需要修改调料的价格,则只需要重写此方法即可。
3:开始编写修饰者和被修饰者的实体类:
一个具体的意大利浓咖啡类(被修饰者):
class Expresso:Beverage { public double Kosten { get; set; } public string Description { get; set; } public Expresso(double kosten, String description) { this.Kosten = kosten; this.Description = description; } public string GetDescription() { return this.Description+" with "; } public double Cost() { return this.Kosten; } }
一个具体的牛奶类(修饰者)
class Milk:Decorator { public Milk(double kosten,String description,Beverage beverage) { this.Description = description; this.Kosten = kosten; this.beverage = beverage; } public override string GetDescription() { return this.beverage.GetDescription() +" "+ this.Description; } public override double Cost() { return this.beverage.Cost() + this.Kosten*0.8; } }
这里我们重写了牛奶类的Cost方法(给价格打了个8折)
4:调用
class Program { static void Main(string[] args) { Expresso ex1 = new Expresso(2.0, "expresso"); Milk m1=new Milk(0.5,"little Milk",ex1); Milk m2=new Milk(0.8,"big Milk",m1); Console.WriteLine(m2.GetDescription()+" $"+m2.Cost()); Console.ReadKey(); } }
总结:个人觉得装饰者模式有一个很大的缺点,就是经过“装饰”后的对象类型已经不是原来的类的对象了,虽然它们还是继承自原来那个接口/抽象类,但是想要获得被装饰的类的具体类信息,已经不太可能了。
JS端使用装饰者模式:
JS代码不具有继承,所以在使用装饰者模式的时候有点摸不着头脑,笔者强行创建了两个JS类,然后通过组合的方式勉强实现了此设计模式:
function Decorator(kosten,description,obj){this.beverage=obj;this.description=description;this.kosten=kosten;this.GetDescription=function(){return this.beverage.GetDescription()+" "+this.description;}this.Cost=function(){return this.beverage.Cost()+this.kosten;}}function Drinks(kosten,description){this.description=description;this.kosten=kosten;this.GetDescription=function(){return this.description;}this.Cost=function(){return this.kosten;}}var expresso=new Drinks(3,"this is a Expresso");var milk=new Decorator(0.8,"milk",expresso);alert(milk.GetDescription()+" $"+milk.Cost());
PS:第一次写博文,如有错漏,欢迎指正
- 装饰者模式(Derector)
- 装饰者模式
- Decorator 装饰者模式
- 装饰者设计模式
- 装饰者模式
- 装饰者模式
- 装饰者模式
- 装饰者模式(Decorator)
- 装饰者模式
- 装饰者模式
- 装饰者模式
- 装饰者模式 DecoratorPattern
- 设计模式 - 装饰者
- 装饰者模式
- 装饰者模式
- 装饰者模式 - 2
- 装饰者模式
- 装饰者模式
- 算法的力量——李开复
- 增强for循环、Map接口遍历、可变参数方法
- UVa 1645Count
- 使用Apriori算法进行关联分析
- iOS 圆形布局代码笔记
- 装饰者模式
- android反编译工具总结
- 理解 pkg-config 工具
- JMeter使用记录3 -- 性能监控插件jmeter-plugins
- 使用框架的php如果使用定时服务Cronjob
- 深入Pthread(五):线程属性
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
- HDUJ 1203 I NEED A OFFER!
- Restore IP Addresses