原型设计模式

一、比较简单的设计模式,在项目中使用的场景很是多java

  • 经过给出一个原型对象来指明全部建立的对象的类型,而后用复制这个原型对象的办法建立出更多同类型的对象

二、原型模式有两种表现形式:设计模式

(1)简单形式this

(2)登记形式prototype

  • PrototypeManager 
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();
        }
    }
}

三、两种形式的比较设计

  • 若是须要建立的原型对象数目较少并且比较固定的话,能够采起第一种形式
  • 若是要建立的原型对象数目不固定的话,能够采起第二种形式

四、利用序列化实现深度克隆code

  • 把对象写到流里的过程是序列化(Serialization)过程
  • 把对象从流中读出来的过程则叫反序列化(Deserialization)过程
  • 写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里面
public  Object deepClone() throws IOException, ClassNotFoundException{
        //将对象写到流里
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        //从流里读回来
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }

五、优势:对象

  • 原型模式容许在运行时动态改变具体的实现类型
  • 克隆一个原型就相似于实例化一个类

六、缺点:blog

  • 每个类都必须配备一个克隆方法
  • 配备克隆方法须要对类的功能进行通盘考虑
  • 对于全新的类来讲不是很难,而对于已经有的类不必定很容易
相关文章
相关标签/搜索