网站实名制认证备案,国外直播sdk,西安 房产网站建设,分销商管理系统一、前言 原型模式是一种创建型设计模式#xff0c;它允许在运行时通过克隆现有对象来创建新对象#xff0c;而不是通过常规的构造函数创建。在原型模式中#xff0c;一个原型对象可以克隆自身来创建新的对象#xff0c;这个过程可以通过深度克隆或浅克隆来实现。简单说原型…
一、前言 原型模式是一种创建型设计模式它允许在运行时通过克隆现有对象来创建新对象而不是通过常规的构造函数创建。在原型模式中一个原型对象可以克隆自身来创建新的对象这个过程可以通过深度克隆或浅克隆来实现。简单说原型模式其实就是从一个对象再创建另外一个可定制的对象而且不需知道任何创建的细节。 原型模式包含三个角色 ①Prototype抽象原型类定义用于克隆自身的接口通常是一个抽象类或接口其中声明了一个克隆方法 clone()用于创建一个新的对象具体的克隆操作由子类实现。 ②ConcretePrototype具体原型类实现 Prototype 接口实现 clone() 方法完成对象的克隆操作。每个具体原型类都有自己的一些属性和方法不同的具体原型类之间具有不同的实现方式。 ③Client客户类使用原型模式创建新的对象在原型模式中客户端通过克隆接口来创建新的对象而不是通过实例化的方式。客户端需要获取一个原型对象并通过克隆方法来创建新的对象从而避免了创建新对象的开销。 原型模式的克隆分为浅拷贝和深拷贝两种。
二、浅拷贝 创建一个新对象新对象的属性和原来对象完全相同对于非基本类型属性仍指向原有属性所指向的对象的内存地址。 这里抽象原型类不用自己创建都是Object里面有clone()方法 具体原型类实现Cloneable里面重写clone方法直接super调用父类的clone方法即可
import java.util.List;/*** Author dengyifan* create 2023/11/10 10:19* description*/
public class UserPrototype implements Cloneable{private String name;private Integer age;private ListString messages;public String getName() {return name;}public void setName(String name) {this.name name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public ListString getMessages() {return messages;}public void setMessages(ListString messages) {this.messages messages;}Overrideprotected UserPrototype clone() throws CloneNotSupportedException {return (UserPrototype) super.clone();}
}客户类
import java.util.ArrayList;
import java.util.List;/*** Author dengyifan* create 2023/11/10 10:22* description*/
public class PrototypeClient {public static void main(String[] args) throws CloneNotSupportedException {UserPrototype userPrototype1 new UserPrototype();userPrototype1.setName(tom);userPrototype1.setAge(18);ListString messages1 new ArrayList();messages1.add(test);userPrototype1.setMessages(messages1);UserPrototype userPrototype2 userPrototype1.clone();System.err.println(String.format(两个对象是否一致%s, userPrototype1 userPrototype2));System.err.println(String.format(两个对象的name属性是否一致%s, userPrototype1.getName() userPrototype2.getName()));System.err.println(String.format(两个对象的messages属性是否一致%s, userPrototype1.getMessages() userPrototype2.getMessages()));System.err.println(userPrototype1.getMessages());System.err.println(userPrototype2.getMessages());messages1.clear();messages1.add(test1);System.err.println(userPrototype1.getMessages());System.err.println(userPrototype2.getMessages());}
} 运行结果 通过结果可以看到通过克隆的对象与原型对象的引用不一致说明再内存中存在两个不同的对象一个是原型对象一个是克隆生成的对象。而这里属性都显示是一致的结果都是true说明两个对象的成员对象是同一个也就是对象本身是复制了但是其成员的对象再内存中没有复制。并且我们修改原型的messages属性克隆对象的messages也跟着改变说明属性确实是同一个对象的引用。
三、深拷贝 深拷贝中除了原型对象与克隆生成的对象被复制以外里面的属性也需要被复制即地址都不一样。这里深拷贝实现了Serializable即进行了序列化。
import java.io.*;
import java.util.List;/*** Author dengyifan* create 2023/11/10 15:43* description*/
public class UserPrototypeDeep implements Serializable {private String name;private Integer age;private ListString messages;public String getName() {return name;}public void setName(String name) {this.name name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public ListString getMessages() {return messages;}public void setMessages(ListString messages) {this.messages messages;}protected UserPrototypeDeep deepClone() throws Exception{ByteArrayOutputStream baonew ByteArrayOutputStream();ObjectOutputStream oosnew ObjectOutputStream(bao);oos.writeObject(this);//将对象从流中取出ByteArrayInputStream bisnew ByteArrayInputStream(bao.toByteArray());ObjectInputStream oisnew ObjectInputStream(bis);return (UserPrototypeDeep) ois.readObject();}
}
import java.util.ArrayList;
import java.util.List;/*** Author dengyifan* create 2023/11/10 15:46* description*/
public class PrototypeDeepClient {public static void main(String[] args) throws Exception {UserPrototypeDeep userPrototypeDeep1 new UserPrototypeDeep();userPrototypeDeep1.setAge(19);userPrototypeDeep1.setName(tom);ListString messages1 new ArrayList();messages1.add(test);userPrototypeDeep1.setMessages(messages1);UserPrototypeDeep userPrototypeDeep2 userPrototypeDeep1.deepClone();System.err.println(String.format(两个对象是否一致%s, userPrototypeDeep1 userPrototypeDeep2));System.err.println(String.format(两个对象的name属性是否一致%s, userPrototypeDeep1.getName() userPrototypeDeep2.getName()));System.err.println(String.format(两个对象的messages属性是否一致%s, userPrototypeDeep1.getMessages() userPrototypeDeep2.getMessages()));System.err.println(userPrototypeDeep1.getMessages());System.err.println(userPrototypeDeep2.getMessages());messages1.clear();messages1.add(test1);System.err.println(userPrototypeDeep1.getMessages());System.err.println(userPrototypeDeep2.getMessages());}
}运行结果 可以看出除了对象本身不一致以外里面的属性也不一致当修改原型对象里面引用对象的属性时克隆对象的属性不会发生变化即也证明属性不是同一个对象。 对于原型模式的应用场景主要有以下几点 1. 当对象的创建过程非常复杂或耗费大量资源时可以使用原型模式来复制一个现有对象从而避免重复创建对象。 2. 当需要创建多个相似的对象时可以使用原型模式来减少重复代码提高代码的重用性。 3. 当创建对象的过程需要大量的数据准备或配置时可以使用原型模式来复制一个已经配置好的对象从而避免重复的数据准备或配置过程。 4. 当需要动态生成对象的子类时可以使用原型模式来复制一个已有的对象并对其进行修改从而避免重新编写子类的代码。 5. 当需要保护对象的状态时可以使用原型模式来创建对象的副本并将副本交给其他对象使用从而避免原始对象的状态被修改。