我们先来想一下生活中有哪些装饰:
女生的首饰:戒指、耳环、项链等装饰品家居装饰品:粘钩、镜子、壁画、盆栽等
戒指、耳环、项链、壁画、盆栽等都是为了提高颜值或增加美观度。但粘钩、镜子不一样,它们是为了方便我们挂东西、洗漱。所以这些装饰品有两种功能:
增强原有的特性:我们本身就是有一定颜值的,添加装饰品提高了我们的颜值。同样,房屋本身就有一定的美观度,家居装饰提高了房屋的美观度。添加新的特性:在墙上挂上粘钩,让墙壁有了挂东西的功能。在洗漱台装上镜子,让洗漱台有了照镜子的功能。
我们发现装饰品并不会改变物品本身,只是起到一个锦上添花的作用。装饰模式也一样,它的主要作用就是:增强一个类原有的功能、为一个类添加新的功能,并且装饰模式也不会改变原有的类。
装饰模式:动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器,与适配器模式的别名相同,但它们适用于不同的场合。
增强功能的装饰模式
这就是增强功能的装饰模式。以后我们可以添加更多的装饰类,比如:耳环等等!
这里的装饰器也实现了IBeauty接口,并且没有添加新的方法,也就是说这里的装饰器仅用于增强功能,并不会改变Me原有的功能,这种装饰模式称之为透明装饰模式,由于没有改变接口,也没有新增方法,所以透明装饰模式可以无限装饰。
添加新功能的装饰模式
这就是用于新增功能的装饰模式。我们在接口中新增了方法:hangThings,然后在装饰器中将House类包装起来,之前House中的方法仍然调用house去执行,也就是说我们并没有修改原有的功能,只是扩展了新的功能,这种模式在装饰模式中称之为半透明装饰模式。
为什么叫半透明呢?由于新的接口IStickyHookHouse拥有之前IHouse不具有的方法,所以我们如果要使用装饰器中添加的功能,就不得不区别对待装饰前的对象和装饰后的对象。也就是说客户端要使用新方法,必须知道具体的装饰类StickyHookDecorator,所以这个装饰类对客户端来说是可见的、不透明的。而被装饰者不一定要知道House,它可以是实现了IHouse接口的任意对象,所以被装饰者对客户端是不可见的、透明的。由于一半透明,一半不透明,所以称之为半透明装饰模式。
现在我们仿照透明装饰模式的写法,同时添加粘钩和镜子装饰:
第二次装饰时,无法获得上一次装饰添加的方法。原因很明显,当我们用IMirrorHouse装饰器后,接口变为了IMirrorHouse,这个接口中并没有hangThings方法。
我们能否让IMirrorHouse继承自IStickyHookHouse,以实现新增两个功能呢?
可以,但那样做的话两个装饰类之间有了依赖关系,那就不是装饰模式了。装饰类不应该存在依赖关系,而应该在原本的类上进行装饰。这就意味着半透明装饰模式中,我们无法多次装饰。