实在解释白点便是在不动原来类点根本上去扩展一些新的功能,在客户端利用的过程中不会觉得到利用装饰器和没有利用装饰器的差异,但是它们的结果会改变。
在生活中有很多装饰器模式的例子存在,例如有些人给手机贴膜和安装手机壳、女孩子扮装购买俊秀的衣服打扮自己、给屋子进行装修等等这些操作实际上都是一个装饰器模式的实现。
给手机贴膜并没有改变手机的功能和原来的属性构造,女孩子扮装并没有动刀子给自己整容,给屋子装修在屋子的根本骨架上进行都雅。以是说装饰器模式是在不改变一个类的构造但是须要给它添加新的功能。
意图
动态地给一个工具添加一些额外的职责。就增加功能来说,装饰器模式比较天生子类更为灵巧。
办理问题
降落访问繁芜系统的内部子系统时的繁芜度,简化客户端与之的接口,避免涌现太多的派生子类。
UML图
该模式中包含的角色及其职责
抽象构件(Component)
定义一个抽象接口以规范准备吸收附加任务的工具,也便是最原始的工具。
详细构件(ConcreteComponent)
实现抽象构件,通过装饰角色为其添加一些职责。通过继续实现Component抽象类中的抽象方法。是最核心、最原始、最基本的接口或抽象类的实现,我们要装饰的便是它。
抽象装饰类(Decorator)
继续抽象构件,并包含详细构件的实例,可以通过其子类扩展详细构件的功能。
详细装饰类(ConcreteDecorator)
实现抽象装饰的干系方法,并给详细构件工具添加附加的任务。
在本例子中:
优缺陷
优点
装饰模式与继续关系的目的都是要扩展工具的功能,但是装饰模式可以供应比继续更多的灵巧性。可以通过一种动态的办法来扩展一个工具的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。通过利用不同的详细装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以利用多个详细装饰类来装饰同一工具,得到功能更为强大的工具。详细构件类与详细装饰类可以独立变革,用户可以根据须要增加新的详细构件类和详细装饰类,在利用时再对其进行组合,原有代码无须改变,符合“开闭原则”缺陷
比继续更加灵巧机动的特性,也同时意味着更加多的繁芜性。装饰模式会导致设计中涌现许多小类,如果过度利用,会使程序变得很繁芜。多层装饰比较繁芜,打消问题须要逐级打消增加了打消的难度。运用处景
不通过继续来扩展功能的时候。当工具的功能哀求可以动态地添加,也可以再动态地撤销时。当现有的功能有比较多繁芜扩展,但是不能通过继续难以实现的时候。案例背景
现在我们成了亿万财主,买了一套大别墅,在入住之前我们须要把屋子装修。现在的装修风格有很多种,将利用装饰器模式来实现一个屋子装修的案例。
示例代码
HouseComponent.php 抽象构件(Component)屋子的抽象
interface HouseComponent{ public function decoration();}
HouseConcreteComponent.php 详细构件(ConcreteComponent)详细的屋子
class HouseConcreteComponent implements HouseComponent{ public function decoration(){ echo "屋子装修\n"; }}
Decorator.php 抽象装饰类(Decorator)装修风格抽象
abstract class Decorator implements HouseComponent{ protected $component; / Decorator constructor. @param $component / public function __construct(HouseComponent $component){ $this->component = $component; }}
ChineseStyle.php 详细装饰类(ConcreteDecorator)中式风格
class ChineseStyle extends Decorator{ public function decoration(){ echo "中国风格------"; $this->component->decoration(); }}
EuropeanStyle.php 详细装饰类(ConcreteDecorator)欧式风格
class EuropeanStyle extends Decorator{ private function doing(){ echo "欧式风格------"; } public function decoration(){ $this->doing(); $this->component->decoration(); }}
调用代码:
// 原来的样子$house1 = new HouseConcreteComponent();$house1->decoration();// 采取中式风格$house2 = new ChineseStyle(new HouseConcreteComponent());$house2->decoration();// 采取欧式风格$house3 = new EuropeanStyle(new HouseConcreteComponent());$house3->decoration();
输出结果:
屋子装修中国风格------屋子装修欧式风格------屋子装修
上面的内容便是经由包装之后输出的内容。
第一个没有任何处理以是默认类里面的是什么便是什么。
第二个采取了 ChineseStyle 来装饰,以是输出中国风格。
第三个采取了 EuropeanStyle 来装饰,以是输出欧洲风格。
屋子实质不变,采取不同的装饰器可以有不同的变革,这便是装饰器的魔力所在。给大家留一个作业,可以去思考一下用装饰器模式去布局一下手机、变形金刚、汽车、商品等等业务的实现。
一句话总结:千变万化,实质不变。
如果以为文章还不错,请把文章分享给更多的人学习,在文章中创造有误的地方也希望各位指出更正。现有误的地方也希望各位指出更正。
更多文章关注微信"大众年夜众号:IT不是挨踢
更多互换欢迎加入QQ群:57914282