被這個模式困惑了一段時間,實際上是被一些術語嚇到了,其實並無那麼難。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
彈窗的代碼,仍是用的方案一,可能時間久了,很差改動。)