网站关键字怎么优化,广安做网站,网站树状栏目有点,温州建设集团官网文章目录 设计模式概述1、原型模式2、原型模式的使用场景3、优点4、缺点5、主要角色6、代码示例7、总结题外话关于使用序列化实现深拷贝 设计模式概述
创建型模式#xff1a;工厂方法、抽象方法、建造者、原型、单例。 结构型模式有#xff1a;适配器、桥接、组合、装饰器、… 文章目录 设计模式概述1、原型模式2、原型模式的使用场景3、优点4、缺点5、主要角色6、代码示例7、总结题外话关于使用序列化实现深拷贝 设计模式概述
创建型模式工厂方法、抽象方法、建造者、原型、单例。 结构型模式有适配器、桥接、组合、装饰器、外观、享元、代理。 行为型模式有责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者。 常用设计模式 单例模式、工厂模式、代理模式、策略模式模板模式、门面模式、责任链模式、装饰器模式、组合模式、builder模式。
1、原型模式
原型模式Prototype Pattern是用于创建重复的对象同时又能保证性能。这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式之一。这种模式是实现了一个原型接口该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时则采用这种模式。
2、原型模式的使用场景
在需要一个类的大量对象的时候使用原型模式是最佳选择因为原型模式是在内存中对这个对象进行拷贝要比直接new这个对象性能要好很多在这种情况下需要的对象越多原型模式体现出的优点越明显。如果一个对象的初始化需要很多其他对象的数据准备或其他资源的繁琐计算那么可以使用原型模式。当需要一个对象的大量公共信息少量字段进行个性化设置的时候也可以使用原型模式拷贝出现有对象的副本进行加工处理。
3、优点
原型模式允许在运行时动态改变具体的实现类型。原型模式可以在运行期间由客户来注册符合原型接口的实现类型也可以动态地改变具体的实现类型看起来接口没有任何变化但其实运行的已经是另外一个类实例了。因为克隆一个原型就类似于实例化一个类。
4、缺点
原型模式最主要的缺点是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑这对于全新的类来说不是很难而对于已经有的类不一定很容易特别是当一个类引用不支持序列化的间接对象或者引用含有循环结构的时候。
5、主要角色
1客户(Client)角色客户类提出创建对象的请求。 2抽象原型(Prototype)角色这是一个抽象角色通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。 3具体原型Concrete Prototype角色被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
6、代码示例
1UML图 2源代码 1抽象原型角色
public interface Prototype{/*** 克隆自身的方法* return 一个从自身克隆出来的对象*/public Object clone();
}2具体原型角色 public class ConcretePrototype1 implements Prototype {public Prototype clone(){//最简单的克隆新建一个自身对象由于没有属性就不再复制值了Prototype prototype new ConcretePrototype1();return prototype;}
}public class ConcretePrototype2 implements Prototype {public Prototype clone(){//最简单的克隆新建一个自身对象由于没有属性就不再复制值了Prototype prototype new ConcretePrototype2();return prototype;}
}3客户端角色
public class Client {public static void main(String[]args){try{Prototype p1 new ConcretePrototype1();//获取原型来创建对象Prototype p2 p1.clone();//有人动态的切换了实现Prototype p3 new ConcretePrototype2();Prototype p4 p3.clone();}catch(Exception e){e.printStackTrace();}}
}
}7、总结
这种情况就是浅拷贝java只拷贝你指定的对象至于你指定的对象里面的别的对象它不拷贝还是把引用给你共享变量这是一种非常不安全的方式需要特别注意。内部的数组和引用对象不会拷贝其他的原始基本类型和String类型会被拷贝。如果需要可以使用深拷贝结合具体对象的情况进行处理可以自己实现深拷贝逻辑或者利用序列化和反序列化实现深拷贝前提是所有需要复制的对象都需要实现java.io.Serializable接口。
题外话关于使用序列化实现深拷贝
利用序列化实现深度克隆
把对象写到流里的过程是序列化(Serialization)过程而把对象从流中读出来的过程则叫反序列化(Deserialization)过程。应当指出的是写到流里的是对象的一个拷贝而原对象仍然存在于JVM里面。在Java语言里深度克隆一个对象常常可以先使对象实现Serializable接口然后把对象实际上只是对象的拷贝写到一个流里序列化再从流里读回来反序列化便可以重建对象。
public Object deepClone() throws IOException, ClassNotFoundException{//将对象写到流里ByteArrayOutputStream bos new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(bos);oos.writeObject(this);//从流里读回来ByteArrayInputStream bis new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois new ObjectInputStream(bis);return ois.readObject();}这样做的前提就是对象以及对象内部所有引用到的对象都是可序列化的否则就需要仔细考察那些不可序列化的对象可否设成transient从而将之排除在复制过程之外。 浅度克隆显然比深度克隆更容易实现因为Java语言的所有类都会继承一个clone()方法而这个clone()方法所做的正式浅度克隆。