JAVA设计模式之原型模式(prototype)
原型模式:
- 原型模式又叫克隆模式
- Java自带克隆模式
- 实现克隆模式必须实现Cloneable
- 接口,如果不实现会发生java.lang.CloneNotSupportedException异常
- 当某个类的属性已经设定好需要创建很多相同属性值的对象的时候使用clone模式非常方便
- 使用clone模式不见得比传统的new方式性能高
- 浅克隆和深克隆
先看下面的代码,没有实现Cloneable接口
- package com.srr.dp.clone;
- /**
- * (原型模式)克隆模式
- */
- public class Appler /*implements Cloneable*/{
- private String clor;
- private int weight;
- private int volume;
- private StringBuilder descr;
- public Appler(String clor) {
- this.clor = clor;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- @Override
- public String toString() {
- return "Appler{" +
- "clor='" + clor + '\'' +
- ", weight=" + weight +
- ", volume=" + volume +
- ", descr=" + descr +
- '}';
- }
- }
- package com.srr.dp.clone;
- public class T {
- public static void main(String[] args) throws CloneNotSupportedException {
- Appler appler = new Appler("yellow");
- Appler appler1 = (Appler) appler.clone();
- System.out.println(appler1);
- }
- }
运行结果:
浅拷贝:
- package com.srr.dp.clone;
- /**
- * (原型模式)克隆模式
- * 浅拷贝
- */
- public class Appler implements Cloneable {
- private String clor;
- private int weight;
- private int volume;
- private Location loc;
- public Appler(String clor,int weight,int volume,Location loc) {
- this.clor = clor;
- this.weight = weight;
- this.volume = volume;
- this.loc = loc;
- }
- public String getClor() {
- return clor;
- }
- public void setClor(String clor) {
- this.clor = clor;
- }
- public int getWeight() {
- return weight;
- }
- public void setWeight(int weight) {
- this.weight = weight;
- }
- public int getVolume() {
- return volume;
- }
- public void setVolume(int volume) {
- this.volume = volume;
- }
- public Location getLoc() {
- return loc;
- }
- public void setLoc(Location loc) {
- this.loc = loc;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- //loc = (Locaton) loc.clone();
- return super.clone();
- }
- @Override
- public String toString() {
- return "Appler{" +
- "clor='" + clor + '\'' +
- ", weight=" + weight +
- ", volume=" + volume +
- ", loc=" + loc +
- '}';
- }
- }
- package com.srr.dp.clone;
- public class Location {
- String name;
- public Location(String name){
- this.name = name;
- }
- @Override
- public String toString() {
- return "Locaton{" +
- "name='" + name + '\'' +
- '}';
- }
- }
- package com.srr.dp.clone;
- /**
- * 测试代码
- */
- public class T {
- public static void main(String[] args) throws CloneNotSupportedException {
- Appler appler = new Appler("yellow",1,1,new Location("洛川"));
- Appler appler1 = (Appler) appler.clone();
- appler.setClor("red");
- appler.getLoc().name = "宝鸡";
- System.out.println("appler1 = "+appler1);
- System.out.println("appler = "+appler);
- }
- }
运行结果:
从结果发现,当改变appler 的颜色还有location的值后,拷贝的apper1对象的颜色未发生改变但是location发生了改变。
这就是浅拷贝,引用对象无法保证拷贝之后完全独立只是拷贝了地址但是地址指向的对象是共享的,
虽然String类型也是引用类型但是共享常量池所以不会有这个问题。
那么如何让引用类型拷贝之后独立呢?
那么就要使用深拷贝请看如下代码:
- package com.srr.dp.clone;
- /**
- * (原型模式)克隆模式
- * 浅拷贝
- */
- public class Appler implements Cloneable {
- private String clor;
- private int weight;
- private int volume;
- private Location loc;
- public Appler(String clor,int weight,int volume,Location loc) {
- this.clor = clor;
- this.weight = weight;
- this.volume = volume;
- this.loc = loc;
- }
- public String getClor() {
- return clor;
- }
- public void setClor(String clor) {
- this.clor = clor;
- }
- public int getWeight() {
- return weight;
- }
- public void setWeight(int weight) {
- this.weight = weight;
- }
- public int getVolume() {
- return volume;
- }
- public void setVolume(int volume) {
- this.volume = volume;
- }
- public Location getLoc() {
- return loc;
- }
- public void setLoc(Location loc) {
- this.loc = loc;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Appler appler = (Appler)super.clone();
- appler.loc = (Location) loc.clone();;
- return appler;
- }
- @Override
- public String toString() {
- return "Appler{" +
- "clor='" + clor + '\'' +
- ", weight=" + weight +
- ", volume=" + volume +
- ", loc=" + loc +
- '}';
- }
- }
- package com.srr.dp.clone;
- public class Location implements Cloneable{
- String name;
- public Location(String name){
- this.name = name;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- @Override
- public String toString() {
- return "Locaton{" +
- "name='" + name + '\'' +
- '}';
- }
- }
- package com.srr.dp.clone;
- /**
- * 测试代码
- */
- public class T {
- public static void main(String[] args) throws CloneNotSupportedException {
- Appler appler = new Appler("yellow",1,1,new Location("洛川"));
- Appler appler1 = (Appler) appler.clone();
- appler.setClor("red");
- appler.getLoc().name = "宝鸡";
- System.out.println("appler1 = "+appler1);
- System.out.println("appler = "+appler);
- }
- }
运行结果:
从结果发现,当改变appler 的颜色还有location的值后,拷贝的apper1对象的颜色未发生改变location也发生了改变。
上面说到String类型的拷贝不存在浅拷贝的问题,那么StringBuilder或者StringBuffer呢,鉴于篇幅这里使用StringBuilder来举例
请看代码:
- package com.srr.dp.clone;
- /**
- * (原型模式)克隆模式
- * 浅拷贝
- */
- public class Appler implements Cloneable {
- private String color;
- private int weight;
- private int volume;
- private Location loc;
- public String getColor() {
- return color;
- }
- public StringBuilder getDesc() {
- return desc;
- }
- public void setDesc(StringBuilder desc) {
- this.desc = desc;
- }
- private StringBuilder desc = new StringBuilder("好吃");
- public Appler(String color,int weight,int volume,Location loc) {
- this.color = color;
- this.weight = weight;
- this.volume = volume;
- this.loc = loc;
- }
- public String getClor() {
- return color;
- }
- public void setColor(String color) {
- this.color = color;
- }
- public int getWeight() {
- return weight;
- }
- public void setWeight(int weight) {
- this.weight = weight;
- }
- public int getVolume() {
- return volume;
- }
- public void setVolume(int volume) {
- this.volume = volume;
- }
- public Location getLoc() {
- return loc;
- }
- public void setLoc(Location loc) {
- this.loc = loc;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Appler appler = (Appler)super.clone();
- appler.loc = (Location) loc.clone();
- return appler;
- }
- @Override
- public String toString() {
- return "Appler{" +
- "color='" + color + '\'' +
- ", weight=" + weight +
- ", volume=" + volume +
- ", loc=" + loc +
- ", desc=" + desc +
- '}';
- }
- }
- package com.srr.dp.clone;
- public class Location implements Cloneable{
- String name;
- public Location(String name){
- this.name = name;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- @Override
- public String toString() {
- return "Locaton{" +
- "name='" + name + '\'' +
- '}';
- }
- }
- package com.srr.dp.clone;
- /**
- * 测试代码
- */
- public class T {
- public static void main(String[] args) throws CloneNotSupportedException {
- Appler appler = new Appler("yellow",1,1,new Location("洛川"));
- Appler appler1 = (Appler) appler.clone();
- appler.getDesc().append("得不得了");
- appler.getLoc().name = "宝鸡";
- System.out.println("appler1 = "+appler1);
- System.out.println("appler = "+appler);
- }
- }
运行结果:
这是是后你会发现当appler的desc值发生改变之后,apper1的值也发生改变了,说明StringBuilder的拷贝方式为浅拷贝,那么如何实现深拷贝呢
请看代码:
- package com.srr.dp.clone;
- /**
- * (原型模式)克隆模式
- * 浅拷贝
- */
- public class Appler implements Cloneable {
- private String color;
- private int weight;
- private int volume;
- private Location loc;
- public String getColor() {
- return color;
- }
- public StringBuilder getDesc() {
- return desc;
- }
- public void setDesc(StringBuilder desc) {
- this.desc = desc;
- }
- private StringBuilder desc = new StringBuilder("好吃");
- public Appler(String color,int weight,int volume,Location loc) {
- this.color = color;
- this.weight = weight;
- this.volume = volume;
- this.loc = loc;
- }
- public String getClor() {
- return color;
- }
- public void setColor(String color) {
- this.color = color;
- }
- public int getWeight() {
- return weight;
- }
- public void setWeight(int weight) {
- this.weight = weight;
- }
- public int getVolume() {
- return volume;
- }
- public void setVolume(int volume) {
- this.volume = volume;
- }
- public Location getLoc() {
- return loc;
- }
- public void setLoc(Location loc) {
- this.loc = loc;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Appler appler = (Appler)super.clone();
- appler.loc = (Location) loc.clone();
- appler.desc = new StringBuilder(this.desc);
- return appler;
- }
- @Override
- public String toString() {
- return "Appler{" +
- "color='" + color + '\'' +
- ", weight=" + weight +
- ", volume=" + volume +
- ", loc=" + loc +
- ", desc=" + desc +
- '}';
- }
- }
- package com.srr.dp.clone;
- public class Location implements Cloneable{
- String name;
- public Location(String name){
- this.name = name;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- @Override
- public String toString() {
- return "Locaton{" +
- "name='" + name + '\'' +
- '}';
- }
- }
- package com.srr.dp.clone;
- /**
- * 测试代码
- */
- public class T {
- public static void main(String[] args) throws CloneNotSupportedException {
- Appler appler = new Appler("yellow",1,1,new Location("洛川"));
- Appler appler1 = (Appler) appler.clone();
- appler.getDesc().append("得不得了");
- appler.getLoc().name = "宝鸡";
- System.out.println("appler1 = "+appler1);
- System.out.println("appler = "+appler);
- }
- }
运行结果:
这是是后你会发现当appler的desc值发生改变之后,apper1的值并没有发生改变。
写到这里原型模式就介绍完了。
原创不易,请多多支持!
JAVA设计模式之原型模式(prototype)的更多相关文章
- java设计模式4——原型模式
java设计模式4--原型模式 1.写在前面 本节内容与C++语言的复制构造函数.浅拷贝.深拷贝极为相似,因此建议学习者可以先了解C++的该部分的相关知识,或者学习完本节内容后,也去了解C++的相应内 ...
- 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)
原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...
- JAVA 设计模式之原型模式
目录 JAVA 设计模式之原型模式 简介 Java实现 1.浅拷贝 2.深拷贝 优缺点说明 1.优点 2.缺点 JAVA 设计模式之原型模式 简介 原型模式是六种创建型设计模式之一,主要应用于创建相同 ...
- java设计模式之原型模式
原型模式概念 该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.java中复制通过clone()实现的.clone中涉及深.浅复制.深.浅复制的概念如下: ⑴浅复制 ...
- 二十四种设计模式:原型模式(Prototype Pattern)
原型模式(Prototype Pattern) 介绍用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象.示例有一个Message实体类,现在要克隆它. MessageModel usin ...
- java设计模式之五原型模式(Prototype)
原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.本小结会通过对象的复制,进行讲解.在Java中 ...
- JAVA设计模式之 原型模式【Prototype Pattern】
一.概述: 使用原型实例指定创建对象的种类,而且通过拷贝这些原型创建新的对象. 简单的说就是对象的拷贝生成新的对象(对象的克隆),原型模式是一种对象创建型模式. 二.使用场景: 创建新的对象能够通过对 ...
- [设计模式] 4 原型模式 prototype
设计模式:可复用面向对象软件的基础>(DP)本文介绍原型模式和模板方法模式的实现.首先介绍原型模式,然后引出模板方法模式. DP书上的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创 ...
- 设计模式 笔记 原型模式 prototype
//---------------------------15/04/07---------------------------- //prototype 原型模式--对象创建型模式 /* 1:意图: ...
随机推荐
- mac OS mysql新建数据库运行sql文件
mysql -uroot -proot123 进入本地数据库 create database 数据库名; use 数据库名; source 文件路径 quit 退出
- 《C Primer Plus(第6版)中文版》一1.12 复习题
本节书摘来自异步社区<C Primer Plus(第6版)中文版>一书中的第1章,第1.12节,作者 傅道坤,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1. ...
- JQuery学习(一)
本文是学习廖老师的Javascript全栈教程后的一些笔记. 使用jQuery: 方法一:下载jQuery库,并在html页面中引入,方式如下: 1 <html> 2 <head&g ...
- OEL6 /boot分区删除恢复
对linux的应用有一段时间来,虽然谈不上精通,但日常应用maintenance还是没问题的,昨天自己故意把/boot分区直接format了,今天来尝试恢复,看看自己对linux启动方面的认识如何,总 ...
- Makefile中的CFLAGS,LDFLAGS,LIBS
CFLAGS:C编译器选项,而CXXFLAGS表示C++编译器的选项 1. CFLAGS参数 选项 说明 -c 用于把源码编译成.o对象文件,不进行链接过程 -o 用于连接生成可执行文件,在其后可以指 ...
- 分治思想--快速排序解决TopK问题
----前言 最近一直研究算法,上个星期刷leetcode遇到从两个数组中找TopK问题,因此写下此篇,在一个数组中如何利用快速排序解决TopK问题. 先理清一个逻辑解决TopK问题→快速排序→递 ...
- Linux下使用Rsync进行文件同步
数据备份方案 1.需要备份的文件目录有(原则上,只要运维人员写入或更改的数据都需要备份)./data,/etc/rc.local,/var/spool/cron/root等,根据不同都服务器做不同的调 ...
- E. Paint the Tree 树形dp
E. Paint the Tree 题目大意:给你一棵树,每一个点都可以染k种颜色,你拥有无数种颜色,每一种颜色最多使用2次,如果一条边的两个节点拥有同一种颜色,那么就说 这条边是饱和的,一个树的价值 ...
- 创造DotNet Core轻量级框架【二】
上一篇 创造DotNet Core轻量级框架[一] 10 题外话 上一篇文章感谢大家提出的各种小建议和各种讨论,但是在写文章的时候框架最最最基础的样子已经做出来了,所以大家的各种建议和意见我会在后续逐 ...
- 给大家发个Python和Django的福利吧,不要钱的那种~~~
前言一: 这篇是一个发放福利的文章,但是发放之前,我还是想跟大家聊聊我为什么要发这样的福利. 我第一份工作是做的IT桌面支持,日常工作就是给同事修修电脑.装装软件.开通账号.维护内部系统之类的基础工作 ...