文章目录

  • 第六章 Caché 设计模式 原型模式
  • 定义
  • 使用场景
  • 优点
  • 结构图
  • 描述
  • 示例
    • 初级写法
      • 缺点
    • 中级写法
      • 缺点
    • 高级写法 (浅复制)
    • 浅复制
    • 深复制
  • 完整示例
    • 简历类(复制类)
    • 对象类(工作经验类)
  • 调用
  • 思考

第六章 Caché 设计模式 原型模式

定义

  • 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  • 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

使用场景

使用原形模式可以解决复杂对象构建资源消耗的问题。也可以用来只读保护。注意其java里继承Cloneable接口。C#继承ICloneable接口。Caché 直接使用%ConstructClone()方法,克隆时不会走构造函数。

优点

  • 一般在初始化的信息不发生变的情况下,克隆是最好的办法,这即隐藏了对象创建的细节,又对性能是大大的提高。
  • 不用重新初始化对象,而是动态地获得对象运行时的状态。

结构图

描述

要求有一个简历类,必须要有姓名,可以设置性别和年龄,可以设置工作经历。最终需要三分简历。

示例

简历类

Class PHA.YX.Design.Prototype.Resume Extends %RegisteredObject
{Property name As %String [ Private ];Property sex As %String [ Private ];Property age As %String [ Private ];Property timeArea As %String [ Private ];Property company As %String [ Private ];Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{s $this.name = nameQuit $$$OK
}Method SetPersonalInfo(sex As %String, age As %String)
{s $this.sex=sexs $this.age=age
}Method SetWorkExperience(timeArea As %String, company As %String)
{s $this.timeArea=timeAreas $this.company=company
}Method Display()
{w ..name _ " " _ ..sex _ " " _ ..age,!w "工作经历:" _ ..timeArea _ " " _ ..company,!
}}

初级写法

/// d ##class(PHA.YX.Design.Program).PrototypeExamplePrimary()
ClassMethod PrototypeExamplePrimary()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")s mResumeB = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeB.SetPersonalInfo("男","30")d mResumeB.SetWorkExperience("2015-2020","XX公司")s mResumeC = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeC.SetPersonalInfo("男","30")d mResumeC.SetWorkExperience("2015-2020","XX公司")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}
DHC-APP>d ##class(PHA.YX.Design.Program).PrototypeExamplePrimary()
姚鑫 男 30
工作经历:2015-2020 XX公司
姚鑫 男 30
工作经历:2015-2020 XX公司
姚鑫 男 30
工作经历:2015-2020 XX公司

缺点

三分简历需要实例化三次,如果需要一百份,就需要实例化一百次,徒增内存。

中级写法

/// d ##class(PHA.YX.Design.Program).PrototypeExampleIntermediate()
ClassMethod PrototypeExampleIntermediate()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeA# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC = mResumeAd mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}
DHC-APP>d ##class(PHA.YX.Design.Program).PrototypeExampleIntermediate()
姚鑫 男 30
工作经历:2015-2020 XX公司
姚鑫 男 30
工作经历:2015-2020 XX公司
姚鑫 男 30
工作经历:2015-2020 XX公司

缺点

引用传值,改动其中一处其他复制实例一起改动。把mResumeB设置一下年龄,mResumeC设置一下公司。如下:

/// d ##class(PHA.YX.Design.Program).PrototypeExampleIntermediate()
ClassMethod PrototypeExampleIntermediate()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeAd mResumeB.SetPersonalInfo("男","31")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC = mResumeAd mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}

运行结果

DHC-APP>d ##class(PHA.YX.Design.Program).PrototypeExampleIntermediate()
姚鑫 男 31
工作经历:2017-2020 SS公司
姚鑫 男 31
工作经历:2017-2020 SS公司
姚鑫 男 31
工作经历:2017-2020 SS公司

高级写法 (浅复制)

使用 .%ConstructClone()方法复制

/// d ##class(PHA.YX.Design.Program).PrototypeExampleSenior()
ClassMethod PrototypeExampleSenior()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeA.%ConstructClone()d mResumeB.SetPersonalInfo("男","31")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC =mResumeA.%ConstructClone()d mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}
DHC-APP> d ##class(PHA.YX.Design.Program).PrototypeExampleSenior()
姚鑫 男 30
工作经历:2015-2020 XX公司
姚鑫 男 31
工作经历:2015-2020 XX公司
姚鑫 男 30
工作经历:2017-2020 SS公司

浅复制

如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其副本引用统一对象。如下增加一个工作经验类的引用字段:

增加一个WorkExperience类

Class PHA.YX.Design.Prototype.WorkExperience Extends %RegisteredObject
{Property workDate As %String [ Private ];Method workDateGet() As %String [ ServerOnly = 1 ]
{Quit i%workDate
}Method workDateSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{s i%workDate = ArgQuit $$$OK
}Property company As %String [ Private ];Method companyGet() As %String [ ServerOnly = 1 ]
{Quit i%company
}Method companySet(Arg As %String) As %Status [ ServerOnly = 1 ]
{s i%company = ArgQuit $$$OK
}}

PHA.YX.Design.Prototype.Resume 增加一个work字段引用WorkExperience

Property work As WorkExperience [ Private ];

并且在构造方法初始化它

Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{s $this.name = names ..work = ##class(WorkExperience).%New()Quit $$$OK
}

给对象添加WorkExperience数据方法

Method CloneWorkExperience()
{s ..work = ..work.%ConstructClone()
}

输出也修改一下

Method Display()
{w ..name _ " " _ ..sex _ " " _ ..age,!w "工作经历:" _ ..timeArea _ " " _ ..company,!w "工作经历Object:" _ ..work.workDateGet() _ " " _ ..work.companyGet(),!
}
/// d ##class(PHA.YX.Design.Program).PrototypeExampleShallow()
ClassMethod PrototypeExampleShallow()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")d mResumeA.SetWorkExperienceObject("2010-2011","腾讯")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeA.%ConstructClone()d mResumeB.SetPersonalInfo("男","31")d mResumeB.SetWorkExperienceObject("2011-2012","阿里")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC =mResumeA.%ConstructClone()d mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeC.SetWorkExperienceObject("2012-2013","百度")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}
DHC-APP> d ##class(PHA.YX.Design.Program).PrototypeExampleShallow()
姚鑫 男 30
工作经历:2015-2020 XX公司
工作经历Object:2012-2013 百度
姚鑫 男 31
工作经历:2015-2020 XX公司
工作经历Object:2012-2013 百度
姚鑫 男 30
工作经历:2017-2020 SS公司
工作经历Object:2012-2013 百度

结果发现。引用的字段并没有重新复制。

深复制

我们在PHA.YX.Design.Prototype.Resume里给work属性,增加一个克隆方法。

Method CloneWorkExperience()
{s ..work = ..work.%ConstructClone()
}
/// d ##class(PHA.YX.Design.Program).PrototypeExampleDeep()
ClassMethod PrototypeExampleDeep()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")d mResumeA.CloneWorkExperience()d mResumeA.SetWorkExperienceObject("2010-2011","腾讯")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeA.%ConstructClone()d mResumeB.SetPersonalInfo("男","31")d mResumeB.CloneWorkExperience()d mResumeB.SetWorkExperienceObject("2011-2012","阿里")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC =mResumeA.%ConstructClone()d mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeC.CloneWorkExperience()d mResumeC.SetWorkExperienceObject("2012-2013","百度")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}

结果发现,把引用字段work的值也修改成功。

DHC-APP>d ##class(PHA.YX.Design.Program).PrototypeExampleDeep()
姚鑫 男 30
工作经历:2015-2020 XX公司
工作经历Object:2010-2011 腾讯
姚鑫 男 31
工作经历:2015-2020 XX公司
工作经历Object:2011-2012 阿里
姚鑫 男 30
工作经历:2017-2020 SS公司
工作经历Object:2012-2013 百度

完整示例

简历类(复制类)

Class PHA.YX.Design.Prototype.Resume Extends %RegisteredObject
{Property name As %String [ Private ];Property sex As %String [ Private ];Property age As %String [ Private ];Property timeArea As %String [ Private ];Property company As %String [ Private ];Property work As WorkExperience [ Private ];Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{s $this.name = names ..work = ##class(WorkExperience).%New()Quit $$$OK
}Method CloneWorkExperience()
{s ..work = ..work.%ConstructClone()
}Method SetPersonalInfo(sex As %String, age As %String)
{s $this.sex=sexs $this.age=age
}Method SetWorkExperience(timeArea As %String, company As %String)
{s $this.timeArea=timeAreas $this.company=company
}Method SetWorkExperienceObject(workDate As %String, company As %String)
{d ..work.workDateSet(workDate)d ..work.companySet(company)
}Method Display()
{w ..name _ " " _ ..sex _ " " _ ..age,!w "工作经历:" _ ..timeArea _ " " _ ..company,!w "工作经历Object:" _ ..work.workDateGet() _ " " _ ..work.companyGet(),!
}}

对象类(工作经验类)

Class PHA.YX.Design.Prototype.WorkExperience Extends %RegisteredObject
{Property workDate As %String [ Private ];Method workDateGet() As %String [ ServerOnly = 1 ]
{Quit i%workDate
}Method workDateSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{s i%workDate = ArgQuit $$$OK
}Property company As %String [ Private ];Method companyGet() As %String [ ServerOnly = 1 ]
{Quit i%company
}Method companySet(Arg As %String) As %Status [ ServerOnly = 1 ]
{s i%company = ArgQuit $$$OK
}}

调用

/// d ##class(PHA.YX.Design.Program).PrototypeExamplePrimary()
ClassMethod PrototypeExamplePrimary()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")s mResumeB = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeB.SetPersonalInfo("男","30")d mResumeB.SetWorkExperience("2015-2020","XX公司")s mResumeC = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeC.SetPersonalInfo("男","30")d mResumeC.SetWorkExperience("2015-2020","XX公司")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}/// d ##class(PHA.YX.Design.Program).PrototypeExampleIntermediate()
ClassMethod PrototypeExampleIntermediate()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeAd mResumeB.SetPersonalInfo("男","31")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC = mResumeAd mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}/// d ##class(PHA.YX.Design.Program).PrototypeExampleSenior()
ClassMethod PrototypeExampleSenior()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeA.%ConstructClone()d mResumeB.SetPersonalInfo("男","31")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC =mResumeA.%ConstructClone()d mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}/// d ##class(PHA.YX.Design.Program).PrototypeExampleShallow()
ClassMethod PrototypeExampleShallow()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")d mResumeA.SetWorkExperienceObject("2010-2011","腾讯")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeA.%ConstructClone()d mResumeB.SetPersonalInfo("男","31")d mResumeB.SetWorkExperienceObject("2011-2012","阿里")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC =mResumeA.%ConstructClone()d mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeC.SetWorkExperienceObject("2012-2013","百度")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}/// d ##class(PHA.YX.Design.Program).PrototypeExampleDeep()
ClassMethod PrototypeExampleDeep()
{s mResumeA = ##class(PHA.YX.Design.Prototype.Resume).%New("姚鑫")d mResumeA.SetPersonalInfo("男","30")d mResumeA.SetWorkExperience("2015-2020","XX公司")d mResumeA.CloneWorkExperience()d mResumeA.SetWorkExperienceObject("2010-2011","腾讯")# dim mResumeB as PHA.YX.Design.Prototype.Resumes mResumeB = mResumeA.%ConstructClone()d mResumeB.SetPersonalInfo("男","31")d mResumeB.CloneWorkExperience()d mResumeB.SetWorkExperienceObject("2011-2012","阿里")# dim mResumeC as PHA.YX.Design.Prototype.Resumes mResumeC =mResumeA.%ConstructClone()d mResumeC.SetWorkExperience("2017-2020","SS公司")d mResumeC.CloneWorkExperience()d mResumeC.SetWorkExperienceObject("2012-2013","百度")d mResumeA.Display()d mResumeB.Display()d mResumeC.Display()
}

思考

用深复制实现,Java,Python,C#,连接Caché数据库(有连接属性,连接时间),Caché数据库持有SQL数据库连接(有连接属性,连接时间)。感兴趣的同学实现后可以发我一起参考下。

第六章 Caché 设计模式 原型模式相关推荐

  1. 第四章 Caché 设计模式 代理模式

    文章目录 第四章 Caché 设计模式 代理模式 定义 类型 使用场景 优点 缺点 结构图 完整示例 抽象主题类 真实主题类 代理类 对象类 调用 思考 第四章 Caché 设计模式 代理模式 定义 ...

  2. 第二十二章 Caché 设计模式 享元模式

    文章目录 第二十二章 Caché 设计模式 享元模式 定义 优点 使用场景 结构图 描述 完整示例 实体类 抽象享元角色 实现享元角色 享元工厂 调用 思考 第二十二章 Caché 设计模式 享元模式 ...

  3. 设计模式 原型模式_创新设计模式:原型模式

    设计模式 原型模式 原型模式用于创建对象的副本. 这种模式非常有用,特别是当从头开始创建对象的成本很高时. 与builder , factory和abstract factory模式相比,它不会从头开 ...

  4. 设计模式 原型模式_设计模式:原型

    设计模式 原型模式 创新设计模式之一是原型设计模式 . 尽管原型是创造模式,但它在概念上与其他模式有所区别. 我的意思是原型在某种意义上创造了自己. 我将在下面解释. 原型模式的所有魔力都基于Java ...

  5. 设计模式 原型模式_原型设计模式:创建另一个小车

    设计模式 原型模式 创建对象确实是一个耗时的过程,也是一件昂贵的事情. 因此,我们现在正冒险节省时间和金钱. 我们该怎么做? 克隆奇迹多莉 有人记得多莉吗? 是的,是绵羊,是第一个被克隆的哺乳动物. ...

  6. Java常用设计模式————原型模式(一)

    介绍 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 原型模式用于创建重复的对象,同时又能保证性能.当直接创建对象的代价比较大时,则采用 ...

  7. 第六十六章 Caché 函数大全 $TRANSLATE 函数

    文章目录 第六十六章 Caché 函数大全 $TRANSLATE 函数 大纲 参数 描述 `$TRANSLATE`和`$REPLACE` 示例 第六十六章 Caché 函数大全 $TRANSLATE ...

  8. 第四十六章 Caché 变量大全 ^$GLOBAL 变量

    文章目录 第四十六章 Caché 变量大全 ^$GLOBAL 变量 大纲 参数 描述 进程私有全局变量 参数 nspace global_name 示例 作为`$DATA`的参数 作为`$ORDER` ...

  9. 第六章 Caché 变量大全 $HOROLOG 变量

    文章目录 第六章 Caché 变量大全 $HOROLOG 变量 大纲 描述 分割日期与时间 日期和时间函数比较 日期和时间转换 设定日期和时间 时区 夏令时 本地时变阈值 1840年以前的日期 示例 ...

最新文章

  1. python 安装easy_install和pip
  2. 第 2 章:初出茅庐【初级篇 - 2.1 穷竭搜索】
  3. php中静态方法有什么作用,PHP中的静态方法与非静态方法有什么不同吗?
  4. 使用idea编写SparkStreaming消费kafka中的数据【小案例】(四)
  5. Object to XML
  6. IN与EXISTS优化
  7. Building Web Parts for Microsoft SharePoint Products and Technologies
  8. SqlTransaction事务和Response.Redirect
  9. Android 游戏开发工具包 (AGDK)
  10. VB连接ACCESS数据库
  11. 超越阿里云,华为云服务器究竟有多厉害!
  12. 中国最美滴100首古诗
  13. linux系统Kile+Okular实现逆向搜索
  14. 电脑分区了如何恢复?电脑新手村教程
  15. 计算机应用1.2版,201303《计算机应用基础》在线作1-2.doc
  16. 300题目 第10讲 积分等式与积分不等式
  17. sed删除代码空行和删去行尾空白
  18. package有什么作用
  19. 一键获取LOL英雄联盟所有英雄技能图片
  20. [学习笔记]设计模式[6]-{适配器模式外观模式}

热门文章

  1. 16S rdna 菌种鉴定
  2. 自己动手修相机——解决佳能镜头光圈故障
  3. 什么是畏缩型性格?如何改变畏缩型性格?
  4. github前端插件大全
  5. 精诚EAS-WMS条码化仓库物流软件
  6. zabbix===》微信报警、聚合图形、自动发现自动注册、监控NFS、MySQL、web服务、URL地址
  7. 庞皓计量经济学第四版_庞皓计量经济学第4版配套题库
  8. 赵小楼《天道》《遥远的救世主》深度解析(10)肖亚文对丁元英有没有动过心思?
  9. java微信公众号开发之各种事件推送
  10. 一个男人一天最舒服的地方在地下车库