TypeScript单例模式、代理模式、观察者模式、工厂模式、发布订阅dome

这篇博客介绍了JavaScript中的四种设计模式:单例模式(预加载和懒加载)、代理模式、观察者模式以及工厂模式。通过实例展示了如何在实际编程中应用这些模式,提升代码的组织和复用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、单例模式

1.预加载
class SoundManager{
    static Instance = new SoundManager();
    name: string = '单例'
    private constructor() { }
}
console.log(SoundManager.Instance.name)
2.懒加载
// ts访问修饰符
// 1、public: 公开的,默认 任何对象在任何地方都可以进行访问
// 2、private: 私有的, 只能在当前类中进行访问
// 3、 protected: 受保护的,这能在当前类或者子类中进行访问
class ISoundManager {
    private static instance: ISoundManager = null;
    private constructor() { }
    name: string = '懒加载';
    static Instance() {
        if (!ISoundManager.instance) {
            ISoundManager.instance = new ISoundManager();
        }
        return ISoundManager.instance;
    }
}
console.log(ISoundManager.Instance().name)

二、 代理模式

interface ICalc {
    calc(num1, num2): number;
}
class Npc1 implements ICalc{
    calc(num1, num2) {
        return num1 + num2;
    }
}
class Npc2 implements ICalc{
    calc(num1, num2) {
        return num1 - num2;
    }
}
class Person {
    delegate: ICalc;
    //计算数字
    GetNum(num1, num2) {
        //拿到num1 和12计算后的结果
        let num = this.delegate.calc(num1, num2);
        console.log(num)
    }
}
let person = new Person();
person.delegate = new Npc2();
person.GetNum(3, 4);
person.delegate = new Npc1();
person.GetNum(3, 4);

三、观察者模式

interface IObserverf{
    nameChanged(oldName,newName);
}
class Person{
    private _name: string = '嘻嘻';
    observers: Array<IObserverf> = new Array<IObserverf>();
    set name(value: string) {
        let oldName: string = this._name;
        this._name = value;
        //发生变化,便利观察者数组,给所有的观察者发消息
        for (let observer of this.observers) {
            observer.nameChanged(oldName,this._name);
        }
    }
    get name(){
        return this._name;
    }
}
class Test implements IObserverf {
    nameChanged(oldName: string,newName: string) {
        document.write("监听到变化,名字" + oldName + "变为" + newName);
    }
}
let person = new Person();
let test = new Test();
person.observers.push(test);
person.name = "哈哈";

四、工厂模式

enum CarType{
    Bmw,
    Audi,
    Benz
}
class Car {
    name: string;
    static Create(carType: CarType): Car {
        let car: Car;
        switch (carType) {
            case CarType.Audi:
                car = new Audi();
                break;
            case CarType.Benz:
                car = new Benz();
                break;
            case CarType.Bmw:
                car = new Bmw();
                break;
        }
        return car;
    }
}
class Bmw extends Car {}
class Benz extends Car {}
class Audi extends Car {}
let bmw = Car.Create(CarType.Bmw);
let bgenz = Car.Create(CarType.Benz);
let audi = Car.Create(CarType.Audi);
console.log(bmw,bgenz,audi)

五、发布订阅&单例模式

class ClientEvent {
    /** 当前被订阅的事件列表 */
    private static _instance: ClientEvent | null = null;
    private _handlers: { [key: string]: { handler: (eventData: any) => void; target: any }[] } = {};

    private constructor() { }

    public static getInstance(): ClientEvent {
        if (!ClientEvent._instance) {
            ClientEvent._instance = new ClientEvent();
        }
        return ClientEvent._instance;
    }

    /**
     * 监听事件
     * @param {string} eventName 事件名称
     * @param {(eventData: any) => void} handler 监听函数
     * @param {object} target 监听目标
     * @returns {number} 当前事件的订阅数
     */
    public on(eventName: string, handler: (eventData: any) => void, target: any): number {
        const objHandler = { handler, target };
        if (!this._handlers[eventName]) {
            this._handlers[eventName] = [];
        }
        this._handlers[eventName].push(objHandler);
        return this._handlers[eventName].length;
    }

    /**
     * 取消监听
     * @param {string} eventName 监听事件
     * @param {(eventData: any) => void} handler 监听函数
     * @param {object} target 监听目标
     */
    public off(eventName: string, handler: (eventData: any) => void, target: any): void {
        const handlerList = this._handlers[eventName];
        if (!handlerList) {
            console.warn(`未找到事件处理程序: ${eventName}`);
            return;
        }

        for (let i = 0; i < handlerList.length; i++) {
            const oldObj = handlerList[i];
            if (oldObj.handler === handler && (!target || target === oldObj.target)) {
                handlerList.splice(i, 1);
                break;
            }
        }

        // 判空,防止内存泄漏
        if (handlerList.length === 0) {
            delete this._handlers[eventName];
        }
    }

    /**
     * 分发事件
     * @param {string} eventName 分发事件名
     * @param {...any} args 分发事件参数
     */
    public dispatchEvent(eventName: string, ...args: any[]): void {
        const handlerList = this._handlers[eventName];
        if (!handlerList) {
            console.warn(`没有要为事件分派的处理程序: ${eventName}`);
            return;
        }
        try {
            for (const objHandler of handlerList) {
                objHandler.handler.apply(objHandler.target, args);
            }
        } catch (error) {
            console.error(`事件分派期间发生错误: ${eventName}`, error);
        }
    }
}

// 延迟初始化 eventManager
const eventManager = ClientEvent.getInstance();
export { eventManager };

调用示例
import { eventManager } from "./clientEvent";
import { constant } from "./constant";

class Test {
    constructor() {
        this.init()
    }
    private _refresh() {
        console.log("1.监听刷新事件");
    }
    private _refreshCopy() {
        console.log("2.监听刷新事件");
    }
    init() {
        console.log('eventManager',eventManager)
        /** 监听刷新事件 */
        eventManager.on(constant.EVENT_TYPE.REFRESH, this._refresh, this);
        eventManager.on(constant.EVENT_TYPE.REFRESH, this._refreshCopy, this);
        const interval = setInterval(() => {
            // 分发事件 
            eventManager.dispatchEvent(constant.EVENT_TYPE.REFRESH);
        }, 500);
        setTimeout(() => {
            /** 取消监听刷新事件 */
            eventManager.off(constant.EVENT_TYPE.REFRESH, this._refresh, this);
        }, 2100)
        setTimeout(() => {
            clearInterval(interval);
            /** 取消监听刷新事件 */
            eventManager.off(constant.EVENT_TYPE.REFRESH, this._refreshCopy, this);
        }, 5000)
    }
}
new Test()
constant.ts
export const constant = {
    EVENT_TYPE: {
        REFRESH: "REFRESH"
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值