JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代表全部的正确,特此声明。若读者需要了解设计模式目录、原则、设计变化方向,环境相关等信息请查看设计模式开篇。
一、UML类图
参与者:
1.1 Product(Document)
- 定义工厂方法所创建的对象的接口。
1.2 ConcreteProduct(MyDocument)
- 实现Product接口。
1.3 Creator(Application)
- 声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
- 可以调用工厂方法以创建一个Product对象。
1.4 ConcreteCreator(MyApplication)
- 重定义工厂方法以返回一个ConcreteProduct实例。
二、意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method使一个类的实例化延迟到其子类。
三、适用性
- 当一个类不知道它所必须创建的对象的类的时候。
- 当一个类希望由它的子类来指定它所创建的对象的时候
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类 是代理者这一信息局部化的时候
四、示例代码
4.1 动机
框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。考虑这样一个应用框架,它可以向用户显示多个文档。在这个框架中,两个主要的抽象是类Application和Document。这两个类都是抽象的,客户必须通过它们的子类来做与具体应用相关的实现。例如,为创建一个绘图应用,我们定义类DrawingApplication和DrawingDocument。Application类负责管理Document并根据需要创建它们—例如,当用户从菜单中选择Open或New的时候。
因为被实例化的特定Document子类是与特定应用相关的,所以Application类不可能预测到哪个Document子类将被实例化—Application类仅知道一个新的文档何时应被创建,而不知道哪一种Document将被创建。这就产生了一个尴尬的局面:框架必须实例化类,但是它只知道不能被实例化的抽象类。
工厂方法模式提供了一个解决办案。它封装了哪一个Document子类将被创建的信息并将这些信息从该框架中分离出来,如下页上图所示。Application的子类重定义Application的抽象操作CreateDocument以返回适当的Document子类对象。一旦一个Application子类实例化以后,它就可以实例化与应用相关的文档,而无需知道这些文档的类。我们称CreateDocument是一个工厂方法(factorymethod),因为它负责“生产”一个对象。
4.2 示例UML
目录结构:
4.3 Product(Document)
- 定义工厂方法所创建的对象的接口。
export default class Document {
constructor() {
}
Open() {
}
Close() {
}
Save() {
}
Revert() {
}
}
4.4 ConcreteProduct(MyDocument)
- 实现Product接口。
import Document from '../Document.js';
export default class MyDocument extends Document {
constructor() {
super();
}
Open() {
console.log(` MyDocument Open `);
}
Close() {
console.log(` MyDocument Close `);
}
Save() {
console.log(` MyDocument Save `);
}
Revert() {
console.log(` MyDocument Revert `);
}
}
import Document from '../Document.js';
export default class WordDocument extends Document {
constructor() {
super();
}
Open() {
console.log(` WordDocument Open `);
}
Close() {
console.log(` WordDocument Close `);
}
Save() {
console.log(` WordDocument Save `);
}
Revert() {
console.log(` WordDocument Revert `);
}
}
4.5 Creator(Application)
- 声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
- 可以调用工厂方法以创建一个Product对象
import Document from '../Document/Document.js';
export default class Application {
#docs=[];
constructor() {
}
CreateDocument() {
console.log(` Application CreateDocument `);
}
NewDocument() {
console.log(` Application NewDocument `);
let doc=this.CreateDocument();//Document
this.#docs.push(doc);
doc.Open();
return doc;
}
OpenDocument() {
console.log(` Application OpenDocument `);
}
}
4.6 ConcreteCreator(MyApplication)
- 重定义工厂方法以返回一个ConcreteProduct实例。
import Application from '../Application.js';
import MyDocument from '../../Document/impl/MyDocument.js';
export default class MyApplication extends Application {
constructor() {
super();
}
CreateDocument() {
let myDoc=new MyDocument();
console.log(` MyApplication CreateDocument `);
return myDoc;
}
}
import Application from '../Application.js';
import WordDocument from '../../Document/impl/WordDocument.js';
export default class WordApplication extends Application {
constructor() {
super();
}
CreateDocument() {
let wordDoc=new WordDocument();
console.log(` MyApplication CreateDocument `);
return wordDoc;
}
}
4.7 Client
import MyApplication from './Application/impl/MyApplication.js';
import WordApplication from './Application/impl/WordApplication.js';
import Document from './Document/Document.js';
export default class Client{
main(){
let application =new MyApplication();//Application
let doc=application.NewDocument();//Document
doc.Close();
let wordapplication =new WordApplication();//Application
let word=wordapplication.NewDocument();//Document
word.Close();
}
}
4.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>
测试结果:
Application.js:11 Application NewDocument
MyApplication.js:11 MyApplication CreateDocument
MyDocument.js:8 MyDocument Open
MyDocument.js:11 MyDocument Close
Application.js:11 Application NewDocument
WordApplication.js:10 MyApplication CreateDocument
WordDocument.js:8 WordDocument Open
WordDocument.js:11 WordDocument Close
五、源代码下载
下载链接:https://pan.baidu.com/s/1XuPqp84cccBNVkbnMY3sKw
提取码:q2ut