js设计模式

  1. 单例模式
    它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。
class User {
    static #instance: User;
    #name: string;
    constructor(name: string) {
        this.#name = name
        if (new.target !== User) {
            return
        }
        if (!User.#instance) {
            User.#instance = this
            return User.#instance
        } else {
            // 提示
            console.error("不能重复初始化")
        }
        return User.#instance
    }

    get getName() {
        return this.#name
    }

}

const u1 = new User("张三")
const u2 = new User("李四")
console.log(u1 === u2); // true
console.log(u2.getName); // 张三

  1. 工厂模式
    它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离
abstract class Shape {
    abstract draw(): void;
}

class Rectangle implements Shape {
    draw() {
        console.log("draw rectangle")
    }
}
class Square implements Shape {
    draw() {
        console.log("draw square")
    }
}
class Circle implements Shape {
    draw() {
        console.log("draw circle ")
    }
}

class ShapeFactory {
    public getShape(shapeType: "Rectangle" | "Square" | "Circle"): Shape {
        switch (shapeType) {
            case "Rectangle":
                return new Rectangle();
            case "Square":
                return new Square();
            case "Circle":
                return new Circle();
            default:
                throw new Error("没有这个形状")
        }
    }
}

const shapeFactory = new ShapeFactory()
const rectangle = shapeFactory.getShape("Rectangle")
const square = shapeFactory.getShape("Square")
const circle = shapeFactory.getShape("Circle")
rectangle.draw() // draw rectangle
square.draw() // draw square
circle.draw() // draw circle

  1. 原型模式
    复用原型上的方法和属性以提高性能
const shapePrototype = {
    name: "",
    draw: function () {
        console.log(this.name);
    }
};

const shape1 = Object.create(shapePrototype, {
    name: {
        value: "square"
    }
});
const shape2 = Object.create(shapePrototype, {
    name: {
        value: "circle"
    }
});

shape1.draw() // square
shape2.draw() // circle
console.log(shape1.draw === shape2.draw) // true

采用ES6的class是同样的效果

class Shape {
    name: string
    constructor(name: string) {
        this.name = name
    }
    draw(): void {
        console.log(this.name)
    }
}

const shape1 = new Shape("square")
const shape2 = new Shape("circle")

shape1.draw() // square
shape2.draw() // circle
console.log(shape1.draw === shape2.draw) // true

  1. 适配器模式
    可用来在现有接口和不兼容的类之间进行适配。它被添加到现有代码中来协调两个不同的接口
class NewAPI {
    newGetList() {
        return [1, 2, 3]
    }
}

class OldAPI {
    oldGetList() {
        return [2, 3, 4]
    }
}

class APIAdapter extends OldAPI {
    constructor() { super() }
    newGetList() {
        return this.oldGetList()
    }
}


function getList(api: NewAPI) {
    return api.newGetList()
}

getList(new NewAPI())
getList(new APIAdapter())
getList(new OldAPI())  // 报错
  1. 依赖注入模式
    将一个对象所依赖的其他对象的创建过程,从该对象本身中分离出来,以便更好地实现解耦和可测试性。
// 定义一个容器类
class Container {
    bindings: { [key: string]: Function };
    constructor() {
        this.bindings = {};
    }

    bind(abstract: string, concrete: Function) {
        this.bindings[abstract] = concrete;
    }

    make(abstract: string | number) {
        const concretion = this.bindings[abstract];
        if (typeof concretion === 'function') {
            console.log(this)
            return concretion(this);
        }
        return concretion;
    }
}

// 创建容器实例
const container = new Container();

// 绑定服务到容器
container.bind('logger', () => {
    return {
        log(message: any) {
            console.log(message);
        }
    };
});

// 使用依赖注入
function serviceWithDependency(container: Container) {
    const logger = container.make('logger');
    logger.log('This is a dependency injection example.');
}

// 解析依赖并执行函数
serviceWithDependency(container);

采用装饰器模式

import "reflect-metadata"

const requiredMetadataKey = Symbol("required");

function required(target: Object, propertyKey: string | symbol, parameterIndex: number) {
    let existingRequiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || [];
    existingRequiredParameters.push(parameterIndex);
    Reflect.defineMetadata(requiredMetadataKey, existingRequiredParameters, target, propertyKey);
}

function validate(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<Function>) {
    let method = descriptor.value!;

    descriptor.value = function () {
        let requiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyName);
        console.log(propertyName)
        if (requiredParameters) {
            for (let parameterIndex of requiredParameters) {
                if (parameterIndex >= arguments.length || arguments[parameterIndex] === undefined) {
                    throw new Error("Missing required argument.");
                }
            }
        }
        return method.apply(this, arguments);
    };
}

class BugReport {
    type = "report";
    title: string;

    constructor(title: string) {
        this.title = title;
    }

    @validate
    print(@required verbose: boolean) {
        if (verbose) {
            console.log(`type: ${this.type}\ntitle: ${this.title}`)
            return;
        } else {
            console.log(`title: ${this.title}`)
        }
    }

    @validate
    log(@required log: string) {
        console.log(log)
    }
}

const bugReport = new BugReport("test")
bugReport.print(true)
bugReport.log("this is a example")

  1. 观察者模式
    它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

MutationObserver观察节点

const div = document.createElement("div")

const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        console.log(mutation);
    });
});

// 配置观察器选项
const config = {
    attributes: true,      // 监听目标节点的属性变化
    childList: true,       // 监听目标节点的子节点增加或删除变化
    characterData: true,   // 监听目标节点的文本内容或字符数据变化
    subtree: true          // 监听目标节点以及所有后代的变化
};

// 传入目标节点和观察选项
observer.observe(div, config);
div.textContent = "test"

// 最后,可以随时停止观察
// observer.disconnect();

defineProperty观察属性

const config = {
    pwd: '',
    host: ''
}
Object.defineProperties(config, {
    host: {
        value: '127.0.0.1',
        configurable: true
    },
    pwd: {
        get: function () {
            return this.value || "123456"
        },
        set: function (value) {
            if (value.length < 6) {
                throw new Error('密码长度必须大于等于6')
            } else {
                this.value = value
            }
        }
    }
})

console.log(config.pwd)
console.log(config.host)
config.pwd = "123"

Proxy观察属性

const config = new Proxy({
    pwd: '',
    host: ''
}, {
    get(target, key, receiver) {
        return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
        console.log(`设置${String(key)}= ${value}, 原始值为${JSON.stringify(receiver)}`)
        return Reflect.set(target, key, value, receiver);
    }
})
config.pwd = "123"

发布订阅模式

import EventEmitter from "events"
const eventEmitter = new EventEmitter()
eventEmitter.on("data", (data) => {
    console.log(data)
})
eventEmitter.emit("data", "this is test data1")
eventEmitter.emit("data", "this is test data2")
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值