十四、原型模式
原型模式属于对象的创建模式,它要求对象可以“克隆”自身,从而可以复制本身的对象来创建一个实例。通过原型创建的对象,不需要关心这个实例本身,只要实现了克隆方法,就可以通过这个方法来创建新的实例,而无需new一个对象。
原型模式有两种实现方式:简单式和管理式。
首先我们来看简单式的实现,简单式主要包含三个要素:原型接口、具体的原型实现和客户端(客户端提出创建对象的请求),下面我们来看代码:
/**
* 原型接口
*/
public interface Prototype {
/**
* 克隆方法
* @return
*/
public Object clone();
}
/**
* 原型的具体实现类1
*/
public class ConcretePrototype1 implements Prototype {
@Override
public Object clone() {
Prototype prototype = new ConcretePrototype1();
return prototype;
}
}
/**
* 原型的具体实现类2
*/
public class ConcretePrototype2 implements Prototype {
@Override
public Object clone() {
Prototype prototype = new ConcretePrototype2();
return prototype;
}
}
/**
* 客户端类
*/
public class Client {
private Prototype prototype;
public Client(Prototype prototype){
this.prototype = prototype;
}
public void operation(){
Prototype copyPrototype = (Prototype) prototype.clone();
System.out.println(copyPrototype);
}
public static void main(String[] args) {
Client client = new Client(new ConcretePrototype1());
client.operation();
}
}
管理式和简单式类似,只是多了个PrototypeManager来管理原型对象的创建,下面请看代码:
public interface Prototype {
public Object clone();
public void setName(String name);
public String getName();
}
public class ConcretePrototype1 implements Prototype {
private String name;
public Prototype clone(){
ConcretePrototype1 prototype = new ConcretePrototype1();
prototype.setName(this.name);
return prototype;
}
public String toString(){
return "Now in Prototype1 , name = " + this.name;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
public class ConcretePrototype2 implements Prototype {
private String name;
public Prototype clone(){
ConcretePrototype2 prototype = new ConcretePrototype2();
prototype.setName(this.name);
return prototype;
}
public String toString(){
return "Now in Prototype1 , name = " + this.name;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
public class PrototypeManager {
/**
* 用来记录原型的编号和原型实例的对应关系
*/
private static Map<String,Prototype> map = new HashMap<>();
/**
* 私有化构造方法,避免外部创建实例
*/
private PrototypeManager(){}
/**
* 向原型管理器里面添加或是修改某个原型注册
* @param prototypeId 原型编号
* @param prototype 原型实例
*/
public synchronized static void setPrototype(String prototypeId , Prototype prototype){
map.put(prototypeId, prototype);
}
/**
* 从原型管理器里面删除某个原型注册
* @param prototypeId 原型编号
*/
public synchronized static void removePrototype(String prototypeId){
map.remove(prototypeId);
}
/**
* 获取某个原型编号对应的原型实例
* @param prototypeId 原型编号
* @return 原型编号对应的原型实例
* @throws Exception 如果原型编号对应的实例不存在,则抛出异常
*/
public synchronized static Prototype getPrototype(String prototypeId) throws Exception{
Prototype prototype = map.get(prototypeId);
if(prototype == null){
throw new Exception("您希望获取的原型还没有注册或已被销毁");
}
return prototype;
}
}
public class Client {
public static void main(String[]args){
try{
Prototype p1 = new ConcretePrototype1();
PrototypeManager.setPrototype("p1", p1);
//获取原型来创建对象
Prototype p3 = (Prototype) PrototypeManager.getPrototype("p1").clone();
p3.setName("张三");
System.out.println("第一个实例:" + p3);
//有人动态的切换了实现
Prototype p2 = new ConcretePrototype2();
PrototypeManager.setPrototype("p1", p2);
//重新获取原型来创建对象
Prototype p4 = (Prototype)PrototypeManager.getPrototype("p1").clone();
p4.setName("李四");
System.out.println("第二个实例:" + p4);
//有人注销了这个原型
PrototypeManager.removePrototype("p1");
//再次获取原型来创建对象
Prototype p5 = (Prototype)PrototypeManager.getPrototype("p1").clone();
p5.setName("王五");
System.out.println("第三个实例:" + p5);
}catch(Exception e){
e.printStackTrace();
}
}
}
应用场景
当要创建的对象较少或者比较固定的时候采用简单式,当对象创建复杂且不固定的时候采用管理式。
如果同一个对象有多个人修改,需要控制每个人的访问权限的时候可以考虑采用原型模式,原型模式已经和java融为一体了,大家很方便的就能实现自己的原型。