首页 > 代码库 > 设计模式之装饰者模式
设计模式之装饰者模式
Decorator
装饰者模式:
类图如下:
注意:
1. Decorator继承于Component【IS A关系】, 继承的目的是使用装饰者和被装饰都拥有相同的接口。这样用户可以统一的把它们看作成Component,操作起来没有不同
2. Decorator又维护一个指向Component实例的引用【HAS A关系】。HAS A Component的目的是让ConcreteDecorator可以在运行时动态给ConcreteComponent增加职责。
也就是说,Decorator跟Component之间,既有静态继承关系又有动态组合关系,
装饰者模式通过继承实现统一了装饰者和被装饰者的接口,通过组合获得了在运行时动态扩展被装饰者对象的能力。
来看一下代码:
/// <summary> /// 酒店服务 /// </summary> public interface IHotelService { /// <summary> /// 客房预订 /// </summary> void Booking(); } public class HotelService : IHotelService { public void Booking() { // 业务逻辑。。。 } } public abstract class DecoratorService : IHotelService { private IHotelService hotelService; public DecoratorService(IHotelService hotelService) { this.hotelService = hotelService; } public virtual void Booking() { if (this.hotelService != null) { this.hotelService.Booking(); } } } /// <summary> /// 携程服务给酒店预订增加了服务 /// </summary> public class CtripService : DecoratorService { public CtripService(IHotelService hotelService) : base(hotelService) { } public override void Booking() { this.Before(); base.Booking(); this.After(); } public void Before() { //租车 + 早餐 + 保险 } public void After() { //景点门票+其他费用 } } /// <summary> /// 去哪儿服务给酒店预订增加了服务 /// </summary> public class QunarService : DecoratorService { public QunarService(IHotelService hotelService) : base(hotelService) { } public override void Booking() { this.Before(); base.Booking(); this.After(); } public void Before() { //租车 + 早餐 + 保险 } public void After() { //景点门票+其他费用 } } public class Customer { public void Travel() { IHotelService hotelService = new HotelService(); DecoratorService ctripService = new CtripService(hotelService); // 如使用第三方的服务:携程,势必要加一些其他的“服务”项目。。。。。 ctripService.Booking(); DecoratorService qunarService = new QunarService(hotelService); // 如使用第三方的服务:去哪儿,势必要加一些其他的“服务”项目。。。。。 qunarService.Booking(); } }
首先,实例化酒店服务,这是我们最想要的服务。
其次,我们可以根据第三方服务公司的服务项目选择服务公司,同时把酒店实例传入。
最后,我们就可预定服务了,同时也预定了第三方的服务。
通过继承,我们使去哪和携程都拥有了相同的预定服务接口,
通过组合,我们在酒店服务的基础上扩展了服务项目。
说到这儿,我感觉装饰者模式和代理模式好像,因为上一篇,我刚写完代理模式,
都是可以在原有功能的基础上扩展功能。仔细想了想,还有有些区别的,于是,我特意用这两个模式分别来实现酒店预订功能,来看到底有什么区别:
1. 代理模式中,用户对HotelService是透明的,也是不关心它的, HotelService是由 代理对象proxy来创建和维护的。
装饰者模式中,是由用户来创建HotelService的,再把它传给具体的装饰者。
可以理解为,代理模式中,代理是知道我要创建谁,而装饰者是不知道我要创建谁,需要你来告诉我。也就是说只要是满足IHotelService接口的,我都可以装饰它。
2. 从类图,我们可以看出,代理对象只有一个,而装饰对象可以有多个,如果代理对象可以是多少,我觉得可以就演变成装饰者模式了。
综上,我认为代理模式和装饰者模式,在一定的条件下,是可以相互转化的。
设计模式之装饰者模式