原始模型模式(prototype)

     原始原型模式属于对象创建模式。通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原始模型模式。例如,在西游记中,孙悟空可以揪下一把毫毛,变出多个孙悟空,和他本身几乎一模一样,换言之,孙悟空可以根据自己的形象,复制出很多”身外之身“类,这就相当于采用了原始原型模式。

     在Java语言中构件模型直接支持原始模型模式。所有的Javabean都继承自Object,而Object类提供了一个Clone()方法,可以将一个JavaBean对象复制一份。但是,这个JavaBean必须实现了一个标识接口Cloneable,表明这个JavaBean支持复制。

一、原型模式的结构

    原型模式中有两种表现方式:第一种是简单形式,第二种是等级形式。这两种表现形式仅仅是原型模式的不同实现。

1、简单形式的原型模式

类图如下:


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

①客户角色:客户类提出创建对象请求;

②抽象原型角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。

③具体原型角色:被复制的对象,此角色需要实现抽象的原型角色所要求的接口。

实例代码:

//在抽象原型角色声明了一个Clone()方法
public interface Prototype extends Cloneable{
     Prototype  clone();
}
//具体原型角色实现clone()方法
public class ConcreatePrototype implements Prototype{
     /**
      * 克隆方法,实现原型模式的实现
      **/
     public Object clone(){
          try{
                  return super.clone();
          }catch(CloneNotSupportedException e){
                  return null;
          }
     }
}
public class Client{
     private Prototype prototype;
     public void operation(Prototype example){
          Prototype p = (Prototype)example.clone();
     }
}

 2、登记形式的原始模型模式

类图如下:


 作为原型模式的第二种形式,他有如下的角色:

①客户端角色:客户端类向管理员提出创建对象的请求;

②抽象原型角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体原型类所需的接口。

③具体原型角色:被复制的对象。需要实现抽象的原型角色所要求的接口;

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

实例代码:

//抽象原型角色,声明clone方法
public interface Prototype extends Cloneable{
     public Object clone();
}
//具体原型角色,实现抽象原型角色声明的方法
public class ConcreatePrototype implements Prototype{
     //克隆方法
     public synchronized Object clone(){
          Prototype temp = nulll;
          try{
               temp = (Prototype)super.clone();
               return temp;
          }catch(CloneNotSupportedException e){
               System.out.println("Clone failed");
          }finally{
               return temp;
          }
     }
}

     下面是原型管理器角色,保持一个聚集,作为对所有原型对象的等级,这个角色提供必要的方法,供外界增加新的原型对象和取得已经登记过的原型对象。代码如下:

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 ConcreatePrototype();
           Prototype copytype = (Prototype)prototype.clone();
           mgr.add(copytype);
     }
}

两种方式的比较:如果需要创建的原型对象数目较少而且比较固定的话,可以采用第一种方式。在这种情况下,原型对象的引用有客户端自己保存;如果要创建的原型对象数目不固定,可以采用第二种形式。在这种情况下,客户端并不保存对原型对象的引用,这个任务交给管理员对象。如果有,可以直接从管理员对象类取得这个对象的引用,如果没有,客户端就需要自行复制词原型对象。

注意:在模式的实现过程中,设计到对象的深复制和浅复制的问题,有关这个问题,请查看前面《java传值、传址以及对象的clone》一章节。

二、什么情况下使用原型模式(Prototype)

     建设一个系统产品类是动态加载的,而且产品类具有一定的等级结构。这个时候如果采用工厂模式的话,工厂类就不得不具有一个相应的等级结构。而产品类的等级结构一旦变化,工厂类的等级结构就不得不有一个相应的变化。这对于产品结构可能会有经常性的变化的系统来说,采用工厂模式就有不方便之处。

     这时如果采取原始原型模式,给每一个产品类配备一个克隆方法,便可以避免使用工厂模式所带来的具有固定等级结构的工厂类。这样,一个使用了原始原型模式的系统与他的产品对象是怎么创建出来的,以及这些产品对象之间的结构是怎样的,以及这个结构会不会发生变化是没有关系的。

三、原型模式的优缺点

优点:①原型模式允许动态的增加或减少产品类。由于创建产品类实例的方法是产品类内部具有的,因此,增加新产品对整个结构没有影响;

②原型模式提供简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而原型模式就不需要这样。

③具有给一个应用软件动态加载新功能的能力。例如:一个分析web服务器的记录文件的应用软件,这对每一种记录文件格式,都可以由一个相应的“格式类”负责。如果出现了应用软件不支持的新的web服务器,只需要体统一个格式类的克隆,并在客户端登记即可,而不必给每个软件的用户提供一个全新的软件包。

④产品类不需要非得有任何事先确定的等级结构,因为原型模式适用于任何的等级结构。

缺点:原型模式中每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说并不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持串行化的间接对象,或引用含有循环结构的时候。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值