本人所学设计模式皆出自于 结城浩先生的《图解设计模式》。
类图
为什么使用原型复制模式
我们知道在很多的类中,我们需要这个了类去持有其他类的对象,又或者构成某一个类的对象十分复杂。又或者,你想解耦框架与生成的实例时,比如说下面我们是根据字符串指定要生成的实例,这样我们就可以把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()方法。