裝飾者模式又叫包裝模式,定義如下:動態的給一個對象添加一些額外的職責,就增加功能來說,裝飾者模式相比生成子類來說更爲靈活。
裝飾者模式的類圖如上:
從圖中可以看到裝飾着模式涉及到四個角色:
1.抽象構件角色Component
Component可以是一個接口或者抽象類,主要是定義一些規則
2.具體構件角色ConcreteComponent
ConcreteComponent是抽象構件的實現類同時也是被裝飾的對象
3.Decorator抽象裝飾者角色
一般是一個抽象者對象,同時實現抽象構件角色中定義的功能,並且含有一個私有屬性執行抽象構件
4.具體裝飾者角色
主要是用來裝飾具體構件角色
/** * 抽象構件 * */ public abstract class Component { // 抽象方法 protected abstract void operation(); }
/** * 具體構件 * */ public class ConcreteComponent extends Component { /** * */ @Override protected void operation() { System.out.println("Hello World!"); } }
public abstract class Decorator extends Component { private Component component; public Decorator(Component component) { this.component = component; } /** * */ @Override protected void operation() { component.operation(); } }
public class ConcreteDecorator extends Decorator { /** * @param component */ public ConcreteDecorator(Component component) { super(component); } // 裝飾方法 private void doSomething() { System.out.println("裝飾"); } @Override protected void operation() { doSomething(); super.operation(); } }
public class Client { public static void main(String[] args) { //被裝飾者 Component component=new ConcreteComponent(); //裝飾者 Decorator decorator=new ConcreteDecorator(component); //裝飾 decorator.operation(); } }
看完裝飾模式大家可能會有一些疑問,不就是要重新擴張一個方法的功能嗎?我直接集成具體構件類重寫裏面的方法不就行了嗎?其實裝飾者模式是繼承關係的一種替代方案,集成是一種高侵入性的,況且我們做開發的也知道,需求是無止境的,你根本不知道用戶的需求最終會變成什麼樣,也許有一天需求變了,那麼你難道還要再次集成然後重寫裏面的方法嗎?
裝飾者模式的優點:
1.裝飾類和被裝飾的對象可以獨立發展不必互相耦合
2.裝飾者模式是繼承關係的一種替代
當然裝飾者模式也是有缺點的,那就是裝飾者的實現類可能會出現類膨脹的情況的,所以是否需要使用裝飾者模式就要看具體的情況了。
裝飾的使用場景
1.需要擴展一個類的功能或給一個類增加附加功能
2.需要動態的給一個對象增加功能並且這些功能可以動態的撤銷
3.需要爲一批兄弟類進行改裝或增加功能
相信大家都做過文件上傳獲取其他和IO相關的操作,其實java IO中主要使用模式就是裝飾者模式,大家可以想象上面的問題,如果爲了增強一個類的功能我們就使用繼承的話,那麼java IO的實現如果使用繼承一定會很可怕的.....
下面是一張java IO使用裝飾者模式的簡單類圖: