所有的实例都从工厂产生,不用自己new 。
简易的工厂模式
class Product {
name: string;
constructor(name: string) {
this.name = name;
}
fn1() {
console.log("fn1", this.name);
}
fn2() {
console.log("fn2");
}
}
// 工厂
class Creator {
create(name: string): Product {
return new Product(name);
}
}
const creator = new Creator();
const p1 = creator.create("p1");
const p2 = creator.create("p2");
p1.fn1();
p2.fn1();
标准的工厂模式
标准的工厂模式
interface IProduct {
name: string;
fn1: () => void;
fn2: () => void;
}
class Product1 implements IProduct {
name: string;
constructor(name: string) {
this.name = name;
}
fn1() {
console.log("fn1", this.name);
}
fn2() {
console.log("fn2");
}
}
class Product2 implements IProduct {
name: string;
constructor(name: string) {
this.name = name;
}
fn1() {
console.log("fn1", this.name);
}
fn2() {
console.log("fn2");
}
}
class Creator {
//依赖导致原则IProduct
create(type: string, name: string): IProduct {
if (type === "p1") {
return new Product1(name);
} else if (type === "p2") {
return new Product2(name);
}
throw new Error("Invalid type");
}
}
const creator = new Creator();
const p1 = creator.create("p1", "p1");
const p11 = creator.create("p1", "p1_1");
const p2 = creator.create("p2", "p2");
const p21 = creator.create("p2", "p2_1");
p1.fn1();
p11.fn1();
p2.fn1();
p21.fn1();
使用场景1:JQuery
不使用工厂模式
const $div = new JQuery("div");
const $p = new JQuery("p");
VS
使用工厂模式
const $div = $("div");
const $p = $("p");、
declare interface Window {
$: (select: string) => JQuery;
}
class JQuery {
select: string;
length: number;
constructor(select: string) {
const domList = Array.prototype.slice.call(document.querySelector(select));
for (let i = 0; i < domList.length; i++) {
// @ts-ignore
this[i] = domList[i];
}
this.select = select;
this.length = domList.length;
}
append(elem: HTMLElement): JQuery {
// append操作 ....
return this;
}
addClass(clazz: string): JQuery {
// addClass操作 ....
return this;
}
}
// 不使用工厂模式
// const $div = new JQuery("div");
// const $p = new JQuery("p");
//使用工厂模式
function $(selector: string) {
return new JQuery(selector); // 逻辑封装
}
window.$ = function (selector: string) {
return new JQuery(selector); // 逻辑封装
};
const $div = $("div");
const $p = $("p");
/**
伪代码,演示 jquery 实例的结构
伪数组,Array.prototype.slice.call或者Array.from可以将伪数组转化为真的数组
const jquery = {
selector: 'div',
length: 3,
'0': div1,
'1': div2,
'2': div3
}
*/
使用场景2:React
JSX编译的产物, _jsx 、_jsxs都是工厂函数,生成VNode。
使用场景3:Vue
vue3模板编译的产物,_createElementBlock、_createElementVNode都是工厂函数,生成VNode