原型模式(Prototype)

定義

用原型實(shí)例指定創(chuàng)建對象的種類,并通過拷貝這些原型創(chuàng)建新的對象。

本質(zhì)

克隆生成對象

克隆是手段,目的是生成對象實(shí)例。

登場角色

  • Prototype(原型)

    抽象類,定義用于復(fù)制現(xiàn)有實(shí)例來生成新實(shí)例的方法。

  • ConcretePrototype(具體的原型)

    實(shí)現(xiàn)復(fù)制現(xiàn)有實(shí)例并生成新實(shí)例的方法。

  • Client(使用者)

    使用復(fù)制實(shí)例的方法生成新的實(shí)例。

示例代碼

/**
 * 定義復(fù)制功能的接口
 */
public interface Product extends Cloneable{
    void use(String s);
    Product createClone();
}


/**
 * 具體的原型1
 */
public class MessageBox implements Product{
    private char decochar;
    public MessageBox(char s){
        this.decochar = s;
    }

    @Override
    public void use(String s) {
        System.out.println("use. " + s);
    }

    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product)clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}


/**
 * 具體的原型2
 */
public class UnderlinePen implements Product{
    private char ulchar;
    public UnderlinePen(char c){
        this.ulchar = c;
    }
    @Override
    public void use(String s) {
        System.out.println("use. " + s);
    }

    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product)clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}


/**
 * Client 管理現(xiàn)有類,并可用現(xiàn)有類對象創(chuàng)建出新的對象
 */
public class Manager {
    private HashMap<String,Product> showCase = new HashMap<>();
    public void register(String name,Product product){
        showCase.put(name,product);
    }
    public Product createProduct(String prototypeName){
        return showCase.get(prototypeName).createClone();
    }
}

/**
 * 測試
 */
public class Main {
    public static void main(String args[]){
        Manager manager = new Manager();
        MessageBox messageBox = new MessageBox('m');
        UnderlinePen underlinePen = new UnderlinePen('u');
        manager.register("m",messageBox);
        manager.register("u",underlinePen);

        Product messageBoxClone = manager.createProduct("m");
        Product underlinePenClone = manager.createProduct("u");
        messageBoxClone.use("this is the messageBoxClone");
        underlinePenClone.use("this is the underlineClone");
    }
}

運(yùn)行結(jié)果

use this is the messageBoxClone
use this is the underlineClone

功能

  • 根據(jù)現(xiàn)有實(shí)例創(chuàng)建新的實(shí)例。原型模式會要求對象實(shí)現(xiàn)一個(gè)可克隆自身的接口,這樣就可以通過克隆實(shí)例對象本身來創(chuàng)建一個(gè)新的對象。
  • 為克隆出來的新的對象實(shí)例復(fù)制原型示例屬性的值。

優(yōu)點(diǎn)

  • 封裝,對客戶隱藏具體的實(shí)現(xiàn)細(xì)節(jié),只需要調(diào)用克隆方法就可以得到對象。

缺點(diǎn)

  • 每個(gè)原型的子類都需要實(shí)現(xiàn)clone操作,尤其是在包含引用類型的對象時(shí),clone方法會比較麻煩,必須要能夠遞歸的讓所有的相關(guān)對象都要正確的實(shí)現(xiàn)克隆。

何時(shí)使用

  • 如果一個(gè)對象想要獨(dú)立于他所使用的對象時(shí),可以使用原型模式,讓系統(tǒng)只面向接口編程,在系統(tǒng)需要新的對象的時(shí)候,可以通過克隆來得到。
  • 如果需要實(shí)例化的類是在運(yùn)行時(shí)動(dòng)態(tài)指定的,可以使用原型模式,可以通過克隆原型來得到需要的實(shí)例。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容