第六章 Caché 设计模式 原型模式
文章目录
- 第六章 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é 设计模式 原型模式相关推荐
- 第四章 Caché 设计模式 代理模式
文章目录 第四章 Caché 设计模式 代理模式 定义 类型 使用场景 优点 缺点 结构图 完整示例 抽象主题类 真实主题类 代理类 对象类 调用 思考 第四章 Caché 设计模式 代理模式 定义 ...
- 第二十二章 Caché 设计模式 享元模式
文章目录 第二十二章 Caché 设计模式 享元模式 定义 优点 使用场景 结构图 描述 完整示例 实体类 抽象享元角色 实现享元角色 享元工厂 调用 思考 第二十二章 Caché 设计模式 享元模式 ...
- 设计模式 原型模式_创新设计模式:原型模式
设计模式 原型模式 原型模式用于创建对象的副本. 这种模式非常有用,特别是当从头开始创建对象的成本很高时. 与builder , factory和abstract factory模式相比,它不会从头开 ...
- 设计模式 原型模式_设计模式:原型
设计模式 原型模式 创新设计模式之一是原型设计模式 . 尽管原型是创造模式,但它在概念上与其他模式有所区别. 我的意思是原型在某种意义上创造了自己. 我将在下面解释. 原型模式的所有魔力都基于Java ...
- 设计模式 原型模式_原型设计模式:创建另一个小车
设计模式 原型模式 创建对象确实是一个耗时的过程,也是一件昂贵的事情. 因此,我们现在正冒险节省时间和金钱. 我们该怎么做? 克隆奇迹多莉 有人记得多莉吗? 是的,是绵羊,是第一个被克隆的哺乳动物. ...
- Java常用设计模式————原型模式(一)
介绍 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 原型模式用于创建重复的对象,同时又能保证性能.当直接创建对象的代价比较大时,则采用 ...
- 第六十六章 Caché 函数大全 $TRANSLATE 函数
文章目录 第六十六章 Caché 函数大全 $TRANSLATE 函数 大纲 参数 描述 `$TRANSLATE`和`$REPLACE` 示例 第六十六章 Caché 函数大全 $TRANSLATE ...
- 第四十六章 Caché 变量大全 ^$GLOBAL 变量
文章目录 第四十六章 Caché 变量大全 ^$GLOBAL 变量 大纲 参数 描述 进程私有全局变量 参数 nspace global_name 示例 作为`$DATA`的参数 作为`$ORDER` ...
- 第六章 Caché 变量大全 $HOROLOG 变量
文章目录 第六章 Caché 变量大全 $HOROLOG 变量 大纲 描述 分割日期与时间 日期和时间函数比较 日期和时间转换 设定日期和时间 时区 夏令时 本地时变阈值 1840年以前的日期 示例 ...
最新文章
- python 安装easy_install和pip
- 第 2 章:初出茅庐【初级篇 - 2.1 穷竭搜索】
- php中静态方法有什么作用,PHP中的静态方法与非静态方法有什么不同吗?
- 使用idea编写SparkStreaming消费kafka中的数据【小案例】(四)
- Object to XML
- IN与EXISTS优化
- Building Web Parts for Microsoft SharePoint Products and Technologies
- SqlTransaction事务和Response.Redirect
- Android 游戏开发工具包 (AGDK)
- VB连接ACCESS数据库
- 超越阿里云,华为云服务器究竟有多厉害!
- 中国最美滴100首古诗
- linux系统Kile+Okular实现逆向搜索
- 电脑分区了如何恢复?电脑新手村教程
- 计算机应用1.2版,201303《计算机应用基础》在线作1-2.doc
- 300题目 第10讲 积分等式与积分不等式
- sed删除代码空行和删去行尾空白
- package有什么作用
- 一键获取LOL英雄联盟所有英雄技能图片
- [学习笔记]设计模式[6]-{适配器模式外观模式}