Java-設計模式-第六篇-原型複製模式

本人所學設計模式皆出自於 結城浩先生的《圖解設計模式》。

類圖

    

爲什麼使用原型複製模式

    我們知道在很多的類中,我們需要這個了類去持有其他類的對象,又或者構成某一個類的對象十分複雜。又或者,你想解耦框架與生成的實例時,比如說下面我們是根據字符串指定要生成的實例,這樣我們就可以把client封裝到框架中,而不用因爲new Something();必須導包,限制生成實例了。將框架從類名的約束中解放出來。

示例代碼

package com.qiang.inte;

/**
 * 複製功能的接口
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public interface Product extends Cloneable {
    /**
     * 接口定義的某種功能
     *
     * @param string 參數
     */
    void use(String string);

    /**
     * 原型複製的方法,用於自我複製
     *
     * @return 你要複製的對象
     */
    Product createClone();
}
package com.qiang.inte.impl;

import com.qiang.inte.Product;

/**
 * 盒子產品
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class BoxProduct implements Product {
    @Override
    public void use(String string) {
        System.out.println("我用包裝盒精美的包裝着:" + string);
    }

    /**
     * 原型複製的方法,用於自我複製
     *
     * @return 盒子產品
     */
    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}
package com.qiang.inte.impl;

import com.qiang.inte.Product;

/**
 * 塑料袋產品
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class PlasticBagsProduct implements Product {
    @Override
    public void use(String string) {
        System.out.println("我用塑料袋裝着:" + string);
    }

    /**
     * 原型複製的方法,用於自我複製
     *
     * @return 塑料袋產品
     */
    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}
package com.qiang;

import com.qiang.inte.Product;

import java.util.HashMap;

/**
 * 註冊中心
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class Register {
    private HashMap<String, Product> register = new HashMap<>();

    /**
     * 向註冊中心註冊原型
     *
     * @param name    原型的名字
     * @param product 原型
     */
    public void regist(String name, Product product) {
        register.put(name, product);
    }

    /**
     * 獲取一個新的實例
     *
     * @param name 原型名字
     * @return 實例
     */
    public Product getInstance(String name) {
        Product product = register.get(name);
        return product.createClone();
    }
}
package com;

import com.qiang.Register;
import com.qiang.inte.Product;
import com.qiang.inte.impl.BoxProduct;
import com.qiang.inte.impl.PlasticBagsProduct;

/**
 * 測試類
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class Test {
    public static void main(String[] args) {
        //進行註冊
        Register register = new Register();
        BoxProduct boxProduct = new BoxProduct();
        PlasticBagsProduct plasticBagsProduct = new PlasticBagsProduct();
        register.regist("box", boxProduct);
        register.regist("plastic", plasticBagsProduct);

        //獲取對象做事
        Product box1 = register.getInstance("box");
        box1.use("香蕉");
        Product box2 = register.getInstance("box");
        box2.use("香蕉");
        System.out.println(box1+"  !=  "+box2);

        Product plastic1 = register.getInstance("plastic");
        plastic1.use("香蕉");
        Product plastic2 = register.getInstance("plastic");
        plastic2.use("香蕉");

        System.out.println(plastic1+"  !=  "+plastic2);
    }
}

運行結果

我用包裝盒精美的包裝着:香蕉
我用包裝盒精美的包裝着:香蕉
com.qiang.inte.impl.BoxProduct@3cd1f1c8  !=  com.qiang.inte.impl.BoxProduct@3a4afd8d
我用塑料袋裝着:香蕉
我用塑料袋裝着:香蕉
com.qiang.inte.impl.PlasticBagsProduct@1996cd68  !=  com.qiang.inte.impl.PlasticBagsProduct@3339ad8e

思考一下

    每一個實際的產品都要去重複的書寫createClone()方法,我們是不是可以通過模板模式來稍微修改一下呢,那樣的話,我們再寫具體的產品時,只要主義寫產品的內部邏輯就可以了,而不用去關注clone了呢。

    CloneAble接口內部並沒有任何方法,它只是起到標記作用,只有實現了這個接口的類,纔可以調用Object類中的clone()方法。

(最近加班非常多,個人精力跟不上,更新會慢很多...)






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章