Chapter 9 原型模式
原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 简单的说就是clone一个对象实例。使得clone出来的copy和原有的对象一模一样。 插一个简单使用clone的例子,如果一个对象内部有可变对象实例的话,public API不应该直接返回该对象的引用,以防调用方的code改变该对象的内部状态。这个时候可以返回该对象的clone。 一般而言,我们要的clone应该是这样的。copy和原型的内容一样,但是又是彼此隔离的。即在clone之后,改变其中一个不影响另外一个。
原型模式分为浅复制和深复制,其中浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深复制把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
class User {
String name;
int age;
}
class Account implements Cloneable {
User user;
long balance;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

我们之所以要深copy,是因为默认的实现提供的浅copy不是隔离的,换言之,改变copy的东西,会影响到原型的内部。比如例子中,改变copy的user的name,影响了原型。特别注意的是string是一种拥有值类型特点的特殊引用类型。
class User implements Cloneable {
String name;
int age;
@Override
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
}
class Account implements Cloneable {
User user;
long balance;
@Override
public Account clone() throws CloneNotSupportedException {
Account account = null;
account = (Account) super.clone();
if (user != null) {
account.user = user.clone();
}
return account;
}
}

再来贴2个实例代码
一、浅复制:
package xiao;
class WorkExp{
private String workDate;
private String company;
public String getWorkDate() {
return workDate;
}
public void setWorkDate(String workDate) {
this.workDate = workDate;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
}
class Resume implements Cloneable{
private String name;
private String sex;
private String age;
private WorkExp work;
public Resume(String name){
this.name = name;
work = new WorkExp();
}
public void setPerInfo(String sex,String age){
this.sex = sex;
this.age = age;
}
public void setWorkExper(String timeArea,String company){
work.setWorkDate(timeArea);
work.setCompany(company);
}
public void display(){
System.out.println(this.name+" "+this.sex+" "+this.age);
System.out.println(work.getWorkDate()+" "+work.getCompany());
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Hello {
public static void main(String[] args) throws Exception{
Resume a = new Resume("big bird");
a.setPerInfo("male", "20");
a.setWorkExper("1998-2006", "IT company");
Resume b = (Resume)a.clone();
b.setWorkExper("1998-2004", "YY company");
Resume c = (Resume)a.clone();
c.setPerInfo("female", "22");
c.setWorkExper("1998-2004", "ZZ company");
a.display();
b.display();
c.display();
}
}
输出:
big bird male 20
1998-2006 ZZ company
big bird male 20
1998-2004 ZZ company
big bird female 22
1998-2004 ZZ company
二、深复制:
package xiao;
class WorkExp implements Cloneable{
private String workDate;
private String company;
public String getWorkDate() {
return workDate;
}
public void setWorkDate(String workDate) {
this.workDate = workDate;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public WorkExp clone() throws CloneNotSupportedException {
return (WorkExp)super.clone();
}
}
class Resume implements Cloneable{
private String name;
private String sex;
private String age;
private WorkExp work;
public Resume(String name){
this.name = name;
work = new WorkExp();
}
public void setPerInfo(String sex,String age){
this.sex = sex;
this.age = age;
}
public void setWorkExper(String timeArea,String company){
work.setWorkDate(timeArea);
work.setCompany(company);
}
public void display(){
System.out.println(this.name+" "+this.sex+" "+this.age);
System.out.println(work.getWorkDate()+" "+work.getCompany());
}
public Resume clone() throws CloneNotSupportedException {
Resume resume = null;
resume = (Resume) super.clone();
if(work != null){
resume.work = work.clone();
}
return resume;
}
}
public class Hello {
public static void main(String[] args) throws Exception{
Resume a = new Resume("big bird");
a.setPerInfo("male", "20");
a.setWorkExper("1998-2006", "IT company");
Resume b = (Resume)a.clone();
b.setWorkExper("1998-2004", "YY company");
Resume c = (Resume)a.clone();
c.setPerInfo("female", "22");
c.setWorkExper("1998-2004", "ZZ company");
a.display();
b.display();
c.display();
}
}
输出:
big bird male 20
1998-2006 IT company
big bird male 20
1998-2004 YY company
big bird female 22
1998-2004 ZZ company
Chapter 9 原型模式的更多相关文章
- 设计模式(六)原型模式(Prototype Pattern)
一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...
- PHP 原型模式
原型模式:原型模式是先创建好一个原型对象,然后通过拷贝原型对象来创建新的对象.适用于大对象的创建,因为创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需内存拷贝即可.也可以用作动态 ...
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- 设计模式--原型模式Prototype(创建型)
一.原型模式 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.原型模式实现的关键就是实现Clone函数,还需要实现深拷贝. 二.UML类图 三.例子 //父类 class Resume ...
- C#设计模式之原型模式
原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象. 分析: 孙悟空:根据自己的形状复制(克隆)出多个身外身 软件开发:通过复制一个原型对象得到多个与原型对象一模一样的新对 ...
- 设计模式 之 原型模式(ProtoType)
什么时原型模式 或 原型模式的定义: 用原型实例来指定创建对象的种类,并通过拷贝这些原型创建新的对象. 原型模式的特点: 1),它是面向接口编程, 2),原型模式的新对象是对原型实例的一个克隆 ...
- Objective-C 原型模式 -- 简单介绍和使用
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建 ...
- C#设计模式-原型模式
在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在内存中分配 ...
- C#设计模式系列:原型模式(Prototype)
1.原型模式简介 1.1>.定义 原型模式(Prototype)用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象. 1.2>.使用频率 中 1.3>.原型模式应用 首先 ...
随机推荐
- 关于 free() 函数用法的若干疑问
<C语言参考手册>中关于 free() 函数有如下描述. (1)free() 函数的原型 void free(void *ptr); (2)free 函数对以前由 malloc.callo ...
- Ibatis入门基本语法(转) good
Ibatis入门基本语法 一个项目中在写ibatis中的sql语句时,where user_id in (#user_id_list# ), 运行时总是不行,后来上网查了查,才知道这里不该用#,而应该 ...
- 利用bind搭建dns
下载bind,我下载的是bind-9.3.1rc1.tar.gz 我下载的文件放在/root目录下 进入目录解压缩 [root@linux root]#tar xfz bind-9.3.1rc1.ta ...
- android搭建环境错误 daemon not running. starting it now on port 5037 ADB server didn't ACK
android搭建环境错误 daemon not running. starting it now on port 5037 ADB server didn't ACK ADB server didn ...
- Java Date 和 Calendar
Java 语言的Date(日期),Calendar(日历),DateFormat(日期格式)组成了Java标准的一个基本但是非常重要的部分.日期是商业逻辑计算一个关键的部分,所有的开发者都应该能够计算 ...
- poj 1088 滑雪(区间dp+记忆化搜索)
题目链接:http://poj.org/problem?id=1088 思路分析: 1>状态定义:状态dp[i][j]表示在位置map[i][j]可以滑雪的最长区域长度: 2>状态转移方程 ...
- Microsoft Deployment Toolkit 2013 Preview Release Now Available
MDT 2013 provides a common console with comprehensive tools and guidance for every organizational ro ...
- react的初涉入
1.react并不是一个完整的MVC,MVVM框架 它只负责view层 2.react跟Web Components不冲突 3.react的特点是“轻” 4.react用组件的方式重新思考构建UI的过 ...
- 写一个背景渐变的TextView输入框
1:在res文件夹下新建一个drawble文件夹,并新建一个背景文件如writebg.xml <?xml version="1.0" encoding="utf-8 ...
- s3c2440栈分配情况(fl2440裸机 stack)
//2440INIT.S ;The location of stacks UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ SVCStac ...