首页 > 其他 > 详细

设计模式(原型模式)

时间:2021-02-21 00:12:23      阅读:30      评论:0      收藏:0      [点我收藏+]

1、原型模式

(1)概念

用原型实例指定创建对象的种类,并且通过拷贝这些模型创建新的对象。因为对于存在大量相同或相似对象,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源(原型模式基于内存二进制流的复制,要比new更快)

技术分享图片

 

 

(2)好处

创建新的对象比较复杂的时候,可以利用原型模式简化对象的创建过程同时提高了效率

不用重新初始化对象,而是动态的获取对象运行时的状态

如果原始对象发生变化(增加或减少属性),其它的克隆的对象也会发生变化,不用修改代码

(3)缺点

需要为每一个类配备一个克隆方法,这对全新的类不是很难,但是对已有的类进行改造的时候需要修改源代码,违背了OCP原则

 

2、实现

(1)浅克隆

  • 创建Person类,有基本数据类型和引用数据类型的属性
class Person implements Cloneable {
    int age = 8;
    int score = 100;

    Location loc = new Location("bj", 22);
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Location类

class Location {
    String street;
    int roomNo;

    @Override
    public String toString() {
        return "Location{" +
                "street=‘" + street + \‘ +
                ", roomNo=" + roomNo +
                };
    }

    public Location(String street, int roomNo) {
        this.street = street;
        this.roomNo = roomNo;
    }
}
  • 测试
    public static void main(String[] args) throws Exception {
        Person p1 = new Person();
        Person p2 = (Person)p1.clone();
        System.out.println(p2.age + " " + p2.score+" "+p2.loc);

        p1.loc.street = "sh";
        System.out.println(p2.age + " " + p2.score+" "+p2.loc);
    }
8 100 Location{street=bj, roomNo=22}
8 100 Location{street=sh, roomNo=22}

  创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。也就是说对于基本数据类型的成员变量进行的是值传递;

引用数据类型的数据,进行的是引用传递(将成员变量的内存地址复制一份给新的对象),原型中成员变量的值会影响到复制的成员变量的值。

依靠Object类,Object类中含有对象的克隆方法

技术分享图片

(2)深克隆(重写clone方法)

  • 创建Person类
class Person implements Cloneable {
    int age = 8;
    int score = 100;

    Location loc = new Location("bj", 22);
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person p = (Person)super.clone();//基本数据类型的属性和String的克隆
        p.loc = (Location)loc.clone();//引用数据类型的克隆
        return p;
    }
}
  • 创建Location类
class Location implements Cloneable {
    String street;
    int roomNo;

    @Override
    public String toString() {
        return "Location{" +
                "street=‘" + street + \‘ +
                ", roomNo=" + roomNo +
                };
    }

    public Location(String street, int roomNo) {
        this.street = street;
        this.roomNo = roomNo;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
  • 测试
  public static void main(String[] args) throws Exception {
        Person p1 = new Person();
        Person p2 = (Person)p1.clone();
        System.out.println(p2.age + " " + p2.score+" "+p2.loc);

        p1.loc.street = "sh";
        System.out.println(p2.age + " " + p2.score+" "+p2.loc);
    }
8 100 Location{street=bj, roomNo=22}
8 100 Location{street=bj, roomNo=22}

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。进本数据类型进行的是值传递,要为所有的引用数据类型的成员变量申请存储空间,并复制每一个引用数据类型成员变量所引用的对象(引用类型的成员变量还是引用数据类型)进行拷贝

(3)深度克隆(利用序列化和反序列化)

  • 创建Person类并实现序列化接口
import java.io.Serializable;
public class Person implements Serializable {
    private String name;
    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name=‘" + name + ‘\‘‘ +
                ‘}‘;
    }
}

要实现序列化或反序列化必须实现接口Serializable 

  • 运用序列化与反序列化实现对象的克隆
import java.io.*;
public class CloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("Tom");
        try {
//序列化 ByteArrayOutputStream bas
=new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bas); oos.writeObject(person1);//以对象流的方式输出
//反序列化 ObjectInputStream ois
= new ObjectInputStream(new ByteArrayInputStream(bas.toByteArray())); Person person2 =(Person) ois.readObject(); person2.setName("Jack"); bas.flush(); oos.flush(); bas.close(); oos.close(); ois.close(); System.out.println(person1); System.out.println(person2); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Person{name=‘Tom‘}
Person{name=‘Jack‘}

 

3、在Spring中的运用

  • 配置文件中配置bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">
<bean name="student" class="pers.zhb.domain.Student" scope="singleton"></bean>
</beans>

配置文件中的bean是以原型模式的方式进行创建的

获取对象

public void test1(){
        ApplicationContext applicationContext=new
                ClassPathXmlApplicationContext("applicationContext.xml");//创建容器对象
        Student student1=(Student)applicationContext.getBean("student");
    }

 

 

深度克(利用序列化和反序列化)

(1)创建Person类并实现序列化接口:

import java.io.Serializable;
public class Person implements Serializable {
    private String name;
    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name=‘" + name + ‘\‘‘ +
                ‘}‘;
    }
}

要实现序列化或反序列化必须实现接口Serializable 

(2)运用序列化与反序列化实现对象的克隆:

import java.io.*;
public class CloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("Tom");
        try {
            ByteArrayOutputStream bas =new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bas);
            oos.writeObject(person1);
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bas.toByteArray()));
            Person person2 =(Person) ois.readObject();
            person2.setName("Jack");
            bas.flush();
            oos.flush();
            bas.close();
            oos.close();
            ois.close();
            System.out.println(person1);
            System.out.println(person2);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
Person{name=‘Tom‘}
Person{name=‘Jack‘}

 

设计模式(原型模式)

原文:https://www.cnblogs.com/zhai1997/p/14423364.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!