標籤:分享圖片 設計 puts 抽象方法 abs 方法 class this 原理
裝飾者模式出現的原因
要對類的功能進行增強,可以建立一個類繼承這個類,這種方法可以解決問題,但如果增加的功能越來越多,那繼承的層次就越來越深,造成繼承冗餘的問題
裝飾者模式可以不用繼承類而增強類的功能,原理是使用對象之間的關聯關係取代類之間的繼承關係
當然還可以使用代理模式來增強類的功能
裝飾者模式中出現的角色
1、裝飾器和被裝飾者的抽象類別
2、被裝飾者(繼承自裝飾器和被裝飾者的抽象類別)
3、裝飾器的抽象
4、裝飾器的具體實現
下面以對門裝鎖再裝貓眼的例子來具體介紹裝飾者模式類結構圖
代碼
Component
//裝飾器和被裝飾者的抽象類別public abstract class Component { //共有的抽象方法,也就是待裝飾的方法 public abstract void show();}
Door
//被裝飾者,繼承自被裝飾者和裝飾器的抽象類別public class Door extends Component { /** * 待裝飾方法的具體實現 */ @Override public void show() { System.out.println("大家好我是門"); }}
ComponentDecorator
//裝飾器的抽象public abstract class ComponentDecorator extends Component { //被裝飾者的引用,可以操作被裝飾者 private Component component; //裝飾者的構造器,用於初始化被裝飾者對象 public ComponentDecorator(Component component) { this.component = component; } /** * 重寫待裝飾方法 */ @Override public void show() { component.show(); //調用被裝飾者的待裝飾方法 }}
LockDecorator
//裝飾器的具體實現public class LockDecorator extends ComponentDecorator { /** * 構造器 * @param component 被裝飾者對象 */ public LockDecorator(Component component) { super(component); } /** * 重寫待裝飾方法 */ @Override public void show() { this.setLock(); //調用裝飾方法 super.show(); //調用父類的待裝飾方法,也就是被裝飾者的待裝飾方法 } /** * 裝飾方法的實現 */ public void setLock(){ System.out.println("為組件加鎖"); }}
EyeDecorator
//裝飾器的具體實現public class EyeDecorator extends ComponentDecorator { /** * 構造器 * @param component 被裝飾者對象 */ public EyeDecorator(Component component) { super(component); } /** * 重寫待裝飾方法 */ @Override public void show() { this.setEye(); //調用裝飾方法 super.show(); //調用父類的待裝飾方法,也就是被裝飾者的待裝飾方法 } /** * 裝飾方法的實現 */ public void setEye(){ System.out.println("為組件加貓眼"); }}
Customer(測試類別)
public class Customer { public static void main(String[] args) { Component door, decorator1, decorator2; door = new Door(); decorator1 = new LockDecorator(door); //裝飾door對象 decorator1.show(); System.out.println("------------------我是嚴肅的分割線------------------"); decorator2 = new EyeDecorator(decorator1); //裝飾decorator1對象 decorator2.show(); }}運行結果
為組件加鎖大家好我是門------------------我是嚴肅的分割線------------------為組件加貓眼為組件加鎖大家好我是門
使用場合
1、需要為某個現有對象添加一個新功能時,可以考慮裝飾者模式或代理模式
2、某個對象的功能經常發生變化或經常需要動態添加功能時
JDK中的InputStream就是經典的裝飾者模式,有興趣的小夥伴可以研究下源碼
Java設計模式之裝飾者模式