冬天已经来临,北方的小伙伴们是否是感受天气一天比一天冷了呢?从秋天过渡到冬天,冷了就穿一件毛衣,若是穿上毛衣还以为冷可能会添一件羽绒服,若是下雪天可能就须要穿上雨衣或者带上雨伞了。在咱们生活中这些衣服以拓展的方式给了你温暖,可是它们并非你的一部分,若是到了春天那么这些衣服可能会一一的脱掉了。学习
在软件开发过程当中,有事想用一些现存的类或者组件,这些类或者组件可能只是完成了一些核心功能。但在不改变其结构的状况下,能够动态的拓展其功能。全部这些均可以用装饰模式来实现。this
什么装饰模式
装饰模式:指的是在没必要改变原类文件和使用继承的状况下,动态地扩展一个对象的功能。它是经过建立一个包装对象,也就是装饰来包裹真实的对象。 —— 节选自百度百科编码
装饰模式有两种方式能够实现给一个类或者一个对象添加行为,第一种是使用继承,使用继承是给现有类添加功能的一种有效途径,经过继承一个现有类能够使得子类在拥有自身方法的同时还拥有父类的方法。可是这种方法是静态的,用户不能控制增长行为的方式和时机。第一种则是使用关联的方法,即将一个类的对象嵌入到另外一个对象中,由另外一个对象来决定是否调用嵌入对象的行为以便扩展本身的行为。spa
装饰模式优缺点
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会以为对象在装饰前和装饰后有什么不一样。装饰模式能够在不须要建立更多子类的状况下,将对象的功能加以扩展。设计
优势
缺点
示例
装饰模式的主要角色以下:调试
类图以下所示:code
代码示例:component
// 抽象构件 abstract class Component { public abstract operate() : void; } // 具体构件 class ConcreteComponent extends Component { public operate() : void { console.log('do something'); } } // 装饰角色 abstract class Decorator extends Component { private component : Component = null; constructor(component : Component ) { super(); this.component = component; } public operate() : void { this.component.operate(); } } // 具体装饰者 class ConcreteDecoratorA extends Decorator { constructor(component : Component) { super(component); } // 定义本身的修饰方法 private methodA() : void { console.log('methodA修饰'); } // 重写父类方法 public operate() : void { this.methodA(); super.operate(); } } class ConcreteDecoratorB extends Decorator { constructor(component : Component) { super(component); } // 定义本身的修饰方法 private methodB() : void { console.log('methodB修饰'); } // 重写父类方法 public operate() : void { this.methodB(); super.operate(); } } function main() { let component : Component = new ConcreteComponent(); // 第一次装饰 component = new ConcreteDecoratorA(component); // 第二次装饰 component = new ConcreteDecoratorB(component); // 装饰后运行 component.operate(); } main();
总结
装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。装饰模式能够在不须要创造更多子类的状况下,将对象的功能加以扩展。对象
继承是一种耦合度较大的静态关系,没法在程序运行时动态扩展。在软件开发阶段,关联关系虽然不会比继承关系减小编码量,可是到了软件维护阶段,因为关联关系使系统具备较好的松耦合性,所以使得系统更加容易维护。blog