美文网首页
创造模式-原型模式

创造模式-原型模式

作者: jxiu | 来源:发表于2018-03-27 18:05 被阅读0次

概述

原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建型模式。

问题

当对象的构造方法非常的复杂,生成新的对象非常的复杂,消耗资源的情况下,我们如何创建对象。

解决方案

通过复制一个指定类型的对象来创建更多同类型的对象。这个被指定的对象就是原型。
复制对象的数据结构。

结构

prototypePattern.png
  • 客户端(Client):使用原型的客户端程序
  • 抽象原型(Prototype):规定了原型对象必须实现的接口(如浅克隆必须实现Cloneable接口)
  • 具体原型(concrePrototype): 抽象原型的具体实现,在客户端使用具体原型,被复制的对象。

java中的克隆模式

浅克隆

浅克隆中

  1. 原型对象的成员变量是值类型(基本类型),将复制一份给克隆对象。
  2. 原型对象的成员变量是引用类型,将引用对象的地址复制一份给克隆对象。就是说两个属性指向同一个对象。对一个属性的修改将影响另外一个属性。
    注意:不可变类型对象(如:String)属性,改变会指向新生成一个新的对象。

浅克隆需要实现Cloneable接口,调用Object的clone()方法(Object的clone()方法是native方法,使用其他语言实现的)。

深克隆

深克隆中无论是基本类型还是引用类型的成员变量都会完整的被复制下来,复制对象的引用类型成员变量地址和原型对象的不相同。
深克隆是通过序列化方式和反序列化实现,序列化就是将对象转换成二进制数组,原型对象还存在内存中,然后将二进制数组进行反序列化重新再内存中生产一个对象。对象序列化需要实现Serializable接口,需要被序列化的成员变量的类也需要实现这个接口。

示例
import java.io.*;

public class User implements Cloneable, Serializable{

    private static final long serialVersionUID = -8906853582930958721L;
    private int age;
    private String name;
    private Address address;

    public User() {
    }

    public User(int age, String name, Address address) {
        this.age = age;
        this.name = name;
        this.address = address;
    }

    /**
     * 深克隆方法:实现Serializable接口,使用ObjetOutputStream和ObjectInputStream实现
     * @return
     */
    public User deepClone(){
        User user = null;
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
            bais = new ByteArrayInputStream(baos.toByteArray());
            ois = new ObjectInputStream(bais);
            user = (User) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            baos = null;
            bais = null;
            try {
                if (oos != null) oos.close();
                if (ois != null) ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return user;

    }
    /**
     * 浅克隆方法:实现Colneable接口使用继承Object类的clone方法
     * @return
     */
    public User weeklyClone(){
        User user = null;
        try {
            user = (User) super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println("该类不支持克隆方法!");
            e.printStackTrace();
        }
        return user;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}
import java.io.Serializable;

public class Address implements Serializable{
    private static final long serialVersionUID = 710758201802876405L;
    private String name;
    private int number;

    public Address(String name, int number) {
        this.name = name;
        this.number = number;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Address{" +
                "name='" + name + '\'' +
                ", number=" + number +
                '}';
    }
}
    public static void main(String[] args) {
        testWeeklyClone();
        testDeepClone();
    }

    public static void testDeepClone(){
        Address address = new Address("上海", 111);
        User xm = new User(10, "小明", address);
        User xmCopy = xm.deepClone();
        System.out.println("小明复制人地址与小明是否是相同对象:" + 
                (xmCopy.getAddress() == xm.getAddress()));
        System.out.println(xm);
        System.out.println(xmCopy);
        address.setName("北京");
        System.out.println("更改小明地址后,小明的地址:" + 
                xm.getAddress());
        System.out.println("更改小明地址后,小明的复制人地址:" + 
                xmCopy.getAddress());
        System.out.println("小明复制人地址与小明是否相同:" + 
                (xmCopy.getAddress() == xm.getAddress()));
    }

    public static void testWeeklyClone(){
        Address address = new Address("上海", 111);
        User xm = new User(10, "小明", address);
        User xmCopy = xm.weeklyClone();
        System.out.println(xm);
        System.out.println(xmCopy);
        address.setName("北京");
        System.out.println("更改小明地址后,小明的复制人地址:" + 
                xmCopy.getAddress());
        System.out.println("小明复制人地址与小明是否相同:" + 
                (xmCopy.getAddress() == xm.getAddress()));
    }

总结

优点
  • 简化复杂对象的创建
缺点
  • 克隆实现比较复杂

相关文章

  • Spring 准备内容

    准备内容 原型设计模式 PropotypeModle 原型模式也属于创造型设计模式,用原型实例指定创建对象的种类,...

  • 【设计模式】之原型模式

    原型模式 什么是原型模式? 原型模式属于创造型模式。当要创建的对象类型可以由已经存在的原型对象确定时,就可以使用它...

  • 原型模式

    原型模式的定义: 使用原型实例指定创建对象的种类。并且通过克隆这个原型创造新的对象,是一种创建型模式。 原型模式的...

  • 设计模式-面相对象7个原则

    设计模式-面相对象7个原则设计模式-创造性模式 单例 原型 工厂 建造者设计模式-设计模式 - 结构性模式 代理 ...

  • 设计模式 - 行为型模式

    设计模式-面相对象5个原则设计模式-创造性模式 单例 原型 工厂 建造者设计模式-设计模式 - 结构性模式 代理 ...

  • 设计模式 - 结构性模式 代理 适配器 桥接 装饰 外观 享元

    设计模式-面相对象5个原则设计模式-创造性模式 单例 原型 工厂 建造者设计模式-设计模式 - 结构性模式 代理 ...

  • 设计模式-创造性模式 单例 原型 工厂 建造者

    设计模式-面相对象5个原则设计模式-创造性模式 单例 原型 工厂 建造者设计模式-设计模式 - 结构性模式 代理 ...

  • 创造模式-原型模式

    概述 原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新...

  • Prototype_pattern-原型模式

    解决问题 原型模式,即通过原型来创造对象,而不是通过new。它在功能上是与单例模式相对的,与工厂模式的功能类似;但...

  • 第3章 创建型模式-原型模式

    一、原型模式简介 二、原型模式的优点 ■ 三、原型模式的使用场景 ■ 四、原型模式的实例

网友评论

      本文标题:创造模式-原型模式

      本文链接:https://www.haomeiwen.com/subject/gtxscftx.html