概念
工厂模式是一种常见的创建对象的设计模式,通过使用工厂函数或构造函数( 省略 new 关键字、分类、解耦、各自逻辑自由扩展 )来封装和抽象对象的创建过程,从而隐藏了具体对象的实现细节,这种模式可以帮助我们在创建对象时更加灵活和可扩展;
理解
你需要吃饭,但不需要自己做饭( new
),只需点餐( create
)即可;
enum Food {
Fruit = 'fruit',
Meat = 'meat'
}
interface IProduct {
cook: () => void
}
class CookFruit implements IProduct {
cook() {
console.log('make Fruit')
}
}
class CookMeat implements IProduct {
cook() {
console.log('make Meat')
}
}
我们可以通过工厂函数:create
实现实例的创建;
依赖倒置原则:依赖于抽象而不是具体、即任何一个类实现接口即可
const create = (type: string): IProduct => {
switch (type) {
case Food.Fruit:
return new CookFruit()
case Food.Meat:
return new CookMeat()
default:
throw new Error('Invalid Food')
}
}
const food1 = create('fruit')
const food2 = create('meat')
food1.cook() // make Fruit
food2.cook() // make Meat
JQuery
$ 使用的也是工厂模式,我们可以直接使用 $ 符,不需使用 new 关键字;
declare interface Window {
$: (selector: string) => JQuery
}
class JQuery {}
function $(selector: string) {
return new JQuery(selector)
}
window.$ = $
// console.log($('p'))
Vue template
render 函数生成 vNode 对象,使用的也是工厂模式
在线编译 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>
编译后:
const profile = React.createElement("div", null,
React.createElement("img", { src: "avatar.png", className: "profile" }),
React.createElement("h3", null, [user.firstName, user.lastName].join(" "))
);
执行返回 vNode
class Vnode(tag, attrs, children) {
// ...
}
React.createElement = function (tag, attrs, children) {
return new Vnode(tag, attrs, children)
}