淺談設計模式(二):裝飾器模式|中介模式|原型模式


裝飾器模式(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);
    }
}

 

結果輸出
 
中介者模式理解起來,就好像
 
  1. 你有很多雜亂的物品擺放在房間的不同地方,找起來很不好找,現在把這些物品統一放到一個櫃子里,方便集中管理。
  2. 一群人去食堂打飯的時候,如果各自去取菜那么食堂可能亂做一團,所以這時候食堂大媽就成為了“中介者”
 
 

原型模式(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操作可以節約性能
  • 原型模式的缺點: 構造函數沒有調用,犧牲了靈活性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM