首页 > 代码库 > 设计模式(四) 原型模式(Prototype)

设计模式(四) 原型模式(Prototype)

1.定义

原型模式属于一种创建型模式,与其他创建型模式不同,原型模式不是直接构造对象,而是通过复制一个已经存在的实例返回新的实例。


2.适用性

为何要拷贝而不直接生成?我的理解是有些时候直接构造实例花费比较大,比如在构造对象的时候需要做大量的数据库查询,这样如果构造许多类似的对象还重复地查询数据库则开销很大,很没效率。直接拷贝现有的实例,在需要情况下做一些小的修改会显得高效许多。


3.结构

技术分享

  • Prototype: 声明一个克隆自身的接口
  • ConcretePrototype:实现一个克隆自身的操作
  • Client : 让一个原型克隆自身从而创建一个新的对象

从上图我们可以看出,原型模式中无论Prototype还是ConcretePrototype都提供有一个Clone()方法,方便拷贝自身返回新的实例。而Client类中注册有一个Prototype对象,方便Client从prototype克隆对象。


4.举例说明

Cookie定义了一个抽象的Prototype,ChocolateCookie和MilkCookie分别是ConcretePrototype,CookieManager是Client,ManageCookies是测试类。

Cookie.java:

package com.andy.designpattern.prototype;

public class Cookie implements Cloneable {
	protected String name;
	public Cookie() {
		// TODO Auto-generated constructor stub
		name = "Cookie";
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return (Cookie)super.clone();
	}
	public String getName() {
		return name;
	}
}

ChocolateCookie.java:

package com.andy.designpattern.prototype;

public class ChocolateCookie extends Cookie {
	public ChocolateCookie() {
		// TODO Auto-generated constructor stub
		this.name = "ChocolateCookie";
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return (ChocolateCookie)super.clone();
	}
}
MilkCookie.java:

package com.andy.designpattern.prototype;

import java.util.jar.Attributes.Name;

public class MilkCookie extends Cookie {
	public MilkCookie(){
		this.name = "MilkCookie";
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return (MilkCookie)super.clone();
	}
}

CookieMachine.java:

package com.andy.designpattern.prototype;

public class CookieMachine {
	private Cookie cookie;
	public Cookie makeCookie(Cookie cookie) throws CloneNotSupportedException{
		return (Cookie)cookie.clone();
	}
}

ManageCookies.java:

package com.andy.designpattern.prototype;

public class ManageCookies {
	public static void main(String[] args) {
		CookieMachine machine = new CookieMachine();
		try {
			System.out.println(machine.makeCookie(new MilkCookie()).getName());
			System.out.println(machine.makeCookie(new ChocolateCookie()).getName());
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

5.效果

Prototype与Abstract Factory和Builder一样,对用户隐藏了产品类,减少了客户知道的名字的数目。

优点:

  1. 可以再运行时刻增加和删除产品,这一点使原型模式比其他的创建型模式更加灵活
  2. 减少子类的构造,有些时候可以节省不少资源
  3. 用类动态配置应用,一些运行时刻环境允许你动态将类装在到应用中

缺点:

每一个Prototype子类都必须实现Clone操作,有时候会有些困难。比如,当所考虑的类已经存在时就难以增加Clone操作;当内部包括一些不支持拷贝或者有循环引用的对象时,实现克隆可能也会很困难。




设计模式(四) 原型模式(Prototype)