设计模式——原型模式

来源:互联网 发布:打印机扫描软件通用 编辑:程序博客网 时间:2024/06/08 15:56

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

角色:

①简单形式的原型模式

抽象原型:通常由接口或者抽象类组成,此角色给出所有原型所需要的接口。

具体原型:被复制对象,此角色通常要实现所有抽象原型所要求的接口

②登记形式的原型模式

抽象原型:通常由接口或者抽象类组成,此角色给出所有原型所需要的接口。

具体原型:被复制对象,此角色通常要实现所有抽象原型所要求的接口

       原型管理器:创建具体的原型类对象,并记录每一个被创建的对象

优点:

1、如果创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
2、可以使用深克隆保持对象的状态。
3、原型模式提供了简化的创建结构。

缺点:

1、在实现深克隆的时候可能需要比较复杂的代码。
2、需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。

使用场景:

1、如果创建新对象成本较大,我们可以利用已有的对象进行复制来获得。
2、如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。
3、需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。

类图:

①简单形式的原型模式


②登记形式的原型模式


代码:

简单的原型模式

package com.sun.prototype;public interface Prototype extends Cloneable{abstract Prototype clone()  throws CloneNotSupportedException;}<strong></strong>

package com.sun.prototype;public class Resume implements Prototype{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Resume [name=" + name + "]";}public static void main(String[] args) throws CloneNotSupportedException {Resume r1 = new Resume();r1.setName("xxx");Resume r2 = (Resume) r1.clone();r2.setName("www");System.out.println("r1:"+r1);System.out.println("r2:"+r2);}@Overridepublic Prototype clone() throws CloneNotSupportedException {// TODO Auto-generated method stubreturn (Prototype) super.clone();}}

登记原型模式只要再简单原型模式基础上增加原型管理器:

package com.sun.prototype;import java.util.Vector;public class PrototypeManager {private Vector<Prototype> v = new Vector<Prototype>();public void add(Prototype p) {v.add(p);}public Prototype get(int i) {return v.get(i);}public int size() {return v.size();}public static void main(String[] args) throws CloneNotSupportedException {PrototypeManager pm = new PrototypeManager();Resume p = new Resume();p.setName("xxx");pm.add(p);Resume p2 = (Resume) p.clone();p2.setName("www");pm.add(p2);System.out.println((Resume)pm.get(0));System.out.println((Resume)pm.get(1));}}
简单形式和登记形式各有所长,如果创建对象较少,且比较固定可采用简单形式,如果创建对象数目不固定则可采用第二种,在这种情况下客户端不需要保存对原型对象的应用,由原型管理器统一保存,在复制一个原型对象之前,客户端查看是否有满足条件的原型对象,如果有直接获取,没有则自行复制。


0 0
原创粉丝点击