做房地产网站建设,可以免费秒玩游戏的网站,济南品牌网站建设价格,嘉兴网站建设品牌升级一、概念
原型模式#xff08;Prototype Pattern#xff09;#xff1a;利用对已有对象#xff08;原型#xff09;进行复制#xff08;或者叫拷贝#xff09;的方式来创建新对象#xff0c;以达到节省创建时间的目的。
使用场景#xff1a;如果对象的创建成本比较大…一、概念
原型模式Prototype Pattern利用对已有对象原型进行复制或者叫拷贝的方式来创建新对象以达到节省创建时间的目的。
使用场景如果对象的创建成本比较大而且同一个类的不同对象之间差别不大大部分字段都相同这种情况下可以考虑原型模式。
二、实现
原型模式有两种实现方法深拷贝和浅拷贝。
浅拷贝只会复制对象中基本数据类型数据和引用对象的内存地址不会递归地复制引用对象以及引用对象的引用对象。深拷贝得到的是一份完完全全独立新的对象。 当一个类中只有基本数据类型时浅拷贝与深拷贝是同样的。 当一个类中含有引用数据类型是浅拷贝只是拷贝一份引用修改浅拷贝的值原来的也会跟着变化。 举个例子 肯德基套餐A对象包含一个可乐对象一个汉堡包对象。 浅拷贝就是复制了一份肯德基套餐A但是里面包含的可乐和汉堡还是原来的那一份如果咬一口汉堡那么原来的那个就缺一块。
深拷贝也是复制了一份肯德基套餐A但是里面的可乐和汉堡是新的对象如果咬一口汉堡那么原来的那个还是完好无损的。
浅拷贝实现
代码注意如果想实现克隆功能要克隆的类要实现Cloneable 接口。 1、肯德基套餐A
public class KFCSetMenuA implements Cloneable {private float price;private Cola cola;private Hamburger hamburger;....省略set和get方法Overrideprotected Object clone() {KFCSetMenuA kfcSetMenuA null;try {kfcSetMenuA (KFCSetMenuA) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();System.out.println(e.toString());}return kfcSetMenuA;}
}2、其他对象
public class Cola implements Cloneable {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}
}public class Hamburger implements Cloneable {}3、实现浅拷贝 public static void main(String[] args) throws CloneNotSupportedException {KFCSetMenuA kfcSetMenuA new KFCSetMenuA();kfcSetMenuA.setPrice(15.5f);Cola cola new Cola();cola.setName(可口可乐);kfcSetMenuA.setCola(cola);KFCSetMenuA cloneKFCSetMenuA (KFCSetMenuA) kfcSetMenuA.clone();cloneKFCSetMenuA.setPrice(16.5f);cloneKFCSetMenuA.getCola().setName(百事可乐);System.out.println(原对象可乐 kfcSetMenuA.getCola().getName());System.out.println(克隆对象可乐 cloneKFCSetMenuA.getCola().getName());System.out.println(原对象价格 kfcSetMenuA.getPrice());System.out.println(克隆对象价格 cloneKFCSetMenuA.getPrice());}4、浅拷贝结果
总结从结果看到说明克隆后的对象和原始的指向的是同一个cola对象改名字后都变了但是基本类型数据是没有改变的。
深拷贝实现方式1
1、重新定义Cola中的clone方法。
public class Cola implements Cloneable {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}NonNullOverrideprotected Object clone() throws CloneNotSupportedException {Cola cola null;try {cola (Cola) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();System.out.println(e.toString());}return cola;}
}2、实现的时候同时把Cola对象clone一遍。 public static void main(String[] args) throws CloneNotSupportedException {KFCSetMenuA kfcSetMenuA new KFCSetMenuA();kfcSetMenuA.setPrice(15.5f);Cola cola new Cola();cola.setName(可口可乐);kfcSetMenuA.setCola(cola);KFCSetMenuA cloneKFCSetMenuA (KFCSetMenuA) kfcSetMenuA.clone();//克隆Cola对象Cola cloneCola (Cola) cola.clone();cloneKFCSetMenuA.setCola(cloneCola);cloneKFCSetMenuA.setPrice(16.5f);cloneKFCSetMenuA.getCola().setName(百事可乐);System.out.println(原对象可乐 kfcSetMenuA.getCola().getName());System.out.println(克隆对象可乐 cloneKFCSetMenuA.getCola().getName());System.out.println(原对象价格 kfcSetMenuA.getPrice());System.out.println(克隆对象价格 cloneKFCSetMenuA.getPrice());}3、深拷贝实现方式1结果 总结这个方式就是把克隆对象中引用的对象也进行浅克隆但是如果出现嵌套多层的时候每个引用对象都得实现克隆太麻烦。
深拷贝实现方式2-序列化
1、在KFCSetMenuA 类中加入如下方法并且KFCSetMenuA 要实现Serializable接口。
public KFCSetMenuA deepClone() {//声明流对象ByteArrayOutputStream bos null;ByteArrayInputStream bis null;ObjectOutputStream oos null;ObjectInputStream ois null;try {//创建序列化流bos new ByteArrayOutputStream();oos new ObjectOutputStream(bos);//将当前对象以对象流的方式输出oos.writeObject(this);//创建反序化流bis new ByteArrayInputStream(bos.toByteArray());ois new ObjectInputStream(bis);//将流对象反序列化实现类的深拷贝。return (KFCSetMenuA) ois.readObject();} catch (Exception e) {e.printStackTrace();return null;} finally {try {//关闭资源bos.close();bis.close();oos.close();ois.close();} catch (IOException e) {e.printStackTrace();}}}2、实现方式
public static void main(String[] args) throws CloneNotSupportedException {KFCSetMenuA kfcSetMenuA new KFCSetMenuA();kfcSetMenuA.setPrice(15.5f);Cola cola new Cola();cola.setName(可口可乐);kfcSetMenuA.setCola(cola);// 序列化深拷贝KFCSetMenuA cloneKFCSetMenuA kfcSetMenuA.deepClone();cloneKFCSetMenuA.setPrice(16.5f);cloneKFCSetMenuA.getCola().setName(百事可乐);System.out.println(原对象可乐 kfcSetMenuA.getCola().getName());System.out.println(克隆对象可乐 cloneKFCSetMenuA.getCola().getName());System.out.println(原对象价格 kfcSetMenuA.getPrice());System.out.println(克隆对象价格 cloneKFCSetMenuA.getPrice());}3、深拷贝实现方式2结果
参考文章 极客时间《设计模式》王争