设计模式(6)[JS版]-JavaScript如何实现抽象工厂模式?
1 学习目标
通过本篇文章的学习,你应当掌握以下知识: 1 知道什么是抽象工厂模式? 2 掌握抽象工厂模式的作用以及什么时候需要使用抽象工厂模式 3 掌握使用JS实现抽象工厂模式的代码编写。
2 什么是抽象工厂模式?
抽象工厂模式提供了一种封装一组具有相同主题的单个工厂而无需指定其具体类的方法。即工厂的工厂;一个将单个相关/从属工厂分组在一起的工厂,但未指定其具体类别。
一个抽象工厂创建了由一个共同主题相关的对象。在面向对象的编程中,工厂是一个创建其他对象的对象。一个抽象工厂已经抽象出了一个主题,这个主题被新创建的对象所共享。
你可能会奇怪为什么要把构造对象的责任交给别人,而不是直接用new关键字调用构造函数。原因是,构造函数对整个创建过程的控制是有限的,有时你需要把控制权交给一个拥有更广泛知识的工厂。
这包括创建过程中涉及对象缓存、对象共享或重用、复杂逻辑、或维护对象和类型计数的应用程序、以及与不同资源或设备交互的对象等场景。如果您的应用程序需要对对象创建过程进行更多控制,请考虑使用抽象工厂模式。
3 抽象工厂模式作用
当存在相互关联的依赖关系且涉及非简单创建逻辑时,建议使用抽象工厂模式。
通常在以下情况下考虑使用抽象工厂模式:
- 一个系统应该独立于其产品的创建,组成和表示方式
- 系统应配置有多个产品系列之一
- 一个相关产品对象系列旨在一起使用,因此您需要强制执行此约束
- 您想要提供产品的类库,并且只想显示它们的接口,而不是它们的实现
- 从概念上讲,依赖项的生存期短于消费者的生存期。
- 您需要一个运行时值来构建特定的依赖关系
- 您想决定在运行时从系列中调用哪种产品。
- 您需要提供一个或多个仅在运行时才知道的参数,然后才能解决依赖关系。
- 当您需要产品之间的一致性时
- 在将新产品或产品系列添加到程序时,您不想更改现有代码。
4 抽象工厂模式参与者
抽象工厂模式参与者主要有:
AbstractFactory:
1 声明产品的接口
2 在JavaScript中不使用
ConcreteFactory:
1 工厂对象
2 create()方法返回新产品
产品 :
1 工厂创建的产品实例
AbstractProduct:
1 在JavaScript中没有使用
2 声明要创建的产品的接口
5 代码实现
因为JavaScript不支持基于类的继承,因此,在下面的JavaScript代码中未使用图中所示的抽象类。抽象类和接口在派生类中的作用是强制使用一致的接口。因此在JavaScript中,我们必须确保每个“ Concrete”对象与其他对象具有相同的接口定义(即属性和方法),以确保自身的一致性。
在下面的代码示例中,我们创建了两个具体的工厂:EmployeeFactory和VendorFactory。EmployeeFactory用于创建Employee的实例,VendorFactory用于创建Vendor的实例。两种产品都可以看做是人员类型(具有相同的接口),所以客户可以将它们看做是相同。在run函数中,我们通过不同的工厂创建了两个员工和两个供应商,它们存储在同一个数组中。每个员工或供应商都要说出他们的名字和类型。日志函数用来收集和显示结果。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS抽象工厂模式:微信公众号AlbertYang</title>
</head>
<body>
</body>
<script>
//员工类
function Employee(name) {
this.name = name;
this.say = function() {
log.add("我是员工:" + name);
};
}
//员工工厂
function EmployeeFactory() {
this.create = function(name) {
return new Employee(name);
};
}
//供应商类
function Vendor(name) {
this.name = name;
this.say = function() {
log.add("我是供应商:" + name);
};
}
//供应商工厂
function VendorFactory() {
this.create = function(name) {
return new Vendor(name);
};
}
// 日志函数
var log = (function() {
var log = "";
return {
add: function(msg) {
log += msg + "n";
},
show: function() {
console.info("%c%s", "color: red; background: #b4b3b3; font-size: 20px", log);
log = "";
}
}
})();
function run() {
var persons = [];
var employeeFactory = new EmployeeFactory();
var vendorFactory = new VendorFactory();
persons.push(employeeFactory.create("张三"));
persons.push(employeeFactory.create("李四"));
persons.push(vendorFactory.create("王麻子"));
persons.push(vendorFactory.create("赵六"));
for (var i = 0, len = persons.length; i < len; i++) {
persons[i].say();
}
log.show();
}
run();
</script>
</html>
今天的学习就到这里,你可以使用今天学习的技巧来改善一下你曾经的代码,如果想继续提高,欢迎关注我,每天学习进步一点点,就是领先的开始。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【原创】经验分享:一个小小emoji尽然牵扯出来这么多东西?
- jQuery 事件对象,拷贝对象,多库共存
- jQuery 事件注册与事件处理
- v-charts 修改文本颜色
- 使用 jsDelivr 免费加速 GitHub Pages 博客的静态资源(二)
- 竞赛比完,代码、模型怎么处理?Kaggle大神:别删,这都是宝藏
- 显示DataGrid序号的一个适用的方法
- SAP Spartacus cms-components.service.ts里的config.cmsComponents
- ng-template和ng-container的嵌套使用
- SAP Spartacus pageSlot一览
- Angular @Hostbinding工作原理
- Python干货 | 遥感影像拼接
- SAP Spartacus 自定义指令的实现以及通过@HostBinding实现属性绑定
- Python气象绘图教程—(十九)剖面图
- Angular DefaultDomRenderer2.setProperty