1. 程式人生 > >GOF設計模式——Prototype模式

GOF設計模式——Prototype模式

port blog 輸出 exc turn crete sta string -o

一、什麽是Prototype模式?

在編程中,我們可以使用new關鍵字指定類名來生成類的實例,但是有時候也會有不指定類名的前提下生成實例。因為有時候對象種類繁多,無法將它們整合到一個類中;或者,生成實例的過程過於復雜,難以根據類生成實例;又或者,想要將類與框架解耦。這時,為了能夠在不使用類名的情況下生成實例,可以使用Prototype模式,Prototype模式又叫原型模式,專門做一些“復制”的操作。

二、Prototype模式思想

技術分享圖片

Client負責調用Prototype接口生成實例,具體的實例生成的過程交給ConcretePrototype實現類,那麽在Client調用Prototype這整個過程中都沒有涉及ConcretePrototype類名。

三、具體實例

假設現在要做一個功能,將字符串放入方框中顯示,或者加上下劃線等操作。

技術分享圖片

1、Manager類

package com.cjs.Prototype;
 
import java.util.HashMap;
 
public class Manager {
    private HashMap showCase = new HashMap();
    public void register(String name, Product proto) {
        showCase.put(name, proto);
    }
 
    public Product create(String protoName) {
        Product product 
= (Product) showCase.get(protoName); return product.createClone(); } }

Manager類定義了兩個方法,一個用於註冊類,另一個是根據關鍵信息創建實例。

2、Product類

package com.cjs.Prototype;
 
public abstract class Product implements Cloneable {
    public abstract void use(String s);
 
    public final Product createClone() {
        Product product 
= null; try { product = (Product) clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return product; } }

Product類定義了一個抽象方法use,用於讓子類實現時擁有個性的行為;還有一個被final修飾的createClone方法,用於復制類,生成實例,這裏用到了Template Method模式。

3、UnderlinePen類

package com.cjs.Prototype;
 
public class UnderlinePen extends Product {
    private char ulchar;
 
    public UnderlinePen(char ulchar) {
        this.ulchar = ulchar;
    }
 
    @Override
    public void use(String s) {
        int length = s.getBytes().length;
        System.out.println("\"" + s + "\"");
        System.out.print(" ");
        for (int i = 0; i < length; i++) {
            System.out.print(ulchar);
        }
        System.out.println("");
    }
}

4、MessageBox類

package com.cjs.Prototype;
 
public class MessageBox extends Product {
    private char decochar;
 
    public MessageBox(char decochar) {
        this.decochar = decochar;
    }
 
    @Override
    public void use(String s) {
        int length = s.getBytes().length;
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }
        System.out.println("");
        System.out.println(decochar + " " + s + " " + decochar);
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }
        System.out.println();
    }
}

5、Main類

package com.cjs.Prototype;
 
public class Main {
    public static void main(String[] args) {
        Manager manager = new Manager();
        UnderlinePen underlinePen = new UnderlinePen(‘~‘);
        System.out.println("main underlinePen‘s hashCode = " + underlinePen.hashCode());
        MessageBox messageBox1 = new MessageBox(‘*‘);
        System.out.println("main messageBox1‘s hashCode = " + messageBox1.hashCode());
        MessageBox messageBox2 = new MessageBox(‘/‘);
        System.out.println("main messageBox2‘s hashCode = " + messageBox1.hashCode());
        manager.register("strong message", underlinePen);
        manager.register("warning box", messageBox1);
        manager.register("slash box", messageBox2);
 
        Product p1 = manager.create("strong message");
        System.out.println("Prototype p1‘s hashCode = " + p1.hashCode());
        Product p2 = manager.create("warning box");
        System.out.println("Prototype p2‘s hasCode = " + p2.hashCode());
        Product p3 = manager.create("slash box");
        System.out.println("Prototype p3‘s hasCode = " + p2.hashCode());
 
        p1.use("hello world");
        p2.use("hello world");
        p3.use("hello world");
    }
}

輸出結果:


技術分享圖片

Main類裏面對於每個生成的實例都打印出它們的hashCode,從Console窗口可以看出,即使是復制出來的實例,它們都不是同一個對象。在整個創建實例的過程中,除了一開始註冊的時候用到了類名,其余的只用到了關鍵字,如“strong message”,“warning box”等,就可以創建對應的實例對象。

四、Prototype的作用

1、對象種類繁多,實現功能類似,使用Prototype模式可以便於源程序的管理,合理減少了類的數量;

2、在難以根據類生成實例的時候,有時候需要創建的類非常復雜,如果經常需要用到此類的對象,那麽每次創建的時候會非常繁瑣,相反,通過實例生成實例的方式會簡單得多。

3、解耦

前面也提過很多次,一旦在某個類文件使用了一個類名來創建實例對象,那麽這個類文件就跟使用的這個類具有高度的耦合性,特別是如果框架也這麽做,那麽這個框架就只適用某些類。

GOF設計模式——Prototype模式