zoukankan      html  css  js  c++  java
  • 05、Java模式原型模式

    原型模式

    原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。

    原型模式的优点:

    • Java自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
    • 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来。

    原型模式的缺点

    • 需要为每一个类都配置一个 clone 方法
    • 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。

    原型模式的结构如下所示:

    原型模式实现

    原型模式的克隆分为浅克隆和深克隆。

    浅克隆:浅克隆仅仅复制所考虑的对象,不会复制它所引用的成员对象。

    深克隆:对象本身被复制外,对象包含的引用也被复制,也就是其中的成员对象也被复制。

    浅克隆实现

    Java 中的 Object 类提供了浅克隆的 clone() 方法,具体原型类只要实现 Cloneable 接口就可实现对象的浅克隆,这里的 Cloneable 接口就是抽象原型类。其代码如下:

    // 具体原型类
    public class RealizeType implements Cloneable {
        public RealizeType() {
            System.out.println("具体原型创建成功!");
        }
    
        public Object clone() throws CloneNotSupportedException {
            System.out.println("具体原型复制成功!");
            return super.clone();
        }
    }
    
    // 原型模式测试类
    public class Main {
        public static void main(String[] args) throws CloneNotSupportedException {
            RealizeType object1 = new RealizeType();
            RealizeType object2 = (RealizeType) object1.clone();
            boolean isEquals = object1 == object2 ? true : false;
            System.out.println(isEquals);
        }
    }
    

    深克隆实现

    我们针对上述的实例进行修改成深克隆的案例。

    • 在Attribute重写clone()方法,并声明为public

    • 在Attribute的clone方法中,调用super.clone()

    • 在Attribute中实现Cloneable接口

    示例代码如下所示:

    // Attribute
    public class Attribute implements Cloneable{
        private String name;
    
        public Attribute(String name) {
            this.name = name;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    // 原型类
    public class RealizeType implements Cloneable {
        private Attribute attribute;
        public RealizeType() {
            System.out.println("具体原型创建成功!");
        }
    
        public Object clone() throws CloneNotSupportedException {
            System.out.println("具体原型复制成功!");
            RealizeType realizeType = (RealizeType) super.clone();
            realizeType.attribute = (Attribute) realizeType.attribute.clone();
            return realizeType;
        }
    
        public Attribute getAttribute() {
            return attribute;
        }
    
        public void setAttribute(Attribute attribute) {
            this.attribute = attribute;
        }
    }
    
    // 测试类
    public class Main {
        public static void main(String[] args) throws CloneNotSupportedException {
            Attribute attribute1 = new Attribute("属性1");
            RealizeType object1 = new RealizeType();
            object1.setAttribute(attribute1);
    
            Attribute attribute2 = new Attribute("属性2");
            RealizeType object2 = (RealizeType) object1.clone();
            object2.setAttribute(attribute2);
            System.out.println("RealizeType1:" + object1.getAttribute().getName());
            System.out.println("RealizeType2:" + object2.getAttribute().getName());
        }
    }
    

    输出结果如下:

    具体原型创建成功!
    具体原型复制成功!
    RealizeType1:属性1
    RealizeType2:属性2
    

    注意:在原型模式中,如果拷贝的类中含有引用成员变量则需要使用深拷贝的方式。

  • 相关阅读:
    DBMS_SCHEDULER 的使用
    Android 鲜为人知的 8 个小秘密
    你正在使用的移动电话已经 40 岁
    HDU1056:HangOver
    Firefox OS 源码泄露!!!
    上网本 硬盘安装linux 最揪心的回忆
    103 Stacking Boxes
    ip2long之后有什么好处?
    mysql怎么创建,删除,查看索引?
    用mysql查询某字段是否有索引
  • 原文地址:https://www.cnblogs.com/pengjingya/p/14939718.html
Copyright © 2011-2022 走看看