设计模式之原型模式

1. 定义

对象在创建时通过克隆现有对象而不是通过实例化新对象来创建

2. 口语化举例

克隆,这种方式在生物界太常见了,比如教科书里典型的例子,克隆羊多利:克隆羊_百度百科 (baidu.com)

为什么要克隆?

  • 需要一个新的产品(羊🐏),要和原来的一样,克隆的方式可以直接复刻DNA,甚至都不需要关注DNA信息具体是什么

为什么不采用新建一个产品(羊🐏)的方式?

  • 这方式太复杂了,如何才能新建一只羊,并且还得和原来的羊保持一样,DNA信息难以解读,难以复刻

克隆,这就是典型的原型模式场景

下面的描述会沿用这个上述这个场景

3. 源码示例

Three.js是著名的WebGL库,其源码中几乎每个对象都实现了clone()方法,也就是说,Three.js广泛应用了原型模式

例如,常用的向量对象Vector3,其源码大体如下:

class Vector3 {

	constructor( x = 0, y = 0, z = 0 ) {
		Vector3.prototype.isVector3 = true;
		this.x = x;
		this.y = y;
		this.z = z;
	}

	clone() {
		return new this.constructor( this.x, this.y, this.z );
	}

	copy( v ) {
		this.x = v.x;
		this.y = v.y;
		this.z = v.z;
		return this;
	}
    // ...
}

上述代码,可以看出向量对象Vector3可以使用clone()函数克隆出一个和自己一模一样的新对象

new Vector3()这种方式相比,还得知道原来的Vector3得具体数据是什么,这就显得简单多了

4. 总结

4.1 设计优点

  • 可以克隆对象而无需关注它原来有什么具体信息

  • 可以更方便地生成复杂对象

4.2 适用场景

  • 需要复制一些对象

    基于内存地址引用的代码对象通常需要考虑这个问题,因为在某个地方改变了引用的对象的数据,那么将影响所有使用这个数据的代码

4.3 JavaScript中的原型

JavaScript中的原型与原型模式不一样,JavaScript中的原型是为了实现面向对象的继承

在JavaScript中,每个对象都有一个指向另一个对象的引用,这个对象就是原型

当我们访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript会去查找它的原型对象,如果原型对象中有这个属性或方法,就会返回它的值,这个过程叫原型链

5. 参考资料

[1] 原型设计模式 (refactoringguru.cn)

[2] three.js/src/math/Vector3.js at dev · mrdoob/three.js (github.com)

posted @ 2023-10-28 21:05  当时明月在曾照彩云归  阅读(6)  评论(0编辑  收藏  举报