javaScript设计模式原理学习记录(一)

161 阅读3分钟

一、何为设计模式

设计模式背景:软件设计多变化

核心思想:封装变化(将变与不变分离,确保变化的部分灵活,不变的部分不变),将变化单独提取出来封装。

每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。 —— Christopher Alexander

三种设计模型:创建型,结构型,行为型

二,工厂模式

工厂模式的概念:将创建对象的过程单独封装

我们采用了 ES5 构造函数的写法,因为 ES6 中的 class 其实本质上还是函数,class 语法只是语法糖,构造函数,才是它的真面目。

构造器和工厂模式?
构造器:本质上去抽象了每个实例的变与不变。
工厂模式:去抽象了各个函数(类)变与不变。

/**
 *  工厂模式:将创建对象的过程单独封装,通过new对象,传参
 *  属与:创建型
 *  构造器:User
 *  解决:构造器解决的是多个类的问题,简单工厂解决的是多个类的问题
 * @param {*} name 
 * @param {*} age 
 * @param {*} career 
 * @param {*} work 
 */

function User(name, age, career,work){
    this.name = name;
    this.age = age;
    this.career = career;
    this.work = work;
}

function careerFn(name, age, career){
    let work;
    switch(career){
        case "coder":
            work = ['写代码','写系分', '修Bug'] 
            break;
        case "productManage":
            work = ['订会议室', '写PRD', '催更']
            break;
        default:
            ''
    }

    return new User(name,age,career,work)
}

let userCoder = new careerFn('张三','22','coder');
let userProductManage = new careerFn('李四','33','productManage')
console.log(userCoder)
console.log(userProductManage)

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

三、抽象类工厂

抽象类工厂:定义是围绕超级工厂创建其他工厂

抽象工厂=>具体工厂=>抽象产品=>具体产品

/**
 * 创建手机抽象工厂
 * 抽象工厂-> 具体工厂
 */
class MobilePhoneFactory {
  // 提供操作系统的接口
  createOS() {
    throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
  }
  // 提供硬件的接口
  createHardWare() {
    throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
  }
}
//具体工厂继承自抽象工厂
class FakeStarFactory extends MobilePhoneFactory{
    createOS(){
        //提供安卓系统实例
        return new AndroidOS()
    }
    createHardWare(){
        // 提供高通硬件实例
        return new QualcommHardWare()
    }
}

/**
 * 创建系统抽象工厂
 */
class OS {
    controlHardWare(){
        throw new Error('抽象产品方法不允许直接调用,你需要将我重写!');
    }
}
// 定义具体操作系统的具体产品类
class AndroidOS extends OS {
    controlHardWare() {
        console.log('我会用安卓的方式去操作硬件')
    }
}
class AppleOS extends OS {
    controlHardWare() {
        console.log('我会用🍎的方式去操作硬件')
    }
}

/**
 * 创建硬件抽象工厂
 */
class HardWare {
    // 手机硬件的共性方法,这里提取了“根据命令运转”这个共性
    operateByOrder() {
        throw new Error('抽象产品方法不允许直接调用,你需要将我重写!');
    }
}
// 定义具体硬件的具体产品类
class QualcommHardWare extends HardWare {
    operateByOrder() {
        console.log('我会用高通的方式去运转')
    }
}
class MiWare extends HardWare {
    operateByOrder() {
        console.log('我会用小米的方式去运转')
    }
}

/**
 *  生产手机
 */
const myPhone = new FakeStarFactory()
const myOs = myPhone.createOS()
const myHardWare = myPhone.createHardWare()
myOs.controlHardWare()
myHardWare.operateByOrder()

//FakeStar过时,可以:
class newStarFactory extends MobilePhoneFactory {
    createOS() {
        // 操作系统实现代码
    }
    createHardWare() {
        // 硬件实现代码
    }
}

好处:FakeStar过时,可以重新生产,而不需要改变内部。

  • 抽象工厂(抽象类,它不能被用于生成具体实例)

  • 具体工厂(用于生成产品族里的一个具体的产品)

  • 抽象产品(抽象类,它不能被用于生成具体实例)

  • 具体产品(用于生成产品族里的一个具体的产品所依赖的更细粒度的产品)