首先用比较官方的语言解释:原型模式属于对象创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。进而避免了每次new对象带来的烦恼。
原型模式又分为:简单形式模式、登记形式模式。下面就分别展开讲解。
简单形式原型模式
这种形式一般会涉及三个角色:
1 客户:用来创建对象
2 抽象原型:这是一个抽象原型
3 具体原型:被克隆的对象,他是抽象原型的实现类,并且实现其具体方法。
代码实例:
抽象原型:
public interface Prototype{
//克隆自身的方法
public Object clone();
}
具体原型角色1:
public class PrototypeImpl1 implements Prototype{
public Prototype clone(){
//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
Prototype prototype1 = new PrototypeImpl1 ();
return prototype1 ;
}
}
具体原型角色2:
public class PrototypeImpl2 implements Prototype{
public Prototype clone(){
//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
Prototype prototype2 = new PrototypeImpl2 ();
return prototype2 ;
}
}
客户角色:
public class Client{
public Prototype prototype;
public Client(Protoype prototype)
this.prototype = prototype;
}
public void opration(Prototype ex){
prototype = ex.clone();
}
具体测试类:
public class Test{
public static void main(String[] args){
Prototype prototype1 = new PrototypeImpl1();
Client client = new Client(prototype1);//传入指定的需要克隆的抽象类型
Prototype prototype2 = client.opration(prototype1);//进行克隆
}
}
登记形式的原型模式
登记形式的原型模式无非就是在简单原型模式上添加一个原型管理器(PrototypeManager)角色,创建具体原型类的对象,并且用于记录保存。
抽象原型角色:
public interface Prototype{
public Prototype clone();
public String getName();
public void setName(String name);
}
具体原型角色:
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 Prototype2 , 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<String,Prototype>();
/**
* 私有化构造方法,避免外部创建实例
*/
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 = PrototypeManager.getPrototype("p1").clone();
p3.setName("张三");
System.out.println("第一个实例:" + p3);
//有人动态的切换了实现
Prototype p2 = new ConcretePrototype2();
PrototypeManager.setPrototype("p1", p2);
//重新获取原型来创建对象
Prototype p4 = PrototypeManager.getPrototype("p1").clone();
p4.setName("李四");
System.out.println("第二个实例:" + p4);
//有人注销了这个原型
PrototypeManager.removePrototype("p1");
//再次获取原型来创建对象
Prototype p5 = PrototypeManager.getPrototype("p1").clone();
p5.setName("王五");
System.out.println("第三个实例:" + p5);
}catch(Exception e){
e.printStackTrace();
}
}
}