首页 > 编程语言 >【JS】165-JavaScript设计模式——工厂模式

【JS】165-JavaScript设计模式——工厂模式

时间:2022-11-28 14:01:30浏览次数:35  
标签:function Object 对象 JavaScript JS let 设计模式 CarMaker 构造函数

二、工厂模式(Factory Pattern)

1.概念介绍

工厂模式的目的在于创建对象,实现下列目标:

  • 可重复执行,来创建相似对象;
  • 当编译时位置具体类型(类)时,为调用者提供一种创建对象的接口;

通过工厂方法(或类)创建的对象,都继承父对象,下面一个简单工厂方法理解:

  1. ​function Person(name, age, sex){​
  2. ​ let p = {}; // 或 let p = new Object(); 创建一个初始对象​
  3. ​ p.name = name;​
  4. ​ p.age = age;​
  5. ​ p.sex = sex;​
  6. ​ p.ask = function(){​
  7. ​ return 'my name is' + this.name;​
  8. ​ }​
  9. ​ return p;​
  10. ​}​
  11. ​let leo = new Person('leo', 18, 'boy');​
  12. ​let pingan = new Person('pingan', 18, 'boy');​
  13. ​console.log(leo.name, leo.age, leo.sex); // 'leo', 18, 'boy'​
  14. ​console.log(pingan.name, pingan.age, pingan.sex); // 'pingan', 18, 'boy'​

通过调用 ​​Person​​​构造函数,我们可以像工厂那样,生产出无数个包含三个属性和一个方法的对象。
可以看出,工厂模式可以解决创建多个类似对象的问题。

2.优缺点

2.1优点

  • 一个调用者想创建一个对象,只要知道其名称就可以了。
  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

2.2缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

3.实现复杂工厂模式

在复杂工厂模式中,我们将其成员对象的实列化推迟到子类中,子类可以重写父类接口方法以便创建的时候指定自己的对象类型。
父类类似一个公共函数,只处理创建过程中的问题,并且这些处理将被子类继承,然后在子类实现专门功能。

比如这里我们需要实现这么一个实例:

  • 需要一个公共父函数 ​​CarMaker​​;
  • 父函数 ​​CarMaker​​​有个 ​​factor​​静态方法,用于创建 ​​car​​对象;
  • 定义三个静态属性,值为三个函数,用于继承父函数 ​​CarMaker​​;

然后我们希望这么使用这个函数:

  1. ​let c1 = CarMaker.factory('Car1');​
  2. ​let c2 = CarMaker.factory('Car2');​
  3. ​let c3 = CarMaker.factory('Car3');​
  4. ​c1.drirve(); // '我的编号是6'​
  5. ​c2.drirve(); // '我的编号是3'​
  6. ​c3.drirve(); // '我的编号是12'​

可以看出,调用时接收以字符串形式指定类型,并返回请求类型的对象,并且这样使用是不需要用 ​​new​​操作符。

下面看代码实现:

  1. ​// 创建父构造函数​
  2. ​function CarMaker(){};​
  3. ​CarMaker.prototype.drive = function(){​
  4. ​ return `我的编号是${this.id}`;​
  5. ​}​
  6. ​// 添加静态工厂方法​
  7. ​CarMaker.factory = function (type){​
  8. ​ let types = type, newcar;​
  9. ​ // 若构造函数不存在 则发生错误​
  10. ​ if(typeof CarMaker[types] !== 'function'){​
  11. ​ throw{ name: 'Error', message: `${types}不存在`};​
  12. ​ }​
  13. ​ // 若构造函数存在,则让原型继承父类,但仅继承一次​
  14. ​ if(CarMaker[types].prototype.drive !== 'function'){​
  15. ​ CarMaker[types].prototype = new CarMaker();​
  16. ​ }​
  17. ​ // 创建新实例,并返回​
  18. ​ newcar = new CarMaker[types]();​
  19. ​ return newcar;​
  20. ​}​
  21. ​// 调用​
  22. ​CarMaker.c1 = function(){​
  23. ​ this.id = 6;​
  24. ​}​
  25. ​CarMaker.c2 = function(){​
  26. ​ this.id = 3;​
  27. ​}​
  28. ​CarMaker.c3 = function(){​
  29. ​ this.id = 12;​
  30. ​}​

定义完成后,我们再执行前面的代码:

  1. ​let c1 = CarMaker.factory('Car1');​
  2. ​let c2 = CarMaker.factory('Car2');​
  3. ​let c3 = CarMaker.factory('Car3');​
  4. ​c1.drirve(); // '我的编号是6'​
  5. ​c2.drirve(); // '我的编号是3'​
  6. ​c3.drirve(); // '我的编号是12'​

就能正常打印结果了。

实现该工厂模式并不困难,主要是要找到能够穿件所需类型对象的构造函数。
这里使用简单的映射来创建该对象的构造函数。

4.内置对象工厂

内置的对象工厂,就像全局的 ​​Object()​​​构造函数,也是工厂模式的行为,根据输入类型创建不同对象。
如传入一个原始数字,返回一个 ​​​Number()​​​构造函数创建一个对象,传入一个字符串或布尔值也成立。
对于传入任何其他值,包括无输入的值,都会创建一个常规的对象。

无论是否使用 ​​new​​​操作符,都可以调用 ​​Object()​​,我们这么测试:

  1. ​let a = new Object(), b = new Object(1),​
  2. ​ c = Object('1'), d = Object(true);​

  3. ​a.constructor === Object; // true ​
  4. ​b.constructor === Number; // true ​
  5. ​c.constructor === String; // true ​
  6. ​d.constructor === Boolean; // true ​

事实上, ​​Object()​​用途不大,这里列出来是因为它是我们比较常见的工厂模式。

参考资料

  1. 《JavaScript Patterns》

【JS】165-JavaScript设计模式——工厂模式_子类


标签:function,Object,对象,JavaScript,JS,let,设计模式,CarMaker,构造函数
From: https://blog.51cto.com/u_11887782/5891098

相关文章

  • 【JS】164-JavaScript设计模式——单体模式
    一、单体模式(SingletonPattern)1.概念介绍单体模式(SingletonPattern)的思想在于保证一个特定类仅有一个实例,即不管使用这个类创建多少个新对象,都会得到与第一次创建的对......
  • 【正则】223-JS常用正则表达式备忘录
    ​翻译自RegexCheatSheet(https://dev.to/emmawedekind/regex-cheat-sheet-2j2a)翻译:前端小智整理编辑:SegmentFault正则表达式或“regex”用于匹配字符串的各个部分,下面是作......
  • JavaWeb项目实战一(Servlet+Jsp项目项目搭建及登录界面)
    之前JavaWeb学的不是太好,准备从下边列的三个发展阶段,每个阶段以项目形式去补充基础JavaWeb发展阶段:Servlet+JspSSM:SpringMVC+Spring+MyBatis其实在中间阶段还存在......
  • EF Core | Passing navigation properties in JSON body to API controller as POST r
    EFCore|PassingnavigationpropertiesinJSONbodytoAPIcontrollerasPOSTrequestHere'stheofficialdocsonavoidinggraphcyclesinJSON:learn.micros......
  • day33- js基础语法
    字符串正常字符串使用单双引号包裹转义字符\'\n\t\u4e2d(\u####)unicode字符Ascll字符多行字符串``tab键上面的``包含多行字符模板字符串需要使......
  • JS中的变量提升与函数提升
    一段JS代码在执行的时候,大致可以分为两步。第一步为对代码的编译阶段,第二步才是真正去执行各语句。代码中用关键字var的变量声明和函数声明(非函数表达式)会在编译阶段提升到......
  • 12个有用的JavaScript数组技巧
    数组是Javascript最常见的概念之一,它为我们提供了处理数据的许多可能性,熟悉数组的一些常用操作是很有必要的。1、数组去重1、from()叠加newSet()方法字符串或数值型数......
  • Selenium4+Python3系列(十) - Page Object设计模式
    前言PageObject(PO)模式,是Selenium实战中最为流行,并且被自动化测试同学所熟悉和推崇的一种设计模式之一。在设计测试时,把页面元素定位和元素操作方法按照页面抽象出来,分离成......
  • Python 爬取单个网页所需要加载的URL地址和CSS、JS文件地址
    直接上代码:脱敏后自用的py采集代码,#!/usr/bin/envpython#-*-coding:utf-8-*-"""@author:Andy@file:xxx.py@time:下午05:50@desc:采集的文章数据进博客"""im......
  • 设计模式之命令模式
    概述在软件开发中,经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,此时,特别希望能够以一种松耦合的方式来设......