被这个模式困惑了一段时间,实际上是被一些术语吓到了,其实并无那么难。java
通俗来讲,就是一个对象原来有一些功能,而后发现功能不够用,想让这个对象更增强大,就使用一个装饰器对这个对象装饰一下,给其在原有的基础上装饰功能。
实现装饰的核心就是这个对象的装饰先后类型不变,因此被装饰的就应该是一个接口或抽象类类型,被装饰器装饰以后仍是能够指向接口或抽象类。angularjs
总接口People
:ide
/** * 一我的的接口 */ public interface People { // 这我的有描述本身的方法 void show(); }
基础的实现,普通人:ui
/** * People的基础实现,一无全部的普通人 */ public class CommonPeople implements People { @Override public void show() { System.out.println("普通人,一无全部"); } }
三个装饰器,分别为人装饰车、房、对象。this
每一个装饰器都是调用原People
的方法,而后为其添加本类应该装饰的功能。全部的装饰器都须要实现People
接口(若是采用抽象类实现须要继承抽象类),保证这个对象被装饰以后仍然是People
类型。阿里云
/** * 车装饰器 */ public class CarDecorator implements People { private People people; public CarDecorator(People people) { this.people = people; } @Override public void show() { this.people.show(); System.out.println("许多年后,终于有车了"); } }
/** * 房装饰器 */ public class HouseDecorator implements People { private People people; public HouseDecorator(People people) { this.people = people; } @Override public void show() { this.people.show(); System.out.println("许多年后,终于有房了"); } }
/** * 对象装饰器 */ public class ObjectDecorator implements People { private People people; public ObjectDecorator(People people) { this.people = people; } @Override public void show() { this.people.show(); System.out.println("许多年后,终于有对象了"); } }
public class Main { public static void main(String[] args) { // 一无全部的普通人 People people = new CommonPeople(); people.show(); System.out.println("-------------------"); // 这我的有车了 people = new CarDecorator(people); people.show(); System.out.println("-------------------"); // 这我的有房了 people = new HouseDecorator(people); people.show(); System.out.println("-------------------"); // 这我的有对象了 people = new ObjectDecorator(people); people.show(); } }
运行结果:spa
若是不使用装饰器,咱们没法这么随意地去拓展对象的功能。code
若是不使用装饰器,类有什么功能,new
出来的对象就有什么功能。三个装饰器,能够排列组合,有房有车的人,有房有对象的人,随意地为这个对象添加功能,想要什么就加什么。而不是像以前生硬地继承,new
什么就有什么功能。
提及装饰器,AngularJS
中但是提供了很是详尽的支持,Decorators in AngularJS视频
就好比AngularJS
中的装饰器,若是是咱们本身写的一个Service
,有一天发现功能不够用了,随便改,反正是我本身写的代码。对象
可是若是你发现第三方库给你提供的Service
方法不够用呢?去改它的代码吗?这是不现实的。
这个慕课网的课程描述了当开发阿里云时,发现UI-Bootstrap
中的一个popover
组件不能自定义模板(如今的UI-Bootstrap
已解决此问题),基于公共组件的开发心得 - 阿里懒懒交流会AngularJS专场
解决方案:
1、改掉它的源代码,本身发布一个库,而后项目中使用这个修改完的库。(没错,阿里的大大们就是这么干的。)
2、设置装饰器,用装饰器为原组件添加新功能。(这个在视频中也提到了,不过是在他们用方案一解决完这个问题时才发现的新方案。偷偷地去看过阿里云中关于popover
弹窗的代码,仍是用的方案一,可能时间久了,很差改动。)