设计模式之原型模式
来源:互联网 发布:手机淘宝查看退货率 编辑:程序博客网 时间:2024/05/20 17:25
一、定义
通过原型实例指定创建对象的种类,并通过拷贝这些原型实例构建新的对象。(我觉简单的说,就是一种更快更省资源的创建新的
对象的方法)
二、实例
定义什么的总是难懂,还是上实例吧!
定义一个Ball类型,实现Cloneable接口,使得这个类的对象能够被克隆。
public class Ball implements Cloneable{ public int id = -1; public String teststring ; public int[] num ; public ArrayList<String> list = new ArrayList<String>(); public T t ; @Override protected Object clone() throws CloneNotSupportedException { Ball ball = null ; try { ball = (Ball) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return ball ; }}//T类型class T{ public int t = 0;}
测试代码如下:
Ball ball = new Ball(); ball.setId(0); for(int i=1;i<100;i++){ try { Ball cloneball = (Ball)ball.clone(); System.out.println(cloneball.id); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
运行结果为:0
三、理论知识
3.1使用场景
原型模式很简单,基本上就是实现以下clone方法就好了,而且代码基本都是一样的。
3.2和new的区别
clone出来的对象是不经过构造函数构造的。也就是说Ball cloneball = (Ball)ball.clone()这句话没有用到构造函数就直接 定义了一个新的对象出来。
3.3clone出的对象的来源
clone方法是从内存中直接拷贝一个对象的数据到新开辟的内存空间中。
四、两种拷贝方式浅拷贝和深拷贝
4.1 区别
浅拷贝:在执行clone来创建对象的时候,新出来的对象其实是和原对象共享数组和引用的(除了基本数据类型)。
深拷贝:用clone生成对象后,这个对象是完全独立的,它的变量不会被其他clone出来的或者原型对象修改。
4.2实例4.2.1浅拷贝:看下面的测试函数:
System.out.println("ball信息:"); System.out.println("id:"+ball.id+" num:"+ball.num[0]+" "+ball.num[1]+" T:"+ball.t.t+" list[0]:"+ball.list.get(0)+" string:"+ball.teststring); System.out.println("cloneball信息:"); System.out.println("id:"+cloneball.id+" num:"+cloneball.num[0]+" "+cloneball.num[1]+" T:"+cloneball.t.t+" list[0]:"+ cloneball.list.get(0)+" string:"+cloneball.teststring); System.out.println("两者的teststring地址是否相同:"+(ball.teststring == cloneball.teststring)); System.out.println("修改ball信息:"); ball.id = 2; ball.num[0] = 2; ball.num[1] = 3; ball.t.t = 2; ball.list.remove(0); ball.teststring = "i am ball after change!" ; ball.list.add("i am the first string ball.list after change !"); System.out.println("id:"+ball.id+" num:"+ball.num[0]+" "+ball.num[1]+" T:"+ball.t.t+" list[0]:"+ball.list.get(0)+" string:"+ball.teststring); System.out.println("此时cloneball的信息变化为:"); System.out.println("id:"+cloneball.id+" num:"+cloneball.num[0]+" "+cloneball.num[1]+" T:"+cloneball.t.t+" list[0]:"+ cloneball.list.get(0)+" string:"+cloneball.teststring);
它的运行结果如下:
ball信息:id:1 num:1 2 T:1 list[0]:i am the first string ball.list string:i am ball!cloneball信息:id:1 num:1 2 T:1 list[0]:i am the first string ball.list string:i am ball!两者的teststring地址是否相同:true修改ball信息:id:2 num:2 3 T:2 list[0]:i am the first string ball.list after change ! string:i am ball after change!此时cloneball的信息变化为:id:1 num:2 3 T:2 list[0]:i am the first string ball.list after change ! string:i am ball!
仔细对比一下可以发现,修改ball中的基本数据类型变量id(int型)、teststring(string),不会导致cloneball中的
相应的变量改变,但是修改list(ArrayList)和num(int[])时就会导致cloneball中变量也改变。这就是浅拷贝。
(注意string类型的变量,在cloneball刚生成的时候里面的teststring和ball中的teststring是同一个东西,他们的地址是一样的,
但是一方的改变对另一方无影响,所以在这里把string也当做普通的数据类型处理)。
我觉得在堆里面的变量在克隆的时候都是共享的,而栈里面的东西都是会重新建立一个。
4.2.1 深拷贝 就是在拷贝对象的时候将原型类中所有的引用对象再拷贝一遍。clone方法改成:
protected Object clone() throws CloneNotSupportedException { Ball ball = null ; try { ball = (Ball) super.clone(); ball.list = (ArrayList<String>) this.list.clone(); ball.t = new T(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return ball ; }
- 设计模式之原型
- 设计模式之原型
- 设计模式 之 原型
- 设计模式之原型
- 设计模式之原型
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之-原型模式
- 设计模式之 原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之--原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 【Codeforces Round 334 (Div 2)C】【脑洞】Alternative Thinking 最多反转一个区间使得最长跳跃子串的长度尽可能长
- matlab调用opencv2.4
- Java文件IO学习笔记(二)---文件锁定
- lightoj1107 How Cow
- 机房人物传记(已完结)+日常
- 设计模式之原型模式
- java 模拟手机通讯录本地保存与读取
- 地图定位弹窗提示 注意事项
- 论文技巧
- android studio使用错误排查记录
- Liunx学习笔记(5)之解压缩
- 在cmd窗口运行需要加载含驱动的java程序
- linux下shell命令之hwclock
- 算法学习--查找(一)