当前位置: 首页 > news >正文

原始模型

概念

         通过一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。

有两种表现形式

 1  简单形式

          1  客户角色:客户端提出创建对象的请求,

          2 抽象原型角色:抽象角色,通常有一个Java接口或Java抽象类实现,给出具体原型所需要接口

          3 具体原型  被复制的对象,实现抽象原型角色

 public class Client {
 3     
 4     private Prototype prototype;
 5     
 6     public  void operation(Prototype example) {
 7         Prototype p =(Prototype)example.clone();
 8     }
 9 
10 }
11 //抽象原型
12 interface Prototype extends Cloneable{
13     public Object clone();
14 }
15 
16 class ConcretePrototype implements Prototype{
17     public Object clone(){
18         try{
19             return super.clone();
20         }catch (CloneNotSupportedException e) {
21             return null;
22         }
23     }
24 }
View Code

通常Java语言中实现clone方法的办法就是这种形式的原始模型模式实现

2  登记形式的原始模型

      

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

class ConcretePrototype implements Prototype{
    public synchronized Object clone(){
        Prototype temp = null;
        
        try {
            temp = (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            return temp;
        }
    }
}

class PrototypeManager{
    private Vector<Prototype> objects = new Vector<>();
    void add(Prototype p) {
        objects.add(p);
    }
    Prototype get(int i){
         return objects.get(i);
    }
    int size() {
        return objects.size();
    }
}
class Client{
    private PrototypeManager manager;
    private Prototype pro;
    public void registerPro(){
        Prototype copy = (Prototype) pro.clone();
        manager.add(copy);
    }
}
View Code

这两种形式各有长短处

如果需要创建的原型对象数目较少而且比较固定的话,可以采取第一种形式,也即简单形式的原始模式。在这种情况下,原型对象的引用可以由客户端自己保存。
如果要创建的原型对象数目不固定的话,可以采取第二种形式,也即登记形式的原始模型模式。在这种情况下,客户端并不保存以原型的引用,这个任务交给管理员对象。在复制一个原型对象之前,客户端可以查看管理员对象是否已经有一个满足要求的原型对象。如果有,可以直接从管理员类取得这个对象的引用;如果没有,客户端就需要自行复制些原型对象。
什么情况下使用原型模式
假设一个系统的产品类是动态加载的,而且产品类具有一定的等级结构。这个时候如果采取工厂模式的话,工厂类就不得不具有一个相应的等级结构。而产品类的等级结构一旦变化,工厂类的等级结构就不得不有一个相应的变化。这对于产品结构可能会有经常性变化系统来说,采用工厂模式就有不便之处。这时如果采取原始模型模式,给每一个产品类配备一个克隆方法(大多数时候只需要给产品等级结构的根类配备一个克隆方法),便可以避免使用工厂模式所带来的具有固定等级结构的工厂类。
原型模式的优缺点
抽象工厂模式有许多与原始模型模式和建造模式相同的效果,包括客户端不知道具体产品类,而只知道抽象产品类,客户端不需要知道这么多的具体产品名称。如果有新的产品类加入,客户端不需要进行改造就可以直接使用。
原始模型模式有其特有的优点:
1.原始模型模式允许动态地增加或减少产品类。由于创建产品类实例的方法是产品类内部具有的,因此,增加新产品对整个结构没有影响
2.原始模型模式提供简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而原始模型模式就不需要这样。对于java来说,原始模型模式又有其特有的方便之处,因为java语言天生就将原始模型模式设计到了语言模型里。善于利用原始模型模式和java语言的特点,可以事半功倍。
3.具有给一个应用软件动态加载新功能的能力。如一个分析web服务器的记录文件的应用 软件,针对每一种记录文件格式,都可以由一个相就的“格式类”负责。如果出现了应用软件所不支持的新的web服务器,只需要提供一个格式类的克隆,并在客户端登记即可,而不必给每个软件的用户提供一个全新的软件包。
4.产品类不需要非得有任何事先确定的等级结构,因为原始模型模式适用于任何的等级结构。
    原始模型模式最主要的缺点就是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。

转载于:https://www.cnblogs.com/whesuanfa/p/7389660.html

相关文章:

  • vue 父组建获取子组建方法为获得_vue实现思想分享和探讨
  • office2013安装程序找不到_office2007提示“错误1706,安装程序找不到所需文件
  • Scrapy学习篇(二)之常用命令行工具
  • uefi+guid分区与legacy+mbr分区_硬盘分区表格式GUID和MBR知识普及
  • excel处置4000行数据卡_数十万数据Excel数据不好处理怎么办?
  • 【学习随笔】关于php.ini的各项说明-1
  • layui获取input信息_爬虫实战:运用requests库和正则表达式爬取淘宝商品信息。
  • 分支结构if
  • opencv3和qt5计算机视觉应用开发pdf_计算机视觉方向简介 | 用深度学习进行表格提取...
  • Runtime 类
  • vue element tree 后台 数据转换_mallcloud商城vue
  • excel统计行数_WPS| 12个简单的Excel技巧,却能让造价人变得如此逆天!
  • RandomAccess接口
  • python用input输入list_python怎么用input函数输入一个列表
  • “大数据应用场景”之隔壁老王(连载四)
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 30天自制操作系统-2
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • CSS 专业技巧
  • Go 语言编译器的 //go: 详解
  • Golang-长连接-状态推送
  • HTTP 简介
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • JavaScript标准库系列——Math对象和Date对象(二)
  • laravel5.5 视图共享数据
  • leetcode386. Lexicographical Numbers
  • Linux中的硬链接与软链接
  • mongodb--安装和初步使用教程
  • ng6--错误信息小结(持续更新)
  • Ruby 2.x 源代码分析:扩展 概述
  • 大快搜索数据爬虫技术实例安装教学篇
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 记录:CentOS7.2配置LNMP环境记录
  • 聚簇索引和非聚簇索引
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 模型微调
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • #etcd#安装时出错
  • #include到底该写在哪
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (转)关于pipe()的详细解析
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • @requestBody写与不写的情况
  • [ C++ ] STL---string类的使用指南
  • [<事务专题>]
  • [20171101]rman to destination.txt
  • [ACL2022] Text Smoothing: 一种在文本分类任务上的数据增强方法
  • [Android实例] 保持屏幕长亮的两种方法 [转]
  • [BT]BUUCTF刷题第4天(3.22)
  • [element-ui] el-dialog 中的内容没有预先加载,因此无法获得内部元素的ref 的解决方案
  • [ffmpeg] x264 配置参数解析