设计模式

287 阅读1分钟

观察者模式

// 观察者
class Observer {
    private name: string;
    public fn: (state: string) => void;
    constructor(name: string, fn: (state: string) => void) {
        this.name = name;
        this.fn = fn;
    }
}

// 被观察者
class Subject {
    private state: string;
    private observers: Observer[];
    constructor(state: string) {
        // 初始状态
        this.state = state;
        this.observers = [];
    }
    // 设置状态
    setState(state: string) {
        this.state = state;
        // 通知观察者
        this.observers.forEach((item: Observer) => {
            item.fn(this.state);
        });
    }
    // 新增观察者
    addObserver(obs: Observer) {
        // 过滤掉已经存在的-去重
        this.observers = this.observers.filter(
            (item: Observer) => item !== obs
        );
        this.observers.push(obs);
    }
    // 删除观察者
    removeObserver(obs: Observer) {
        this.observers = this.observers.filter(
            (item: Observer) => item !== obs
        );
    }
}
// 创建观察者
const xiaozhang: Observer = new Observer("校长", (state) => {
    console.log(`因为${state},校长`);
});
const laoshi: Observer = new Observer("老师", (state) => {
    console.log(`因为${state},老师`);
});

//创建被观察者
const xiaoming: Subject = new Subject("学习"); // 初始状态

// 添加观察者
xiaoming.addObserver(xiaozhang);
xiaoming.addObserver(laoshi);

// 更改状态,触发观察者动作
xiaoming.setState("玩游戏");

发布订阅模式

type Hander = {
    [key: string]: Function[];
};

class Observer {
    public message: Hander;
    constructor() {
        this.message = {};
    }

    public on(type: string, fn: () => void) {
        if (!this.message[type]) {
            this.message[type] = [];
        }
        this.message[type].push(fn);
    }
    public off(type: string, fn?: () => void) {
        // fn不存在的时候,取消的type类型的所有事件
        if (!fn) {
            delete this.message[type];
            return;
        }
        // 是否存在
        if (!this.message[type]) return;
        // 取消类型为type 且事件为fn的
        this.message[type] = this.message[type].filter(
            (item: Function) => item !== fn
        );
    }
    public emit(type: string) {
        // 是否订阅过
        if (!this.message[type]) return;

        this.message[type].forEach((item: Function) => item());
    }
}

const p = new Observer();

//订阅a
p.on("a", handerA);
p.on("a", handerB);

p.off("a"); // 取消a类型所有事件

p.off("a", handerA); // 取消a类型中,handerA事件

p.emit("a"); // 触发a

function handerA() {
    console.log("a");
}

function handerB() {
    console.log("b");
}