淺談設計模式(二):裝飾器模式|中介模式|原型模式
阿新 • • 發佈:2019-12-31
裝飾器模式(Decorator Pattern)
裝飾器模式可用來給一個類動態新增功能,將其裝飾成一個新的類。這就是裝飾器的概念。看到這裡我們可能會想,要達到這種效果,我們用子類繼承父類不就可以了嗎? 沒錯裝飾器模式,本身是一種繼承的替代方案。那既然是替代方案,那麼自然就有它不一樣的地方。 具體區別在哪裡呢? 請看- 裝飾器模式更靈活:繼承時父子類的關係是靜態的,而裝飾器模式是動態的,裝飾類和被裝飾類的關係是執行時候確認的
- 裝飾類和被裝飾類的耦合關係是鬆散的,各自可以獨立變化
// 1.首先我們有一個Pen介面 public interface Pen { public void write(); } // 2.Pencil類實現了Pen這個介面 public class Pencil implements Pen { public void write () { System.out.print("寫"); } } // 3.裝飾類PencilDecorator也實現了Pen這個介面,且代理呼叫Pencil的方法 public class PencilDecorator implements Pen{ Pen pen; public PencilDecorator(Pen pen) { this.pen = pen; } public void write () { pen.write(); } } // 4.用具體裝飾類繼承PencilDecorator,這樣就可以做擴充套件變化 public class BluePencilDecorator extends PencilDecorator{ public BluePencilDecorator (Pen pen) { super(pen); } public void writeBlue () { this.write(); System.out.println("寫出來是藍色的"); } } // 同4.用具體裝飾類繼承PencilDecorator,這樣就可以做擴充套件變化 public class RedPencilDecorator extends PencilDecorator{ public RedPencilDecorator (Pen pen) { super(pen); } public void writeRed () { this.write(); System.out.println("寫出來是紅色的"); } } // 測試 public class Test { public static void main(String args []) { Pen pencil = new Pencil(); RedPencilDecorator redPencil = new RedPencilDecorator(pencil); BluePencilDecorator bluePencil = new BluePencilDecorator(pencil); redPencil.writeRed(); bluePencil.writeBlue(); } }
輸出結果 程式碼的結構如下圖所示 從這裡我們看到了,經過PencilDecorator類這一層的隔離,Pencil類和BluePencilDecorator類/RedPencilDecorator類在一定程度上解耦,從而各自獨立發展了。這就是代理模式能夠替代繼承的原因和它的獨特優勢 唉!! 等一下,好像看到了什麼熟悉的東西,請看 沒錯,這還真就是代理模式的程式碼。 在這裡,我們可以從兩個角度去理解裝飾器模式。
- 第一,從構成上看,裝飾器模式 = 代理模式 + 類繼承。 也就是在代理模式的基礎上,加了一堆繼承[代理類]的子類,從而進行擴充套件變化,並且還儘量減少了和原有類的聯絡。
- 第二,從功能上看,代理模式側重的是“控制”,而裝飾器模式側重的是“擴充套件”。比如說,類A代理了類B,那麼這兩個類由於同一個介面的約束,它們的方法和實現的功能其實是一樣的。而類C裝飾了類D,那麼這個時候類C不僅僅具備了類D的方法,同時還能加入自己的特殊邏輯。
中介者模式(Mediator Pattern)
簡單的說,中介者模式是一個分散到集中的一個過程 還是看下具體的程式碼// Colleague介面 public interface Colleague { public void handleExternal(Mediator mediator); public void handleInternal(); } // 中介者介面 public abstract class Mediator { public Colleague A; public Colleague B; public Colleague C; public Mediator (Colleague A, Colleague B, Colleague C) { super(); this.A = A; this.B = B; this.C = C; } public abstract void handleA (); public abstract void handleB (); public abstract void handleC (); } // 實現了中介者介面的中介者類,封裝了不同Colleague類的物件間的複雜操作 public class ConcreteMediator extends Mediator{ public ConcreteMediator(Colleague A, Colleague B, Colleague C) { super(A,B,C); } public void handleA() { B.handleInternal(); C.handleInternal(); } public void handleB() { A.handleInternal(); C.handleInternal(); } public void handleC() { A.handleInternal(); B.handleInternal(); } } // Colleague類在涉及其他Colleague類的複雜操作的時候,通過中介者呼叫 public class A implements Colleague { public void handleExternal(Mediator mediator) { mediator.handleA(); System.out.println("---------------"); } public void handleInternal() { System.out.println("A"); } } // Colleague類在涉及其他Colleague類的複雜操作的時候,通過中介者呼叫 public class B implements Colleague { public void handleExternal(Mediator mediator) { mediator.handleB(); System.out.println("---------------"); } public void handleInternal() { System.out.println("B"); } } // Colleague類在涉及其他Colleague類的複雜操作的時候,通過中介者呼叫 public class C implements Colleague { public void handleExternal(Mediator mediator) { mediator.handleC(); System.out.println("---------------"); } public void handleInternal() { System.out.println("C"); } } // 測試 public class main { public static void main(String args []) { Colleague a = new A(); Colleague b = new B(); Colleague c = new C(); Mediator mediator = new ConcreteMediator(a,b,c); a.handleExternal(mediator); b.handleExternal(mediator); c.handleExternal(mediator); } }
結果輸出 中介者模式理解起來,就好像
- 你有很多雜亂的物品擺放在房間的不同地方,找起來很不好找,現在把這些物品統一放到一個櫃子裡,方便集中管理。
- 一群人去食堂打飯的時候,如果各自去取菜那麼食堂可能亂做一團,所以這時候食堂大媽就成為了“中介者”
原型模式(Prototype Pattern)
原型模式是什麼? 一句話,原型模式就是克隆物件,完了。 這麼簡單? 這也能叫設計模式? 沒錯,就是這樣 讓我們看下程式碼// 通過實現Cloneable介面並重寫clone方法的方式,讓Bar物件變得可克隆。 public class Bar implements Cloneable { String value; public String getValue () { return value; } public void setValue (String value) { this.value = value; } public Bar clone() { Bar clone = null; try { clone = (Bar)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } } // 呼叫clone方法可以克隆物件 public class mian { public static void main(String args []) { Bar bar = new Bar(); Bar bar2 = bar.clone(); bar.setValue("1"); bar2.setValue("2"); System.out.println(bar.getValue()); System.out.println(bar2.getValue()); } }
執行結果 告訴我,原型模式的本質是什麼 原型模式的本質就是—— 套娃 原型模式的優缺點
- 原型模式的優點: 底層的二進位制實現拷貝,相比起new操作可以節約效能
- 原型模式的缺點: 建構函式沒有呼叫,犧牲了靈活性