扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇内容介绍了“Prototype原型模式怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
在于都等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站建设、做网站 网站设计制作按需定制,公司网站建设,企业网站建设,品牌网站制作,营销型网站建设,外贸网站制作,于都网站建设费用合理。
Prototype(原型模式)
Prototype(原型模式)属于创建型模式,既不是工厂也不是直接 New,而是以拷贝的方式创建对象。
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
举例子
如果看不懂上面的意图介绍,没有关系,设计模式需要在日常工作里用起来,结合例子可以加深你的理解,下面我准备了三个例子,让你体会什么场景下会用到这种设计模式。
做钥匙
很显然,为了房屋安全,要尽量做到一把钥匙只能开一扇门,每把钥匙结构都多多少少不一样,却又很相似,做钥匙的人按照你给的钥匙一模一样做一个新的,这属于什么模式呢?
两种状态表
当网站做不停机维护时,假设维护内容是给每个高级会员账户多打 100 元现金,现在需要改数据库表。已知:
数据库表有几千万条数据,其中高级会员有几千位,为了方便调用已经缓存在中间层了,且数据库对应 ID 更新后对应缓存也会更新。
几千条数据修改语句执行完需要几分钟,这几分钟内无法接受用户数据不同步的问题。
一种常见的做法是,我们生成一份高级会员列表的拷贝,代替数据库缓存的结果,数据库只要读到对应会员 ID 就从拷贝列表中获取,数据表新增一列状态标志,操作完后这个拷贝移除,更新高级会员缓存。
但是如何生成高级会员列表拷贝呢?如果直接从几千万条用户数据中重新查询,会有较高的数据库查询成本。
模版组件
通用搭建系统中,我们可以将某个拖拽到页面的区块设置为 “模版”,这个模版可以作为一个新组件被重新拖拽到任意为止,实例化任意次。实际上,这是一种分段式复制粘贴,你会如何实现这个功能呢?
意图解释
解决上面问题的办法都很简单,就是基于已有对象进行复制即可,效率比 New 一个,或者工厂模式都要高。
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
所谓原型实例,就是被选为拷贝模版的那个对象,比如做钥匙例子中,你给老板的样板钥匙;两种状态表中的已有缓存高级会员列表;模版组件中选中的那个组件。然后,通过拷贝这些原型创建你想要的对象即可。
我们抽象思考一下,如果每把钥匙都遵循 Prototype 接口,提供了 clone() 方法以复制自己,那就可以快速复制任意一把钥匙。钥匙工厂可无法解决每把钥匙不一样的问题,我们要的就是和某个钥匙一模一样的副本,复制一份钥匙最简单。
高级会员状态表例子中,查询数据库的成本是高昂的,但如果仅仅复制已经查询好的列表,时间可以忽略不计,因此最经济的方案是直接复制,而不是通过工厂模式重新连接数据库并执行查询。
模版组件更是如此,我们根本没有定义那么多组件实例的基类,只要每个组件提供一个 clone() 函数,就可以立即复制任意组件实例,这无疑是最经济实惠的方案。
看到这里,你应该知道了,原型模式的精髓是对象要提供 clone() 方法,而这个 clone() 方法实现难度有高有低。
一般来说,原型模式的拷贝建议用深拷贝,毕竟新对象最好不要影响到旧对象,但是在深拷贝性能问题较大的情况下,可以考虑深浅拷贝结合,也就是将在新对象中,不会修改的数据使用浅拷贝,可能被修改的数据使用深拷贝。
结构图
Client 是发出指令的客户端,Prototype 是一个接口,描述了一个对象如何克隆自身,比如必须拥有 clone() 方法,而 ConcretePrototype 就是克隆具体的实现,不同对象有不同的实现来拷贝自身。
代码例子
下面例子使用 typescript 编写。
class Component implements Prototype {
/**
* 组件名
*/
private name: string
/**
* 组件版本
*/
private version: string
/**
* 拷贝自身
*/
public clone = () => {
// 构造函数省略了,大概就是传递 name 和 version
return new Component(this.name, this.version)
}
}
我们可以看到,实现了 Prototype 接口的 Component 必须实现 clone 方法,这样任意组件在执行复制时,就可以直接调用 clone 函数,而不用关心每个组件不同的实现方式了。
从这就能看出,原型模式与 Factory 与 Builder 模式还是有类似之处的,在隐藏创建对象细节这一点上。
使用的时候,我们就可以这样创建一个新对象:
const newComponent = oldComponent.clone()
这里有两个注意点:一般来说,如果要二次修改生成的对象,不建议给 clone 函数加参数,因为这样会导致接口的不一致。 我们可以为对象实例提供一些 set 函数进行二次修改。另外,clone 函数要考虑性能,就像前面说过的,可以考虑深浅拷贝结合的方式,同时要注意当对象存在引用关系甚至循环引用时,甚至不一定能实现拷贝函数。
弊端
每个设计模式必有弊端,但就像每一期都说的,有弊端不代表设计模式不好用,而是指在某种场景喜爱存在问题,我们只要规避这些场景,在合理的场景使用对应设计模式即可。
原型模式的弊端:
每个类都要实现 clone 方法,对类的实现是有一定入侵的,要修改已有类时,违背了开闭原则。
当类又调用了其他对象时,如果要实现深拷贝,需要对应对象也实现 clone 方法,整体链路可能会特别长,实现起来比较麻烦。
“Prototype原型模式怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流