栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式 - 原型模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式 - 原型模式

目录

概念编码

实例浅克隆深克隆

对于引用类型单独克隆序列化实现深克隆 总结源码

概念

原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过克隆这些原型创建新的对象原型模式是一种对象创建型模式原型模式最典型的例子就是孙悟空用猴毛复制出和自己一模一样的分身来,通过原型对象克隆出多个一模一样的对象就是原型模式
编码 实例

通过原型模式实现销售管理系统中的客户类(Customer)Customer.java

public class Customer implements Cloneable {

    private String name;

    private String address;

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

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

    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Java中通过实现Cloneable接口重写clone()方法来实现原型模式Test.java

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Customer customer = new Customer();
        customer.setName("张三");
        customer.setAddress("四川省成都市");
        System.out.println(customer);

        Customer customerClone = (Customer) customer.clone();
        customerClone.setAddress("浙江省杭州市");
        System.out.println(customerClone);
    }
}

输出如下:

Customer{name='张三', address='四川省成都市'}
Customer{name='张三', address='浙江省杭州市'}

通过克隆方法创建的对象是全新的对象,它们在内存中拥有新的地址
浅克隆

如上例子,客户地址修改为Address类Customer.java

public class Customer implements Cloneable {

    private String name;

    private Address address;

    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;
    }

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

    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Address.java

public class Address {

    private String province;

    private String city;

    public Address(String province, String city) {
        this.province = province;
        this.city = city;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + ''' +
                ", city='" + city + ''' +
                '}';
    }
}

Test.java

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Customer customer = new Customer();
        customer.setName("张三");
        customer.setAddress(new Address("四川省", "成都市"));
        System.out.println(customer);

        Customer customerClone = (Customer) customer.clone();
        System.out.println(customerClone);

        System.out.println(customer == customerClone);

        System.out.println("--------------");

        customer.getAddress().setProvince("浙江省");
        customer.getAddress().setCity("杭州市");

        System.out.println(customer);
        System.out.println(customerClone);
        System.out.println(customer == customerClone);

    }
}

输出如下:

Customer{name='张三', address=Address{province='四川省', city='成都市'}}
Customer{name='张三', address=Address{province='四川省', city='成都市'}}
false
--------------
Customer{name='张三', address=Address{province='浙江省', city='杭州市'}}
Customer{name='张三', address=Address{province='浙江省', city='杭州市'}}
false

可以发现,修改customer后customerClone的值也跟着修改了在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte等简单数据类型,引用类型包括类、接口、数组等复杂类型,浅克隆与深克隆的区别在于是否支持引用类型的成员变量的复制在浅克隆中,对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有被复制
深克隆 对于引用类型单独克隆

Customer.java

public class Customer implements Cloneable {

    // ... 省略,同上

    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Customer customer = (Customer) super.clone();
        customer.address = (Address) customer.address.clone();
        return customer;
    }
}

Address.java

public class Address implements Cloneable {

    // ... 省略,同上

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

输出如下:

Customer{name='张三', address=Address{province='四川省', city='成都市'}}
Customer{name='张三', address=Address{province='四川省', city='成都市'}}
false
--------------
Customer{name='张三', address=Address{province='浙江省', city='杭州市'}}
Customer{name='张三', address=Address{province='四川省', city='成都市'}}
false

序列化实现深克隆

Customer.java

import java.io.Serializable;


public class Customer implements Serializable {

    // ... 省略,同上

    
    public Customer deepClone() throws Exception {
        // TODO 将对象写入流中
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutputStream oss = new ObjectOutputStream(bao);
        oss.writeObject(this);

        // TODO 将对象从流中取出
        ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Customer) ois.readObject();
    }
}

Address.java

import java.io.Serializable;


public class Address implements Serializable {

	// 需要实现序列化的对象必须实现```Serializable```接口
    // ... 省略,同上

}

输出如下:

Customer{name='张三', address=Address{province='四川省', city='成都市'}}
Customer{name='张三', address=Address{province='四川省', city='成都市'}}
false
--------------
Customer{name='张三', address=Address{province='浙江省', city='杭州市'}}
Customer{name='张三', address=Address{province='四川省', city='成都市'}}
false

在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将被复制
总结

优点

1.原型模式是在内存中进行二进制流的拷贝,比直接new一个对象性能好

缺点

1.必须配备克隆方法
2.对克隆复杂对象或对克隆出的对象进行复杂改造时容易引入风险
3.深拷贝、浅拷贝要运用得当

适用场景

1.类初始化消耗较多资源
2.new产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)
3.构造函数比较复杂
4.循环体中生产大量对象时

原型模式源代码

Object、ArrayList、HashMap、CacheKey

源码

GitHub:https://github.com/Maggieq8324/design_pattern.git

- End -
- 个人学习笔记 -
- 仅供参考 -

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/786004.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号