Java与模式学习笔记 —— 原始模型(Prototype)模式

原始模型模式属于对象创建模式。通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多同类型的对象。

一、引言

Java语言的构件模型直接支持原始模型模式。所有的JavaBean都继承自java.lang.Object,而Object类提供一个clone()方法,可以将一个JavaBean对象复制一份。但是,这个JavaBean必须实现一个标识接口Cloneable,表明这个JavaBean支持复制。如果一个对象没有实现这个接口而调用clone()方法,Java编译器会抛出CloneNotSupportedException异常。

克隆满足的条件
  1. 对任何的对象x,都有:x.clone() != x。换言之,克隆对象与原对象不是同一个对象。
  2. 对任何的对象x,都有:x.clone().getClass = x.getClass()。换言之,克隆对象与原对象的类型一样。
  3. 如果对象x的equals()方法定义恰当的话,那么x.clone.equals(x)应当是成立的。

二、原始模型模式的结构

根据实现的不同分为:简单形式和登记形式

简单形式的原始模型模式

在这里插入图片描述

这种形式涉及到三个角色:

  • 客户(Client)角色:客户类提出创建对象的请求。
  • 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
  • 具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
public class Client {
	private Prototype prototype;
	
	public void operation(Prototype example) {
		Prototype p = (Prototype) example.clone();
	}
}

public interface Prototype extends Cloneable {
	Prototype clone();
}

public class ConcretePrototype implements Prototype {
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			return null;
		}
	}
}
登记形式的原始模型模式

在这里插入图片描述

这种形式涉及到四个角色:

  • 客户端(Client)角色:客户端类向管理员提出创建对象的请求。
  • 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体原型类所需的接口。
  • 具体原型(Concrete Prototype)角色:被复制的对象。需要实现抽象的原型角色所要求的接口。
  • 原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。
public interface Prototype extends Cloneable {
	public Object clone();
}

public class ConcretePrototype implements Prototype {
	public synchronized Object clone() {
		Prototype temp = null;
		try {
			temp = (Prototype) super.clone();
			return temp;
		} catch (CloneNotSupportedException e) {
			System.out.println("Clone failed.");
		} finally {
			return temp;
		}
	}
}

import java.util.Vector;

public class PrototypeManager {
	private Vector objects = new Vector();
	
	public void add (Prototype object) {
		objects.add(object);
	}
	
	public Prototype get(int i) {
		return (Prototype) objects.get(i);
	}
	
	public int getSize() {
		return objects.size();
	}
}

public class Client {
	private PrototypeManager mgr;
	private Prototype prototype;
	
	public void registerPrototype() {
		prototype = new ConcretePrototype();
		Prototype copytype = (Prototype) prototype.clone();
		mgr.add(copytype);
	}
}
两种形式的比较

如果需要创建的原型对象数目较少而且比较固定的话,采用简单形式,原型对象的引用可以由客户端自己保存。
如果需要创建的原型对象数目不固定的话,采用登记形式,客户端不保存对原型对象的引用,这个任务被交给管理员对象。在复制一个原型对象之前,客户端可以查看管理员对象是否已经有一个满足要求的原型对象。如果有,可以直接从管理员类取得这个对象引用;如果没有,客户端就需要自行复制此原型对象。

三、深复制和浅复制

浅复制

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象

深复制

被复制对象的所有的变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量被指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值