设计模式 ~ 工厂模式

工厂模式

工厂模式是一种设计模式,指在通过使用工厂函数或构造函数来创建对象;
它提供了一种灵活的方式来创建对象实例,而无需直接调用构造函数或使用new关键字;
可以分类,解耦;
可以扩展多个类(派生类、平行类等);
创建逻辑也可以自由扩展;


下面是一个使用工厂函数实现工厂模式的示例:

interface IProduct {
  name: string
  fn1: () => void
  fn2: () => void
}

class Product1 implements IProduct {
  name: string
  constructor(name: string) {
    this.name = name
  }
  fn1() {
    alert('product1 fn1')
  }
  fn2() {
    alert('product1 fn2')
  }
}

class Product2 implements IProduct {
  name: string
  constructor(name: string) {
    this.name = name
  }
  fn1() {
    alert('product2 fn1')
  }
  fn2() {
    alert('product2 fn2')
  }
}

工厂函数: create
为何没有返回 class 而是一个接口,因为依赖倒置原则,即任何一个 class 实现接口即可

class Creators {
  create(type: string, name: string): IProduct {
    if (type === 'p1') {
      return new Product1(name)
    }
    if (type === 'p2') {
      return new Product2(name)
    }
    throw new Error('Invalid type')
  }
}

使用工厂函数创建实例:

const creator = new Creator()
const p1 = creator.create('p1')
const p2 = creator.create('p2')
const p3 = creator.create('p3')

UML 类图演示:
设计模式 ~ 工厂模式_第1张图片


JQuery

工厂模式 JQuery 原理:

class JQuery {
  selector: string // 选择器
  length: number
  constructor(selector: string) {
    const domList = Array.from(document.querySelectorAll(selector)) // DOM元素
    const length = domList.length // 元素集合长度
    for (let i = 0; i < length; i++) {
      this[i] = domList[i]
    }
    this.selector = selector
    this.length = length
  }
  append(elem: HTMLElement): JQuery {
    // append 的操作...
    return this
  }
  addClass(className: string): JQuery {
    // addClass 的操作...
    return this
  }
  // ... methods ...
}

创建工厂函数,以及TS声明扩展 window 全局的属性

declare interface Window {
  $: (selector: string) => JQuery
}
function $(selector: string) {
  return new JQuery(selector)
}
window.$ = $
console.log($('p')) // test

在 vue 中的模板,react 的 jsx 中,render 函数生成 vNode 对象,使用的也是工厂模式

Vue template

在线编译 https://vue-next-template-explorer.netlify.app/

<div>
  <span>文字</span>
  <span :id="hello" class="message">{{ msg }}</span>
</div>

会编译出 _createXX JS 代码,这些属于工厂函数,创建 vnode 。

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock("div", null, [
    _createElementVNode("span", null, "文字"),
    _createElementVNode("span", {
      id: _ctx.hello,
      class: "message"
    }, _toDisplayString(_ctx.msg), 9 , ["id"])
  ]))
}

React createElement

在线编译 https://www.babeljs.cn/repl

const profile = <div>
  <img src="avatar.png" className="profile" />
  <h3>{[user.firstName, user.lastName].join(' ')}</h3>
</div>

编译之后的函数执行返回 vNode

const profile = React.createElement("div", null,
    React.createElement("img", { src: "avatar.png", className: "profile" }),
    React.createElement("h3", null, [user.firstName, user.lastName].join(" "))
);

其大概原理:

class Vnode(tag, attrs, children) {
    // ...
}
React.createElement =  function (tag, attrs, children) {
    return new Vnode(tag, attrs, children)
}

你可能感兴趣的:(设计模式)