本人所學設計模式皆出自於 結城浩先生的《圖解設計模式》。
類圖
爲什麼使用原型複製模式
我們知道在很多的類中,我們需要這個了類去持有其他類的對象,又或者構成某一個類的對象十分複雜。又或者,你想解耦框架與生成的實例時,比如說下面我們是根據字符串指定要生成的實例,這樣我們就可以把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()方法。