js构造函数之工厂模式(学习笔记1)

news2025/1/19 14:15:54

目录

一、简单工厂

1、存储一个用户信息

2、存储N个用户信息

3、存储N个用户信息+不同年龄用户有不同美食的搭配方案【简单工厂模式】

二、抽象工厂模式

1、抽象工厂(AbstractFactory)

2、具体工厂(ConcreteFactory)

3、生产新款手机

4、总结


本文是小编阅读《JavaScript 设计模式核心原理与应用实践》这本书,记录的学习笔记,更多详细知识可以直接阅读原文

JavaScript 设计模式核心原理与应用实践——掘金小册icon-default.png?t=N7T8https://juejin.cn/book/6844733790204461070/section/6844733790246404109首要任务:认识哪些是变与不变


一、简单工厂

通过实现用户需求举例

1、存储一个用户信息

// 原始对象
const obj = {
  id:1,
  name:'sxx',
  age:19,
  sex:1
}
console.log(obj);

2、存储N个用户信息

// 简单构造器
class User{
  constructor(id,name,age,sex){
    this.id = id
    this.name = name
    this.age = age
    this.sex = sex
  }
}
// 调用简单构造器
const me = new User(1,'sxx',19,1);
const you = new User(2,'张三',66,0);
console.log(me,you);

在创建一个user过程中,谁变了,谁不变?

很明显,变的是每个user的姓名、年龄这些值,这是用户的个性,不变的是每个员工都具备姓名、年龄、工种这些属性,这是用户的共性

3、存储N个用户信息+不同年龄用户有不同美食的搭配方案【简单工厂模式】

(1)笨方法

// 一个一个构建构造器【笨方法】
class Young{
  constructor(id,name,sex){
    this.id = id
    this.name = name
    this.age = 19
    this.sex = sex
    this.food = ['汉堡','炸鸡','可乐']
  }
}
class Old{
  constructor(id,name,sex){
    this.id = id
    this.name = name
    this.age = 99
    this.sex = sex
    this.food = ['稀饭','青菜','荔枝肉']
  }
}
function Factory(id,name,age,sex){
  switch(age){
    case 19:
      return new Young(id,name,sex)
    case 99:
      return new Old(id,name,sex)
  }
}
const me = Factory(1,'sxx',19,1)
const you = Factory(2,'张三',99,0)
console.log(me,you);

(2)灵活方法

// 观察变与不变【灵活方法】
class User{
  constructor(id,name,age,sex,food){
    this.id = id
    this.name = name
    this.age = age
    this.sex = sex
    this.food = food
  }
}
function Factory(id,name,age,sex){
  let food
  switch(age){
    case 3:
      food = ['奶粉','米糊']
      break
    case 19:
      food = ['汉堡','炸鸡','可乐']
      break
    case 99:
      food = ['稀饭','青菜','荔枝肉']
      break
  }
  return new User(id,name,age,sex,food)
}
console.log(Factory(1,'baby',3,0));
console.log(Factory(2,'sxx',19,1));
console.log(Factory(3,'张三',99,0));


新的需求:

①推出普通、豪华、至尊等套餐,不同年龄用户能够自主选择套餐

②拓展功能:供服务员、厨师、老板等使用

以上需求,每一次都要回去修改 Factory 的函数体,Factory会变得异常庞大——没有遵守开放封闭原则

开放封闭原则:对拓展开放,对修改封闭。软件实体(类、模块、函数)可以扩展,但是不可修改


二、抽象工厂模式

举例:制造智能手机
已知
        ①智能手机的基本组成操作系统和硬件
        ②二者条件兼顾才能实现量产
        ③二者不同的厂商并不知道下一个生产线具体要生产的设计
解决措施
        写一个抽象类,约定某手机的基本组成

1、抽象工厂(AbstractFactory)

class MobilePhoneFactory {
    // 提供操作系统的接口
    createOS(){
        throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
    }
    // 提供硬件的接口
    createHardWare(){
        throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
    }
}

(1)以上类,除了约定手机流水线的通用能力之外,啥也不干。如果让它干点啥,比如 new 一个 MobilePhoneFactory 实例,并尝试调用它的实例方法,它将报错

(2)在抽象工厂模式中,以上类就是食物链顶端最大的Boss

2、具体工厂(ConcreteFactory)

当明确了生产方案:抽象工厂不工作,具体工厂来工作
举例:一个专门生产 Android 系统 + 高通硬件的手机(FakeStar)的生产线

(1)定制一个具体工厂

// 具体工厂继承自抽象工厂
class FakeStarFactory extends MobilePhoneFactory {
    createOS() {
        // 调用AndroidOS()构造函数,提供安卓系统实例
        return new AndroidOS()
    }
    createHardWare() {
        // 调用QualcommHardWare()构造函数,提供高通硬件实例
        return new QualcommHardWare()
    }
}

①两个构造函数:AndroidOS 和 QualcommHardWare,分别用于生成具体的操作系统和硬件实例像这种被用于 new 出具体对象的类,叫做具体产品类(ConcreteProduct)

具体产品类往往不会孤立存在,不同的具体产品类往往有着共同的功能,比如安卓系统类和苹果系统类,它们都是操作系统,都有着可以操控手机硬件系统这样一个最基本的功能

③因此我们可以用一个抽象产品(AbstractProduct)类来声明这一类产品应该具有的基本功能

(2)抽象产品类

// 定义操作系统这类产品的抽象产品类
class OS {
    controlHardWare() {
        throw new Error('抽象产品方法不允许直接调用,你需要将我重写!');
    }
}

// 定义具体操作系统的具体产品类
class AndroidOS extends OS {
    controlHardWare() {
        console.log('我会用安卓的方式去操作硬件')
    }
}

class AppleOS extends OS {
    controlHardWare() {
        console.log('我会用🍎的方式去操作硬件')
    }
}
...

(3)硬件类产品

// 定义手机硬件这类产品的抽象产品类
class HardWare {
    // 手机硬件的共性方法,这里提取了“根据命令运转”这个共性
    operateByOrder() {
        throw new Error('抽象产品方法不允许直接调用,你需要将我重写!');
    }
}

// 定义具体硬件的具体产品类
class QualcommHardWare extends HardWare {
    operateByOrder() {
        console.log('我会用高通的方式去运转')
    }
}

class MiWare extends HardWare {
    operateByOrder() {
        console.log('我会用小米的方式去运转')
    }
}
...

(4)生产一台FakeStar手机

// 这是我的手机
const myPhone = new FakeStarFactory()
// 让它拥有操作系统
const myOS = myPhone.createOS()
// 让它拥有硬件
const myHardWare = myPhone.createHardWare()
// 启动操作系统(输出‘我会用安卓的方式去操作硬件’)
myOS.controlHardWare()
// 唤醒硬件(输出‘我会用高通的方式去运转’)
myHardWare.operateByOrder()

3、生产新款手机

此时我们不需要对抽象工厂MobilePhoneFactory做任何修改,只需要拓展它的种类
这样对原有的系统不会造成任何潜在影响,即“对拓展开放,对修改封闭”

class newStarFactory extends MobilePhoneFactory {
    createOS() {
        // 操作系统实现代码
    }
    createHardWare() {
        // 硬件实现代码
    }
}

4、总结

(1)抽象工厂和简单工厂有哪些异同?

①共同点:尝试去分离一个系统中变与不变的部分
②不同点:场景的复杂度

简单工厂:处理容易抽离的类

    逻辑本身比较简单,故而不苛求代码可扩展性。

抽象工厂:处理非常棘手、繁杂的类

    这些类中不仅能划分出门派,还能划分出等级,同时存在着千变万化的扩展可能性

    这使得我们必须对共性作更特别的处理、使用抽象类去降低扩展的成本,同时需要对类的性质作划分

(2)四个关键角色

  • 抽象工厂(抽象类,不能被用于生成具体实例):  用于声明最终目标产品的共性。在一个系统里,抽象工厂可以有多个(大家可以想象我们的手机厂后来被一个更大的厂收购了,这个厂里除了手机抽象类,还有平板、游戏机抽象类等等),每一个抽象工厂对应的这一类的产品,被称为“产品族
  • 具体工厂(用于生成产品族里的一个具体的产品):  继承自抽象工厂、实现了抽象工厂里声明的那些方法,用于创建具体的产品的类
  • 抽象产品(抽象类,不能被用于生成具体实例):  上面我们看到,具体工厂里实现的接口,会依赖一些类,这些类对应到各种各样的具体的细粒度产品(比如操作系统、硬件等),这些具体产品类的共性各自抽离,便对应到了各自的抽象产品类
  • 具体产品(用于生成产品族里的一个具体的产品所依赖的更细粒度的产品):  比如我们上文中具体的一种操作系统、或具体的一种硬件等

(3)学习注意点

①学会用 ES6 模拟 JAVA 中的抽象类

②了解抽象工厂模式中四个角色的定位与作用

③对“开放封闭原则”形成自己的理解,知道它好在哪,知道执行它的必要性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1215463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

No matching version found for zr-map-ol@1.1.19.

问题描述: 通常情况下直接安装可能还会报错,因为有的依赖包是在私库里的 解决方法: 1.查看模块的注册信息 2. 安装 如果上面这种方式安装之后npm i还是报错,试试下面这种方式(我没有试下面的方式 上面的已经解决掉了) 具体可以参…

医疗器械展示预约小程序的效果如何

医疗器械行业涵盖的内容非常广,市场中大小从业的品牌/门店也很多,比如我们常见的轮椅、康复器械、拐杖、血压仪等产品市场需求都非常高,当然还有医院里用的器械等。 医疗器械市场呈现多品牌、多门店的发展趋势,虽然这些东西不是必…

Rust开发——使用rust实现Redis中hset

一、Redis中hset HSET 是 Redis 中用于在哈希数据结构中设置指定字段的值的命令。哈希是一种类似于字典或映射的数据结构,它存储了键值对的集合,其中每个键都包含多个字段和与这些字段相关联的值。 哈希表在 Redis 中以键值对形式存储,并通…

macos 配置ndk环境

选择Android Studio下默认的ndk环境 mac电脑的ndk默认路径一般是 /Users/user_name/Library/Android/sdk/ndk/version_code 其中user_name为自己电脑的用户名,version_code为自己ndk安装的版本号,比如我这里电脑的ndk路径就是 /Users/zhangsan/Libra…

【用unity实现100个游戏之15】开发一个类保卫萝卜的Unity2D塔防游戏1(附项目源码)

文章目录 先看本次实现的最终效果前言素材一、绘制路径点和连线1. 新建Waypoint ,绘制路径点和连线2. 绘制路径点按钮效果3. 显示路径顺序文本4. 实时修改路径点位置 二、生成敌人1. 固定生成敌人配置2. 随机生成敌人配置 三、对象池创造敌人四、控制敌人沿前面绘制…

计算属性与watch的区别,fetch与axios在vue中的异步请求,单文本组件使用,使用vite创建vue项目,组件的使用方法

7.计算属性 7-1计算属性-有缓存 模板中的表达式虽然很方便,但是只能做简单的逻辑操作,如果在模版中写太多的js逻辑,会使得模板过于臃肿,不利于维护,因此我们推荐使用计算属性来解决复杂的逻辑 <!DOCTYPE html> <html lang"en"> <head><meta …

DP4306F—Sub-1G无线收发通信芯片

DP4306F是一款高性能低功耗的单片集成收发机&#xff0c;工作频率可覆盖200MHz~1000MHz&#xff0c;集成M0核MCU&#xff0c;支持230 / 408 / 433 / 470 / 868 / 915频段。该芯片集成了射频接收器、射频发射器、频 率综合器、GFSK调制器、GFSK解调器等功能模块。通过SPI接口可以…

spark性能调优 | 默认并行度

Spark Sql默认并行度 看官网&#xff0c;默认并行度200 https://spark.apache.org/docs/2.4.5/sql-performance-tuning.html#other-configuration-options 优化 在数仓中 task最好是cpu的两倍或者3倍(最好是倍数&#xff0c;不要使基数) 拓展 在本地 task需要自己设置&a…

LTE信令流程及业务流程

1、Attach过程 完成完成鉴权、身份验证、用户注册以外&#xff0c;包含默认承载的建立 1)在LTE网络中&#xff0c;PDN连接是默认承载的建立&#xff0c;它是在EPS承载中建立的&#xff0c;主要用于在UE和PDN之间传输数据。 2)在建立PDN连接时&#xff0c;会通过EPS隧道连接到PD…

算法笔记-第五章-素数

算法笔记-第五章-素数 素数判断打印素数表c代码c 代码 最大素数最小素数孪生素数 素数判断 //素数 #include <cstdio> #include <cmath>bool isPrime(int n) {if (n < 1) //已知一个素数判断&#xff1a;条件就是n是否能被2&#xff0c;&#xff0c;&#xff0…

ES聚合与分组查询取值参数含义(Java api版本)

一、说明 在项目中使用Elasticsearch的聚合与分组查询后,对于返回结果一脸懵逼,查阅各资料后,自己总结了一下参数取值的含义,不一定全面,只含常见参数 二、分组查询 2.1 参数解释 SearchResponse<Map> searchResponse null;try {searchResponse client.search(s ->…

CentOS中安装常用环境

一、CentOS安装 redis ①&#xff1a;更新yum sudo yum update②&#xff1a;安装 EPEL 存储库 Redis 通常位于 EPEL 存储库中。运行以下命令安装 EPEL 存储库 sudo yum install epel-release③&#xff1a;安装 Redis sudo yum install redis④&#xff1a;启动 Redis 服…

哪种猫罐头比较好?推荐给新手养猫的5款好口碑猫罐头!

新手养猫很容易陷入疯狂购买的模式&#xff0c;但有些品牌真的不能乱买&#xff01;现在的大环境不太好&#xff0c;我们需要学会控制自己的消费欲望&#xff0c;把钱花在刀刃上&#xff01;哪种猫罐头比较好&#xff1f;现在宠物市场真的很内卷&#xff0c;很多品牌都在比拼产…

SOLIDWORKS功能布局实用技巧之保存实体技术

在SOLIDWORKS软件中&#xff0c;有一些命令可以将一个或多个实体保存为独立的零件文件。然而&#xff0c;每个命令都具有不同的特性&#xff0c;有些命令的选项可以让您在保存多个零件时直接生成装配体文件。让我们来深入了解这些功能布局技巧&#xff0c;特别是实体保存技术。…

Moka人事:实现无代码开发的API连接,打通电商平台与用户运营系统

无代码开发的API连接&#xff1a;Moka人事的核心优势 Moka人事&#xff0c;是北京希瑞亚斯科技有限公司于2015年推出的一款数据驱动的智能化HR SaaS产品。这款产品的主要优势在于其无需进行API开发即可实现系统的连接和集成&#xff0c;这不仅大大提升了企业的工作效率&#x…

软件测试/测试开发丨掌握未来,引领人工智能测试新潮流!

点此领取人工智能课程 在数字化革命的浪潮中&#xff0c;人工智能软件成为企业创新和成功的关键推动力。为了在这个竞争激烈的市场中脱颖而出&#xff0c;精湛的人工智能软件测试技能变得至关重要。 ChatGPT应用实战&#xff1a; 学员将深入了解 ChatGPT 的实际应用&#xf…

【BIM入门实战】高程点无法放置的解决方法

文章目录 一、问题提出二、解决办法1. 检查模型图形样式2. 高程点可以放置的图元一、问题提出 在平面图中添加高程点时有时会遇到无法在楼板等平面构件上放置高程点,应如何设置才能使高程点正常放置? 如下图所示,楼板上无法放置高程点: 二、解决办法 1. 检查模型图形样式…

安防监控展示预约小程序的作用如何

监控在生活中的用途非常广泛&#xff0c;普遍应用于小区门户、商业大厦、产业基地、家庭、汽车等场景中&#xff0c;市场需求较大&#xff0c;同时随着科技发展&#xff0c;安防监控产品更新迭代也比较快&#xff0c;衍生出的经销店、安装技术工等产业近些年也比较火。 安防监…

C++初阶(十一)STL简介及string类初讲

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、什么是STL二、STL的版本三、STL的六大组件四、STL的重要性五、如何学习STL六、STL的缺陷七…

NewStarCTF2023 Week3 Reverse方向 题目STL WP

分析 代码不多&#xff0c;逻辑挺清楚的。 先用Z3解出V7&#xff1a; from z3 import *s Solver() v1, v2, v3, v4, v5, v6 BitVecs(v1 v2 v3 v4 v5 v6, 32) v7, v8, v9, v10, v11 BitVecs(v7 v8 v9 v10 v11, 32)s.add((v1 << 15) ^ v1 0x2882D802120E) s.add((v2 …