Android设计模式之(3)----原型模式
来源:互联网 发布:vb.net 高级编程 pdf 编辑:程序博客网 时间:2024/06/18 10:17
原型模式
用原型实例指定创建对象的,拷贝这些对象生成新的对象进行使用。
也可以直接进行new一个对象,但是当对象的构造复杂时,new的效率会很低,使用clone更好
new适用于简单的构造
clone适用于复杂的构造
应用场景
- 资源消耗大的对象
- 节省资源,比如在for循环内创建相同的对象
- 一个对象要让其他人使用,并且使用过程中要改变这个对象的某些属性,可考虑将原有对象拷贝,并且修改需要改变的属性,在进行使用
- 对象结构复杂的情况使用拷贝
浅拷贝代码实现
原型对象实现Cloneable接口(默认是浅拷贝)
class Prototype implements Cloneable { public Prototype clone() { Prototype prototype = null; try { prototype = (Prototype) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return prototype; }}
原型对象具体的内容实现
class ConcretePrototype extends Prototype { public String name; public ArrayList<String> list = new ArrayList<>(); public ConcretePrototype() { System.out.println("执行了ConcretePrototype构造函数"); } @Override public String toString() { return "ConcretePrototype{" + "name='" + name + '\'' + ", list=" + list + '}'; } public void show() { System.out.println("原型模式实现类"); }}
使用方式
ConcretePrototype cp = new ConcretePrototype(); cp.name = "原始数据"; for (int i = 0; i < 10; i++) { cp.list.add(i, String.valueOf(i));//填充数据 } ConcretePrototype cloneConcretePrototype = (ConcretePrototype) cp.clone();//实现拷贝 cloneConcretePrototype.name = "拷贝数据"; System.out.println(cp.toString()); System.out.println(cloneConcretePrototype.toString());
显示结果:
执行了ConcretePrototype构造函数ConcretePrototype{name='原始数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}ConcretePrototype{name='拷贝数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
原型对象不实现Cloneable接口(默认是浅拷贝)
其实就是把cloneable接口的内容手动实现一次
class ConcretePrototype2 { public String name; public ArrayList<String> list = new ArrayList<>(); public ConcretePrototype2() { System.out.println("执行了ConcretePrototype2构造函数"); } public ConcretePrototype2 clone() { //手动new对象进行赋值 concretePrototype2 concretePrototype2 = new ConcretePrototype2(); concretePrototype2.name = this.name; concretePrototype2.list = this.list; return concretePrototype2; } @Override public String toString() { return "ConcretePrototype2{" + "name='" + name + '\'' + ", list=" + list + '}'; } public void show() { System.out.println("原型模式实现类"); }}
调用方式
ConcretePrototype2 cp = new ConcretePrototype2(); cp.name = "原始数据"; for (int i = 0; i < 10; i++) { cp.list.add(i, String.valueOf(i));//填充数据 } ConcretePrototype2 cloneConcretePrototype = (ConcretePrototype2) cp.clone();//实现拷贝 cloneConcretePrototype.name = "拷贝数据"; System.out.println(cp.toString()); System.out.println(cloneConcretePrototype.toString());
显示结果
执行了ConcretePrototype2构造函数执行了ConcretePrototype2构造函数ConcretePrototype2{name='原始数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}ConcretePrototype2{name='拷贝数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
构造函数执行了两次,说明了cloneable接口的复制是不会执行2次构造的,直接new对象则会调用2次构造。
测试
修改复制后的数据
ConcretePrototype2 cp = new ConcretePrototype2(); cp.name = "原始数据"; for (int i = 0; i < 10; i++) { cp.list.add(i, String.valueOf(i));//填充数据 } ConcretePrototype2 cloneConcretePrototype = (ConcretePrototype2) cp.clone();//实现拷贝 cloneConcretePrototype.name = "拷贝数据"; cloneConcretePrototype.list.add("追加测试数据"); System.out.println(cp.toString()); System.out.println(cloneConcretePrototype.toString());
显示结果
执行了ConcretePrototype2构造函数执行了ConcretePrototype2构造函数ConcretePrototype2{name='原始数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 追加测试数据]}ConcretePrototype2{name='拷贝数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 追加测试数据]}
【追加测试数据无论是原型还是拷贝后的对象都有这个数据】
问题原因:深拷贝-浅拷贝
Cloneable接口默认实现的是浅拷贝,对于基本类型会进行拷贝,但是对于引用类型(集合,数据,对象)等clone仅仅代表指向了同一个内存地址,所以修改一个两个都会变化。
解决方案:在引用类型的具体数据类型在进行一次clone,将浅拷贝处理为深拷贝
深拷贝代码实现
代码如下
public ConcretePrototype2 clone() { //手动new对象进行赋值// ConcretePrototype2 concretePrototype2 = new ConcretePrototype2();// concretePrototype2.name = this.name;// concretePrototype2.list = this.list;// return concretePrototype2; //将具体的集合修改为深拷贝 ConcretePrototype2 concretePrototype2 = new ConcretePrototype2(); concretePrototype2.name = this.name; concretePrototype2.list = (ArrayList<String>) this.list.clone(); return concretePrototype2; }
显示结果
执行了ConcretePrototype2构造函数执行了ConcretePrototype2构造函数ConcretePrototype2{name='原始数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}ConcretePrototype2{name='拷贝数据', list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 追加测试数据]}
应证我们的想法,对于集合,数组,对象等,如果要新增数据,需要对其重写更改具体的数据类型。
总结
原型模式可以避免构造复杂的对象时的资源消耗问题,提升创建对象的效率。
可以保护原始对象的数据安全性
clone是二进制流,对于复杂的构造对象,性能提升明显,但是对于简单的构造没必要使用clone
github代码地址
阅读全文
0 0
- Android设计模式之(3)----原型模式
- Android设计模式之原型模式
- Android设计模式之原型模式
- Android 设计模式之原型模式
- android设计模式--之原型模式(prototype)
- 设计模式之原型模式(Prototype)
- 设计模式之原型模式(Prototype)
- 设计模式之原型模式(clone)
- 设计模式之原型模式(Prototype)
- 设计模式之----------原型模式(prototype)
- 设计模式之原型模式(Prototype)
- 设计模式之原型模式(ProtoType)
- (4)设计模式之原型模式
- 设计模式之:原型模式(Prototype)
- 设计模式之原型模式(Prototype)
- 设计模式之原型模式(Prototype)
- 设计模式之原型模式(Prototype)
- 设计模式之原型模式(Prototype)
- c++基础知识总结
- MySQL Oracle 别名
- 解决android7.0+ 自定义Toast时长,但是toast不显示问题
- Codeforces 106 D. Treasure Island(前缀和预处理)
- spring mvc InitBinder 遇到的坑接收不了参数
- Android设计模式之(3)----原型模式
- Krpano插件--event事件注释
- Bootstrap Table使用整理(一)
- TensorFlow 训练 MNIST 数据
- 配置表的处理方式
- ESXi对接iscsi存储操作指南
- Insertion Sort List
- E
- CI框架cli命令行