JavaScript 设计模式 (二) 工厂方法模式 Factory method pattern

岑眰
• 阅读 2286

前言

第一篇是读书笔记,本篇开始的具体设计模式会参考维基百科对于二十三种著名GoF设计模式的解释

有理解不到位的,或者错误的地方欢迎在文章下方留言

定义

定义:一个用于创建对象的接口,但是让子类决定实例化哪个类。工厂方法允许一个类延迟实例化它使用的子类。

示例

在创建类时经常遇到需要创建类似的但不完全一样的实例,比如创建一个类表示键盘

class Keyboard {
  constructor(properties) {
    this.brand = properties.brand
  }
}

class MechanicalKeyboard extends Keyboard {
  constructor(properties) {
    super(properties)
  }
}

个人理解

首先 Factory method pattern(工厂方法模式) 不等于 Factory function(工厂函数);

Factory function(工厂函数)

  • Factory function(工厂函数)的作用是返回一个对象。它可能是创建类的替代方法。
  • 在 JavaScript 没有 class 的概念时,大家都是用函数去模拟 class,但是这只是对于工厂方法模式的应用,并不是工厂方法模式本身
  • 注:设计模式是可复用的解决方案,并不是具体应用

例如:


// 创建
const People = ({ // 姓名
  lastName, // 姓
  firstName // 名
}) => ({
  lastName,
  firstName
})
 
const createProgrammer = ({ // 程序员
  lastName, // 姓
  firstName // 名
  programmingLanguage // 编程语言
}) => ({
  ...People({ firstName, lastName }),
  programmingLanguage
})
 
const createDriver = ({ // 司机
  lastName, // 姓
  firstName // 名
  driverLicense // 驾驶证
}) => ({
  ...People({ firstName, lastName }),
  driverLicense
})

// 使用
const programmer = createProgrammer({
  firstName: '耿',
  lastName: '司机',
  programmingLanguage: 'JavaScript'
})
 
const driver = createDriver({
  firstName: '王',
  lastName: '大厨',
  driverLicense: 'A1'
})

Factory method pattern(工厂方法模式)

关于工厂方法模式的定义我找了几个关键词:

  • 创建对象的接口
  • 允许类延迟实例化它使用的子类

那我们可以把创建对象时用到的一些类看做网站数据库里的数据,
而工厂方法模式的实例就是后台给我们的一个数据接口,
我们传进去一些参数(要什么对象),后台返回一些数据(创建的对象),
而我们不需要知道这些数据到底怎么被查出来的(具体如何实现),
放在了哪里(具体如何定义),
而且在调用接口前并不需要去做查询操作(用到后才实例化)

流程图

JavaScript 设计模式 (二) 工厂方法模式 Factory method pattern

部分代码示例

ES6
class People {
  // 基础人模板
  name = "基础人模板";
  constructor(props) {
    this.name = props.name;
  }
}
class Programmer extends People {
  // 程序员
  programmingLanguage = "JavaScript";
  constructor(props) {
    super(props);
    this.programmingLanguage = props.programmingLanguage;
  }
}
class Driver extends People {
  // 司机
  driverLicense = "无证老司机";
  constructor(props) {
    super(props);
    this.driverLicense = props.driverLicense;
  }
}

class Chef extends People {
  // 厨师
  cookCard = "无证";
  constructor(props) {
    super(props);
    this.cookCard = props.cookCard;
  }
}


class PeopleFactory {
  public static createProgrammer(props) {
    return new Programmer(props);
  }
  public static createDriver(props) {
    return new Driver(props);
  }
  public static createChef(props) {
    return new Chef(props);
  }
}

const unlicensedDriver = PeopleFactory.createDriver({
  name: "老司机",
  driverLicense: "A1"
});
console.log(unlicensedDriver);
typescript
interface PeopleProps {
  // 基础人接口
  name: string;
}
interface ProgrammerProps extends PeopleProps {
  // 程序员接口
  programmingLanguage: string;
}
interface DriverProps extends PeopleProps {
  // 司机接口
  driverLicense: string;
}
interface ChefProps extends PeopleProps {
  // 厨师接口
  cookCard: string;
}

class People {
  // 基础人模板
  name: string = "基础人模板";
  constructor(props: PeopleProps) {
    this.name = props.name;
  }
}

class Programmer extends People {
  // 程序员
  programmingLanguage: string = "JavaScript";
  constructor(props: ProgrammerProps) {
    super(props);
    this.programmingLanguage = props.programmingLanguage;
  }
}
class Driver extends People {
  // 司机
  driverLicense: string = "无证老司机";
  constructor(props: DriverProps) {
    super(props);
    this.driverLicense = props.driverLicense;
  }
}

class Chef extends People {
  // 厨师
  cookCard: string = "无证";
  constructor(props: ChefProps) {
    super(props);
    this.cookCard = props.cookCard;
  }
}


class PeopleFactory {
  public static createProgrammer(
    props: ProgrammerProps
  ): Programmer {
    return new Programmer(props);
  }
  public static createDriver(
    props: DriverProps
  ): Driver {
    return new Driver(props);
  }
  public static createChef(props: ChefProps): Chef {
    return new Chef(props);
  }
}

const unlicensedDriver = PeopleFactory.createDriver({
  name: "老司机",
  driverLicense: "A1"
});
console.log(unlicensedDriver);

个人理解适用场景

  • 在团队中协作开发时,知道要创建很多相似不相同的类,但是暂时不知道所有的具体类是什么样子的,可以使用这个模式,等需要添加时直接在工厂类代码中添加静态方法,返回新的对象即可,这样可以方便代码的拓展与修改
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
红烧土豆泥 红烧土豆泥
4年前
软件设计模式-创建型模式之工厂进阶版
简介:所谓工厂模式,创建一个对象的接口,让子类决定实例化哪一个工厂类,使其创建过程延迟到了子类。所谓的万能工厂类,通过反射调用的方式,获取到子类对象,并实例化返回,此外本案例还通过重载的方式,允许了有参和无参两种获取到实例的方式。language/@author:demo@date:2021/8/7@describe:/public
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
Unity C# 设计模式(二)简单工厂模式
定义:简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactoryMethod)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该
Wesley13 Wesley13
3年前
C#设计模式 —— 工厂模式
。  工厂模式同样是项目中最常用的设计模式,工厂模式中又分为简单工厂,工厂方法,抽象工厂。下面我们由简单的开始逐一介绍。1.简单工厂模式  简单工厂又被称为静态工厂,在设计模式中属于创建型模式。主要解决的问题是封装了实例化的过程,通过传入参数来获不同实例。下面我们举一个项目中可能会用到的例子。  假设我们程序的数据保存在几个不同
Wesley13 Wesley13
3年前
00_设计模式之语言选择
设计模式之语言选择设计模式简介背景设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式(Designpattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的
Wesley13 Wesley13
3年前
Java设计模式
模式描述工厂方法模式提供一个用于创建产品的接口,由实现类决定实现哪些产品。工厂方法模式使一个类的实例化延迟到子类,并且只适用于一个产品的等级结构。优点可以一定程度上解耦,消费者和产品实现类隔离开,只依赖产品接口(抽象产品),产品实现类如何改动与消费者完全无关。例子还是以之前简单工厂的手机为案例:/
Wesley13 Wesley13
3年前
23种设计模式(面向对象语言)
一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。所有的创建型模式都有两个主要功能:  1.将系统所使用的具体类的信息封装起来  2.隐藏