博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之原型模式
阅读量:3915 次
发布时间:2019-05-23

本文共 6718 字,大约阅读时间需要 22 分钟。

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

调用者不需要知道任何创建细节,不调用构造函数

属于创建型模式

适用场景

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

优点

性能优良,Java自带的原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多
可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建过程

缺点

必须配备克隆(或者可拷贝)方法
当对已有类进行改造的时候,需要修改代码,违反了开闭原则
深拷贝,浅拷贝需要运用得当

原型模式和单例模式是对立的

实现Cloneable的都是浅克隆
深克隆:1.序列化;2.转Json;

例子

1.自定义克隆接口
public interface IPrototype
{
T clone();}
public class ConcretePrototype implements IPrototype{
private int age; private String name; 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; } @Override public ConcretePrototype clone() {
ConcretePrototype concretePrototype = new ConcretePrototype(); concretePrototype.setAge(this.age); concretePrototype.setName(this.name); return concretePrototype; } @Override public String toString() {
return "ConcretePrototype{" + "age=" + age + ", name='" + name + '\'' + '}'; }}
客户端调用
public class Client {
public static void main(String[] args) {
ConcretePrototype prototype = new ConcretePrototype(); prototype.setAge(18); prototype.setName("Jack"); System.out.println(prototype); //拷贝原型对象 ConcretePrototype cloneType = prototype.clone(); System.out.println(cloneType); }}
2.浅拷贝
public class ConcretePrototype implements Cloneable {
private int age; private String name; private List
hobbies; 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 List
getHobbies() {
return hobbies; } public void setHobbies(List
hobbies) {
this.hobbies = hobbies; } @Override public ConcretePrototype clone() {
try {
return (ConcretePrototype)super.clone(); } catch (CloneNotSupportedException e) {
e.printStackTrace(); } return null; } @Override public String toString() {
return "ConcretePrototype{" + "age=" + age + ", name='" + name + '\'' + ", hobbies=" + hobbies + '}'; }}
客户端调用
public class Client {
public static void main(String[] args) {
ConcretePrototype prototype = new ConcretePrototype(); prototype.setAge(18); prototype.setName("Jack"); List
hobbies = new ArrayList<>(); hobbies.add("打球"); hobbies.add("游戏"); prototype.setHobbies(hobbies); System.out.println(prototype); //拷贝原型对象 ConcretePrototype cloneType = prototype.clone(); cloneType.getHobbies().add("学习"); System.out.println("拷贝前对象: " + prototype); System.out.println("拷贝后对象: " + cloneType); System.out.println(prototype == cloneType); System.out.println("原型对象的爱好: " + prototype.getHobbies()); System.out.println("拷贝对象的爱好: " + cloneType.getHobbies()); System.out.println(prototype.getHobbies() == cloneType.getHobbies()); }}
3.深拷贝
public class ConcretePrototype implements Cloneable ,Serializable{
private int age; private String name; private List
hobbies; 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 List
getHobbies() {
return hobbies; } public void setHobbies(List
hobbies) {
this.hobbies = hobbies; } private static ConcretePrototype instance = new ConcretePrototype(); private ConcretePrototype(){
} public static ConcretePrototype getInstance(){
return instance; } @Override public ConcretePrototype clone() {
try {
return (ConcretePrototype)super.clone(); } catch (CloneNotSupportedException e) {
e.printStackTrace(); } return null; } public ConcretePrototype deepClone(){
ConcretePrototype concretePrototype = null; try {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); concretePrototype = (ConcretePrototype)ois.readObject(); ois.close(); bis.close(); oos.close(); bos.close(); } catch (Exception e) {
e.printStackTrace(); } return concretePrototype; } public ConcretePrototype deepCloneObject(){
ConcretePrototype concretePrototype = null; try {
ConcretePrototype clone = (ConcretePrototype)super.clone(); clone.hobbies = (List)((ArrayList)clone.hobbies).clone(); concretePrototype = clone; } catch (Exception e) {
e.printStackTrace(); } return concretePrototype; } @Override public String toString() {
return "ConcretePrototype{" + "age=" + age + ", name='" + name + '\'' + ", hobbies=" + hobbies + '}'; }}
客户端调用
public class Client {
public static void main(String[] args) {
ConcretePrototype prototype = ConcretePrototype.getInstance(); prototype.setAge(18); prototype.setName("Jack"); List
hobbies = new ArrayList<>(); hobbies.add("打球"); hobbies.add("游戏"); prototype.setHobbies(hobbies); System.out.println(prototype); //拷贝原型对象 ConcretePrototype cloneType = prototype.deepCloneObject(); cloneType.getHobbies().add("学习"); System.out.println("拷贝前对象: " + prototype); System.out.println("拷贝后对象: " + cloneType); System.out.println(prototype == cloneType); System.out.println("原型对象的爱好: " + prototype.getHobbies()); System.out.println("拷贝对象的爱好: " + cloneType.getHobbies()); System.out.println(prototype.getHobbies() == cloneType.getHobbies()); }}

转载地址:http://bkjrn.baihongyu.com/

你可能感兴趣的文章
成为优秀Java程序员的10大技巧
查看>>
一位10年Java工作经验的架构师聊Java和工作经验
查看>>
Java架构师学习路线
查看>>
号称精通Java的你,是否真的名副其实
查看>>
你可以把编程当做一项托付终身的职业
查看>>
细思极恐——你真的会写Java吗?
查看>>
Java并发面试,幸亏有点道行,不然又被忽悠了
查看>>
Java基础面试题收集整理
查看>>
SpringBoot基础篇Bean之条件注入@Condition使用姿势
查看>>
让你秒懂线程和线程安全,只需5步!
查看>>
Spring Boot学习之Logback和Log4j2集成与日志发展史
查看>>
Java注解(annotation)机制
查看>>
volatile关键字全面解析
查看>>
Java如何实现哈夫曼编码
查看>>
从源代码的角度理解Java设计模式的装饰模式
查看>>
系统架构中为什么要引入消息中间件?
查看>>
Java内存模型详解
查看>>
Java NIO之Selector
查看>>
SLF4J源码解析(一)
查看>>
Spring AOP用法详解
查看>>