JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代表全部的正确,特此声明。若读者需要了解设计模式目录、原则、设计变化方向,环境相关等信息请查看设计模式开篇。
一、UML类图
参与者:
1.1 Prototype(Graphic)
- 声明一个克隆自身的接口。
1.2 ConcretePrototype(Staff、WholeNote、HalfNote)
- 实现一个克隆自身的操作。
1.3 Client(GraphicTool)
- 让一个原型克隆自身从而创建一个新的对象。
二、意图
用原型实例指定创建对象,并且通过拷贝这些原型创建新的对象。从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
三、适用性
当一个系统应该独立于它的产品创建、构成和表示时,要使用 Prototype模式;
- 当要实例化的类是在运行时刻指定时,例如,通过动态装载;。
- 为了避免创建一个与产品类层次平行的工厂类层次时
- 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
四、优点和缺点
4.1 优点
- 隐藏了对象创建的细节,大大提升了性能。不用重新初始化对象,而是动态的获得对象运行时的状态。
4.2 缺点
- 深复制 or 浅复制 。
五、示例代码
5.1 动机
比如你想构建一个拥有通用架构的音乐编辑器 ,该编辑器架构可以图形编辑,也可以增加一些表示音符、休止符和五线谱的新对象。这个编辑器框架可能有一个工具选择板用于将这些音乐对象加到乐谱中。这个选择板可能还包括选择、移动和其他操纵音乐对象的工具。用户可以点击四分音符并使用它将四分音符加到乐谱中。或者他们可以使用在五线谱上上下移动一个音符,从而改变它的音调。
我们假定该框架为音符和五线谱这样的图形构件提供了一个抽象的Graphics类。此外,为定义选择板中的那些工具,还提供一个抽象类Tool。该框架还为一些创建图形对象实例并将它们加入到文档中的工具预定义了一个GraphicTool子类(The framework also predefines a GraphicTool subclass for tools that create instances of graphical objects and add them to the document.)。
但GraphicTool给框架设计者带来一个问题。音符和五线谱的类特定于我们的应用,而GraphicTool类却属于框架。GraphicTool不知道如何创建我们的音乐类的实例,并将它们添加到乐谱中。我们可以为每一种音乐对象创建一个GraphicTool的子类,但这样会产生大量的子类,这些子类仅仅在它们所初始化的音乐对象的类别上有所不同。我们知道对象复合object composition是比创建子类更灵活的一种选择。问题是,该框架怎么样用它来参数化GraphicTool的实例,而这些实例是由Graphic类所支持创建的(The question is, how can the framework use it to parameterize instances of GraphicTool by the class of Graphic they're supposed to create? )。
解决办法是让GraphicTool通过拷贝或者“克隆”一个Graphic子类的实例来创建新的Graphic,我们称这个实例为一个原型。GraphicTool将它应该克隆和添加到文档中的原型作为参数(GraphicTool is parameterized by the prototype it should clone and add to the document. )。如果所有Graphic子类都支持一个Clone操作,那么GraphicTool可以克隆所有种类的Graphic。
5.2 示例UML
目录结构:
5.3 Prototype(Graphic)
- 声明一个克隆自身的接口。
export default class Graphic {
constructor() {
}
Draw(position) {
console.log(` 非重点 `);
}
Clone() {
console.log(` 重点 `);
}
}
5.4 ConcretePrototype(Staff、WholeNote、HalfNote)
- 实现一个克隆自身的操作。
import Graphic from '../Graphic.js';
export default class Staff extends Graphic {
#oneAtti=0;
#anotherAtti=0;
constructor() {
super();
}
Clone() {
let newCopy=new Staff(); //copy 的深度,
newCopy.#oneAtti=this.#oneAtti;
newCopy.#anotherAtti=2;
return newCopy;
}
}
5.5 Client(GraphicTool)
- 让一个原型克隆自身从而创建一个新的对象。
5.6 Client
import Staff from './Graphic/impl/Staff.js';
import Graphic from './Graphic/Graphic.js';
export default class Client{
main(){
let staff =new Staff();//Graphic
let copystaff=staff.Clone();
console.log(` aaaaaaaa `);
}
}
5.8 测试HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="module" >
import Client from './Client.js';
let cl=new Client();
cl.main()
</script>
</head>
<body>
</body>
</html>
测试结果:
六、源代码下载
下载链接:https://pan.baidu.com/s/1XuPqp84cccBNVkbnMY3sKw
提取码:q2ut