1.定义
原型模式属于1种创建型模式,与其他创建型模式不同,原型模式不是直接构造对象,而是通过复制1个已存在的实例返回新的实例。
2.适用性
为什么要拷贝而不直接生成?我的理解是有些时候直接构造实例花费比较大,比如在构造对象的时候需要做大量的数据库查询,这样如果构造许多类似的对象还重复地查询数据库则开消很大,很没效力。直接拷贝现有的实例,在需要情况下做1些小的修改会显得高效许多。
3.结构
- Prototype: 声明1个克隆本身的接口
- ConcretePrototype:实现1个克隆本身的操作
- Client : 让1个原型克隆本身从而创建1个新的对象
从上图我们可以看出,原型模式中不管Prototype还是ConcretePrototype都提供有1个Clone()方法,方便拷贝本身返回新的实例。而Client类中注册有1个Prototype对象,方便Client从prototype克隆对象。
4.举例说明
Cookie定义了1个抽象的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和Builder1样,对用户隐藏了产品类,减少了客户知道的名字的数目。
优点:
- 可以再运行时刻增加和删除产品,这1点使原型模式比其他的创建型模式更加灵活
- 减少子类的构造,有些时候可以节省很多资源
- 用类动态配置利用,1些运行时刻环境允许你动态将类装在到利用中
缺点:
每个Prototype子类都必须实现Clone操作,有时候会有些困难。比如,当所斟酌的类已存在时就难以增加Clone操作;当内部包括1些不支持拷贝或有循环援用的对象时,实现克隆可能也会很困难。