Java设计模式——原型模式
2016-12-22 15:48
267 查看
原型模式既简单、又好用,需要实现Cloneable接口,说的纯粹点,原型模式的作用就是克隆。下面举一个例子,我们来克隆绵羊:
绵羊类,实现Cloneable接口:
接下来就可以测试了:
打印出的log:
我们发现,修改了克隆体的属性,并没有修改原样本的属性,这就是原型模式的作用;
接下来我们进一步做实验,给每个绵羊添加几个爱好(hobby):
接下来我们测试:
我们看输出的log:
我们发现,修改克隆体后样本也改变了,这就涉及到了深拷贝与浅拷贝的知识:浅拷贝也叫影子拷贝,他其实并不是真的拷贝了一份,而是拷贝后的字段引用了样本字段的地址,指向了样本字段,与样本字段共用一个。下面我们修改一下程序的clone方法:
接下来测试,测试代码不做修改,看log:
没错,这就是我们想要的效果。
绵羊类,实现Cloneable接口:
public class Sheep implements Cloneable { private String name = "小白"; private String color = "白色"; @Override public Sheep clone() throws CloneNotSupportedException { Sheep sheep = (Sheep) super.clone(); sheep.name = this.name; sheep.color = this.color; return sheep; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", color='" + color + '\'' + '}'; } }
接下来就可以测试了:
try { //新建一个绵羊 Sheep sheep = new Sheep(); //克隆一个绵羊 Sheep cloneSheep = sheep.clone(); //修改克隆羊的属性 cloneSheep.setName("小红"); cloneSheep.setColor("红色"); Log.d("test", sheep.toString()); Log.d("test", cloneSheep.toString()); Log.d("test", sheep.toString()); } catch (CloneNotSupportedException e) { e.printStackTrace(); }
打印出的log:
test: Sheep{name='小白', color='白色'} test: Sheep{name='小红', color='红色'} test: Sheep{name='小白', color='白色'}
我们发现,修改了克隆体的属性,并没有修改原样本的属性,这就是原型模式的作用;
接下来我们进一步做实验,给每个绵羊添加几个爱好(hobby):
public class Sheep implements Cloneable { private String name = "小白"; private String color = "白色"; private ArrayList<String> hobby = new ArrayList<>(); @Override public Sheep clone() throws CloneNotSupportedException { 4000 Sheep sheep = (Sheep) super.clone(); sheep.name = this.name; sheep.color = this.color; sheep.hobby = this.hobby; return sheep; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public ArrayList<String> getHobby() { return hobby; } public void setHobby(ArrayList<String> hobby) { this.hobby = hobby; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", color='" + color + '\'' + ", hobby=" + hobby + '}'; } }
接下来我们测试:
try { //新建一个绵羊 Sheep sheep = new Sheep(); ArrayList<String> hobby = sheep.getHobby(); hobby.add("草"); hobby.add("空气"); Log.d("test", "sheep = " + sheep.toString()); //克隆一个绵羊 Sheep cloneSheep = sheep.clone(); //修改克隆羊的属性 cloneSheep.setName("小红"); cloneSheep.setColor("红色"); ArrayList<String> hobby2 = cloneSheep.getHobby(); hobby2.add("胡萝卜"); hobby2.add("大海"); Log.d("test", "cloneSheep = " + cloneSheep.toString()); Log.d("test", "sheep = " + sheep.toString()); } catch (CloneNotSupportedException e) { e.printStackTrace(); }
我们看输出的log:
sheep = Sheep{name='小白', color='白色', hobby=[草, 空气]} cloneSheep = Sheep{name='小红', color='红色', hobby=[草, 空气, 胡萝卜, 大海]} sheep = Sheep{name='小白', color='白色', hobby=[草, 空气, 胡萝卜, 大海]}
我们发现,修改克隆体后样本也改变了,这就涉及到了深拷贝与浅拷贝的知识:浅拷贝也叫影子拷贝,他其实并不是真的拷贝了一份,而是拷贝后的字段引用了样本字段的地址,指向了样本字段,与样本字段共用一个。下面我们修改一下程序的clone方法:
@Override public Sheep clone() throws CloneNotSupportedException { Sheep sheep = (Sheep) super.clone(); sheep.name = this.name; sheep.color = this.color; sheep.hobby = (ArrayList<String>) this.hobby.clone(); return sheep; }
接下来测试,测试代码不做修改,看log:
sheep = Sheep{name='小白', color='白色', hobby=[草, 空气]} cloneSheep = Sheep{name='小红', color='红色', hobby=[草, 空气, 胡萝卜, 大海]} sheep = Sheep{name='小白', color='白色', hobby=[草, 空气]}
没错,这就是我们想要的效果。
相关文章推荐
- Selenium WebDriver 中鼠标和键盘事件分析及扩展
- JavaMail入门教程之接收邮件(4)
- 第一章 Java的I/O演进之路
- JAVA - 优雅的记录日志(log4j实战篇)
- java
- 为java程序添加远程jmi监控
- 【leetcode】Ugly Number II Java
- 第十三章:字符串(下)
- 基于POI的两个JAVA操作Office工具类
- JDK自带工具keytool生成ssl证书
- jdk安装
- Java 中被static 修饰的属性,方法和代码块在什么时候加载
- SpringBoot整合MyBatis
- Java服务器调优
- java单列设计模式
- 加密解密算法java实现(4)—MD5
- java 常用正则表达式汇总
- Java泛型
- java项目和C#项目实现通信
- Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解