1. 程式人生 > >淺談設計模式(二):裝飾器模式|中介模式|原型模式

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

裝飾器模式(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操作可以節約效能
  • 原型模式的缺點: 建構函式沒有呼叫,犧牲了靈活性