圖解23種設計模式(TypeScript版)——前端切圖仔提高內功的必經之路

關注公衆號「 執鳶者」,回覆「 書籍」獲取大量前端學習資料,回覆「 前端視頻」獲取大量前端教學視頻,回覆「 設計模式」獲取本節總體思惟導圖。

使用思惟導圖來闡述23種設計模式,並以TypeScript實現其代碼,讓咱們前端切圖崽寫出的代碼具備可擴展性、可複用性、減小代碼冗餘問題,提高自身內功。

1、設計原則

2、建立型模式

建立型模式包含單例模式、簡單工廠模式、工廠方法模式、抽象工廠模式、原型模式、建造者模式。建立型模式就是建立對象的模式,抽象了實例化的過程。它幫助一個系統獨立於如何建立、組合和表示它的那些對象。 關注的是對象的建立,建立型模式將建立對象的過程進行了抽象,也能夠理解爲將建立對象的過程進行了封裝,做爲客戶程序僅僅須要去使用對象,而再也不關心建立對象過程當中的邏輯。

2.1 單例模式

// 餓漢式
class Singleton1 {
    // 1. 構造器私有化,外部不能new
    private constructor(){}

    // 2. 本類內部建立對象實例化
    private static instance : Singleton1 = new Singleton1();

    // 3. 提供一個公有的靜態方法,返回實例對象
    public static getInstance() : Singleton1 {
        return this.instance;
    }
}

console.log(Singleton1.getInstance(), '11111');

// 懶漢式
class Singleton2 {
    private constructor(){}

    private static instance: Singleton2 = null;

    public static getInstance() : Singleton2 {
        if (this.instance === null) {
            this.instance = new Singleton2();
        }

        return this.instance;
    }
}

console.log(Singleton2.getInstance(), '2222')

2.2 簡單工廠模式

// 抽象產品接口
interface Product{}

// 具體產品一
class ConcreteProduct1 implements Product {
    constructor(){}
}

// 具體產品二
class ConcreteProduct2 implements Product {
    constructor(){}
}

// 簡單工廠
class SimpleFactory {
    public static createProduct(type : number) : Product {
        let product = null;
        if (type === 1) {
            product = new ConcreteProduct1();
        } else if ( type === 2) {
            product = new ConcreteProduct2();
        }

        return product;
    }
}

// 使用
let product = SimpleFactory.createProduct(1);
console.log(product);

2.3 工廠方法模式

// 抽象產品接口
interface Product2{
    method1() : void;
    method2() : void;
}

// 具體產品一
class ConcreteProduct_1 implements Product2 {
    constructor(){}
    method1() {

    }
    method2() {

    }
}

// 具體產品二
class ConcreteProduct_2 implements Product2 {
    constructor(){}
    method1() {

    }
    method2() {
        
    }
}

// 抽象工廠
abstract class Creator {
    public abstract createProduct(type : number) : Product;
}

// 具體工廠
class ConcreteCreator extends Creator {
    constructor(){
        super();
    }

    public createProduct(type : number) : Product {
        let product = null;
        if (type === 1) {
            product = new ConcreteProduct_1();
        } else if (type === 2) {
            product = new ConcreteProduct_2();
        }
        return product;
    }
}

// 使用
const creator : Creator = new ConcreteCreator();
const myProduct : Product = creator.createProduct(1);

2.4 抽象工廠模式

// 抽象工廠接口
interface AbstractFactory {
    createProductA() : AbstractProductA;
    createProductB() : AbstractProductB;
}

// 抽象產品A接口
interface AbstractProductA {}

// 抽象產品B接口
interface AbstractProductB {}

// 具體工廠1
class ConcreteFactory1 implements AbstractFactory {
    constructor() {}
    public createProductA() : AbstractProductA {
        return new ConcreteProductA1();
    }
    public createProductB() : AbstractProductB {
        return new ConcreteProductB1();
    }
}

// 具體工廠2
class ConcreteFactory2 implements AbstractFactory {
    constructor() {}
    public createProductA() : AbstractProductA {
        return new ConcreteProductA2();
    }
    public createProductB() : AbstractProductB {
        return new ConcreteProductB2();
    }
}

// 具體產品A1
class ConcreteProductA1 implements AbstractProductA {}
// 具體產品A2
class ConcreteProductA2 implements AbstractProductA {}
// 具體產品B1
class ConcreteProductB1 implements AbstractProductB {}
// 具體產品B2
class ConcreteProductB2 implements AbstractProductA {}

// 使用
const factory1 : AbstractFactory = new ConcreteFactory1();
const factory2 : AbstractFactory = new ConcreteFactory2();
const productA1 : AbstractProductA = factory1.createProductA();
const productA2 : AbstractProductA = factory2.createProductA();
const productB1 : AbstractProductB = factory1.createProductB();
const productB2 : AbstractProductB = factory2.createProductB();

2.5 原型模式

interface Prototype {
    clone():Prototype;
}

class Dog implements Prototype {
    public name: string;
    public birthYear: number;
    public sex: string;
    public presentYear: number;
    constructor() {
        this.name = "lili";
        this.birthYear = 2015;
        this.sex = "男";
        this.presentYear = 2018;
    }

    public getDiscription(): string {
        return `狗狗叫${this.name},性別${this.sex},${this.presentYear}年${this.presentYear - this.birthYear}歲了`
    }

    // 實現複製
    public clone(): Prototype {
        return Object.create(this);
    }
}

// 使用
const dog = new Dog();
console.log(dog.getDiscription());
dog.presentYear = 2020;
const dog1 = Object.create(dog);
console.log(dog1.getDiscription());

2.6 建造者模式

// 抽象建造者
abstract class Builder {
    public abstract buildPartA() : void;
    public abstract buildPartB() : void;
    public abstract buildPartC() : void;
    public abstract buildProduct() : Product;
}

// 具體建造者
class ConcreteBuilder extends Builder {
    private product : Product;
    constructor(product : Product) {
        super();
        this.product = product;
    }

    public buildPartA() : void {}
    public buildPartB() : void {}
    public buildPartC() : void {}

    // 最終組建一個產品
    public buildProduct() : Product {
        return this.product;
    }
}

// 產品角色
class Product {
    public doSomething() : void {
        // 獨立業務
    }
}

// 指揮者
class Director {
    private _builder : Builder;
    constructor(builder : Builder) {
        this._builder = builder;
    }

    set builder(builder : Builder) {
        this._builder = builder;
    }

    // 將處理建造的流程交給指揮者
    public constructorProduct() {
        this._builder.buildPartA();
        this._builder.buildPartB();
        this._builder.buildPartC();
        return this._builder.buildProduct();
    }
}

// 使用
const builder : Builder = new ConcreteBuilder(new Product());
const director : Director = new Director(builder);
const product : Product = director.constructorProduct();

3、結構型模式

結構型模式包含適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。結構型模式爲解決怎樣組裝現有的類,設計他們的交互方式,從而達到實現必定的功能。

3.1 適配器模式

// 類適配器
// 目標對象
interface Target {
    request() : void;
}
// 被適配者
class Adaptee {
    constructor() {}
    // 這是源角色,有本身的的業務邏輯
    public specificRequest() : void {}
}
// 適配器
class Adapter extends Adaptee implements Target {
    constructor() {
        super();
    }
    public request() : void {
        super.specificRequest();
    }
}

const target : Target = new Adapter();
target.request();
// 對象適配器
// 目標對象
interface Target {
    request() : void;
}
// 被適配者
class Adaptee {
    constructor() {}
    // 這是源角色,有本身的的業務邏輯
    public specificRequest() : void {}
}
// 適配器
class Adapter implements Target {
    private adaptee : Adaptee;
    constructor(adaptee : Adaptee) {
        this.adaptee = adaptee;
    }
    public request() : void {
        this.adaptee.specificRequest();
    }
}
// 使用
const target : Target = new Adapter(new Adaptee());
target.request();
// 接口適配器
interface Adaptee {
    operation1() : void;
    operation2() : void;
}

abstract class AbsAdapter implements Adaptee {
    public operation1() : void {}
    public operation2() : void {} 
}

class UseClass extends AbsAdapter {
    public operation1() : void {}// 重寫該類
}

3.2 橋接模式

// 實現接口角色
interface Implementor {
    doSomething() : void;
    doAnything() : void;
}

// 具體實現角色
class ConcreteImplementor1 implements Implementor {
    public doSomething() : void {

    }
    public doAnything() : void {

    }
}
class ConcreteImplementor2 implements Implementor {
    public doSomething() : void {

    }
    public doAnything() : void {
        
    }
}

// 抽象類
abstract class Abstraction {
    private imp : Implementor;
    constructor(imp : Implementor) {
        this.imp = imp;
    }

    // 自身的行爲和屬性
    public request() : void {
        this.imp.doSomething();
    }
}
// 具體抽象化角色
class RefinedAbstraction extends Abstraction {
    constructor(imp : Implementor) {
        super(imp);
    }

    public request() : void {
        // 本身寫一些處理業務
        super.request();
    }
}

// 調用
// 定義一個實現化角色
const imp : Implementor = new ConcreteImplementor1();
// 定義一個抽象化角色
const abs : Abstraction = new RefinedAbstraction(imp);
// 執行上下文
abs.request();

3.3 裝飾者模式

// 抽象構件
abstract class Component {
    public abstract operate() : void;
}

// 具體構件
class ConcreteComponent extends Component {
    public operate() : void {
        console.log('do something');
    }
}

// 裝飾角色
abstract class Decorator extends Component {
    private component : Component = null;
    constructor(component : Component ) {
        super();
        this.component = component;
    }

    public operate() : void {
        this.component.operate();
    }
}

// 具體裝飾者
class ConcreteDecoratorA extends Decorator {
    constructor(component : Component) {
        super(component);
    }

    // 定義本身的修飾方法
    private methodA() : void {
        console.log('methodA修飾');
    }

    // 重寫父類方法
    public operate() : void {
        this.methodA();
        super.operate();
    }
}

class ConcreteDecoratorB extends Decorator {
    constructor(component : Component) {
        super(component);
    }

    // 定義本身的修飾方法
    private methodB() : void {
        console.log('methodB修飾');
    }

    // 重寫父類方法
    public operate() : void {
        this.methodB();
        super.operate();
    }
}

function main() {
    let component : Component = new ConcreteComponent();
    // 第一次裝飾
    component = new ConcreteDecoratorA(component);
    // 第二次裝飾
    component = new ConcreteDecoratorB(component);
    // 裝飾後運行
    component.operate();
}

main();

3.4 組合模式

abstract class Component {
    protected name : string;
    constructor(name : string) {
        this.name = name;
    }

    public abstract doOperation() : void;

    public add(component : Component) : void {

    }

    public remove(component : Component) : void {

    }

    public getChildren() : Array<Component> {
        return [];
    }
}

class Composite extends Component {
    // 構件容器
    private componentList : any;
    constructor(name : string) {
        super(name);
        this.componentList = [];
    }

    public doOperation() : void {
        console.log(`這是容器${this.name},處理一些邏輯業務!`);
    }

    public add(component : Component) : void {
        this.componentList.push(component);
    }

    public remove(component : Component) : void {
        const componentIndex = this.componentList.findIndex((value : Component, index : Number) => {
            return value == component;
        });
        this.componentList.splice(componentIndex, 1);
    }

    public getChildren() : Array<Component> {
        return this.componentList;
    }
}

class Leaf extends Component {
    constructor(name : string) {
        super(name);
    }

    public doOperation() : void {
        console.log(`這是葉子節點${this.name},處理一些邏輯業務!`);
    }
}

function main() {
    const root : Component  = new Composite('root');
    const node1 : Component = new Leaf('1');
    const node2 : Component = new Composite('2');
    const node3 : Component = new Leaf('3');

    root.add(node1);
    root.add(node2);
    root.add(node3);

    const node2_1 : Component = new Leaf("2_1");
    node2.add(node2_1);

    const children1 = root.getChildren();
    console.log(children1);

    root.remove(node2);

    const children2 = root.getChildren();
    console.log(children2);
}

main();

3.5 外觀模式

class SubSystemA {
    public doOperationA() : void {
        console.log('子系統A的舉動');
    }
}

class SubSystemB {
    public doOperationB() : void {
        console.log('子系統B的舉動');
    }
}

class Facade {
    private subSystemA : SubSystemA;
    private subSystemB : SubSystemB;
    constructor() {
        this.subSystemA = new SubSystemA();
        this.subSystemB = new SubSystemB();
    }

    public doOperation() : void {
        this.subSystemA.doOperationA();
        this.subSystemB.doOperationB();
    }
}

function main() {
    const facade : Facade = new Facade();
    facade.doOperation();
}

main();

3.6 享元模式

abstract class Flyweight {
    public abstract doOperation(extrinsicState : string) : void;
}

class ConcreteFlyweight extends Flyweight {
    private intrinsicState : string;
    constructor(intrinsicState : string) {
        super();
        this.intrinsicState = intrinsicState;
    }

    public doOperation(extrinsicState : string) : void {
        console.log(`這是具體享元角色,內部狀態爲${this.intrinsicState},外部狀態爲${extrinsicState}`);
    }
}

interface flyweightObject {
    [key : string] : Flyweight
}

class FlyweightFactory {
    private flyweights : flyweightObject;
    constructor() {
        this.flyweights = {};
    }

    public getFlyweight(intrinsicState : string) : Flyweight {
        if (!this.flyweights[intrinsicState]) {
            const flyweight : Flyweight = new ConcreteFlyweight(intrinsicState);
            this.flyweights[intrinsicState] = flyweight;
        }
        return this.flyweights[intrinsicState];
    }
}

function main() {
    const factory : FlyweightFactory = new FlyweightFactory();
    const flyweight1 : Flyweight = factory.getFlyweight("aa");
    const flyweight2 : Flyweight = factory.getFlyweight("aa");
    flyweight1.doOperation('x');
    flyweight2.doOperation('y');
}

main();

3.7 代理模式

// 靜態代理
interface Subject {
    doOperation() : void;
}

class RealSubject implements Subject {
    public doOperation() {
        console.log('我是RealSubject類,正在執行');
    }
}

class MyProxy implements Subject {
    private target : Subject;
    constructor(realSubject : Subject) {
        this.target = realSubject;
    }

    public doOperation() {
        console.log('我是代理類');
        this.target.doOperation();
    }
}

function main() {
    const realSubject : Subject = new RealSubject();
    const myProxy : Subject = new MyProxy(realSubject);

    myProxy.doOperation();
}

main();
// 動態代理
interface Subject {
    doOperation() : void;
}

class RealSubject implements Subject {
    constructor() {}

    public doOperation() : void {
        console.log('我是RealSubject類,正在執行');
    }
}

class ProxyFactory {
    private target : any;
    constructor(target : any) {
        this.target = target;
    }

    public getProxyInstance() : any {
        return new Proxy(this.target, {
            get: (target, propKey) => {
                // 作的一些攔截處理
                return target[propKey];
            }
        });
    }
}

function main() {
    const target : Subject = new RealSubject();
    const proxyInstance : Subject = <Subject>new ProxyFactory(target).getProxyInstance();

    proxyInstance.doOperation();
}

main();

4、行爲型模式

行爲型模式包含模板方法模式、命令模式、訪問者模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter模式)、狀態模式、策略模式、職責鏈模式(責任鏈模式)。行爲型模式對在不一樣的對象之間劃分責任和算法的抽象化,行爲型模式不單單關注類和對象的結構,並且重點關注他們之間的相互做用,經過行爲型模式,能夠更加清晰地劃分類與對象的職責,並研究系統在運行時實例對象之間的交互。

4.1 模板方法模式

abstract class AbstractClass {
    constructor() {}

    // 模板方法
    public template() : void {
        this.operation1();
        this.hookMethod() && this.operation2();
        this.operation3();
    }

    // 基本方法
    protected operation1() : void {
        console.log('使用了方法operation1');
    }

    protected operation2() : void {
        console.log('使用了方法operation2');
    }

    protected operation3() : void {
        console.log('使用了方法operation3');
    }

    // 鉤子方法
    protected hookMethod() : boolean {
        return true;
    }
}

class ConcreteClassA extends AbstractClass {
    protected operation2() :void {
        console.log('對該方法operation2進行了修改再使用');
    }

    protected operation3() :void {
        console.log('對該方法operation3進行了修改再使用');
    }
}

class ConcreteClassB extends AbstractClass {
    // 覆蓋鉤子方法
    protected hookMethod() : boolean {
        return false;
    }
}

function main() {
    const class1 : AbstractClass = new ConcreteClassA();
    const class2 : AbstractClass = new ConcreteClassB();

    class1.template();
    class2.template();
}

main();

4.2 命令模式

interface Command {
    execute() : void;
    undo() : void;
}

// 開啓命令
class ConcreteCommandOn implements Command {
    private receiver : Receiver;
    constructor(receiver : Receiver) {
        this.receiver = receiver;
    }

    // 執行命令的方法
    public execute() : void {
        this.receiver.actionOn();
    }

    // 撤銷命令的方法
    public undo() : void {
        this.receiver.actionOff();
    }
}

// 關閉命令
class ConcreteCommandOff implements Command {
    private receiver : Receiver;
    constructor(receiver : Receiver) {
        this.receiver = receiver;
    }

    // 執行命令的方法
    public execute() : void {
        this.receiver.actionOff();
    }

    // 撤銷命令的方法
    public undo() : void {
        this.receiver.actionOn();
    }
}

// 空命令(省去判空操做)
class NoCommand implements Command {
    public execute() : void {}
    public undo() : void {}
}

class Receiver {
    public actionOn() : void {
        console.log('我是命令接收者,開啓了某動做');
    }
    public actionOff() : void {
        console.log('我是命令接收者,關閉了某動做');
    }
}

class Invoker {
    private onCommands : Array<Command>;
    private offCommands : Array<Command>;
    private undoCommand : Command;
    private slotNum : number = 7;
    constructor() {
        this.undoCommand = new NoCommand();
        this.onCommands = [];
        this.offCommands = [];

        for (let i = 0; i < this.slotNum; i++) {
            this.onCommands[i] = new NoCommand();
            this.offCommands[i] =  new NoCommand();
        }
    }

    public setCommand(index : number, onCommand : Command, offCommand : Command) : void {
        this.onCommands[index] = onCommand;
        this.offCommands[index] = offCommand;
    }

    // 開啓
    public on (index : number) : void {
        this.onCommands[index].execute();// 調用相應方法
        //記錄此次操做,用於撤銷
        this.undoCommand = this.onCommands[index];
    }

    // 關閉
    public off (index : number) : void {
        this.offCommands[index].execute();
        this.undoCommand = this.offCommands[index];
    }

    // 撤銷
    public undo () : void {
        this.undoCommand.undo();
    }
}

function main() {
    // 建立接收者
    const receiver : Receiver = new Receiver();

    // 建立命令
    const commandOn : Command = new ConcreteCommandOn(receiver);
    const commandOff : Command = new ConcreteCommandOff(receiver);

    // 建立調用者
    const invoker : Invoker = new Invoker();
    invoker.setCommand(0, commandOn, commandOff);

    invoker.on(0);
    invoker.off(0);
    invoker.undo();
}

main();

4.3 訪問者模式

abstract class AbstractElement {
    // 定義業務邏輯
    public abstract doSomething() : void;
    // 容許誰來訪問
    public abstract accept (visitor : Visitor) : void;
}

class ConcreteElement1 extends AbstractElement{
    public doSomething() : void {
        console.log('ConcreteElement1執行的業務邏輯');
    }

    public accept(visitor : Visitor) : void {
        visitor.visit1(this)
    }
}

class ConcreteElement2 extends AbstractElement{
    public doSomething() : void {
        console.log('ConcreteElement1執行的業務邏輯');
    }

    public accept(visitor : Visitor) : void {
        visitor.visit2(this)
    }
}

abstract class Visitor {
    public abstract visit1(element1 : ConcreteElement1) : void;
    public abstract visit2(element2 : ConcreteElement2) : void;
}

class ConcreteVistor extends Visitor {
    public visit1(element1 : ConcreteElement1) : void {
        console.log('進入處理element1')
        element1.doSomething();
    }

    public visit2(element2 : ConcreteElement2) : void {
        console.log('進入處理element2');
        element2.doSomething();
    }
}

// 數據結構,管理不少元素(ConcreteElement1,ConcreteElement1)
class ObjectStructure {
    private listSet : Set<AbstractElement>;
    constructor() {
        this.listSet = new Set();
    }

    // 增長
    public attach(element : AbstractElement) : void {
        this.listSet.add(element);
    }

    // 刪除
    public detach(element : AbstractElement) : void {
        this.listSet.delete(element);
    }

    // 顯示
    public display(visitor : Visitor) : void {
        for (let element of this.listSet.values()) {
            element.accept(visitor);
        }
    } 
}

function main() {
    const objectStructure : ObjectStructure = new ObjectStructure();
    objectStructure.attach(new ConcreteElement1());
    objectStructure.attach(new ConcreteElement2());

    const visitor :Visitor = new ConcreteVistor();

    objectStructure.display(visitor);
}

main();

4.4 迭代器模式

interface AbstractIterator {
    next() : any;
    hasNext() : boolean;
    remove() : boolean;
}

class ConcreteIterator implements  AbstractIterator {
    private list : any[];
    public cursor : number = 0;
    constructor(array : any[]) {
        this.list = array;
    }

    public next() : any {
        return this.hasNext() ? this.list[this.cursor++] : null;
    }

    public hasNext() : boolean {
        return this.cursor < this.list.length;
    }

    public remove() : boolean{
        this.list.splice(this.cursor--, 1);
        return true;
    }
}

interface Aggregate {
    add(value : any) : void;
    remove(value : any) : void;
    createIterator() : AbstractIterator;
}

class ConcreteAggregate implements Aggregate {
    // 容納對象的容器
    private list : any[];
    constructor() {
        this.list = [];
    }

    add(value : any) : void {
        this.list.push(value)
    }

    remove(value : any) : void {
        const index = this.list.findIndex((listValue) => {
            return value === listValue;
        });
        this.list.splice(index, 1);
    }

    createIterator() : AbstractIterator {
        return new ConcreteIterator(this.list);
    }
}

function main() {
    const aggregate : Aggregate = new ConcreteAggregate();
    aggregate.add('11111');
    aggregate.add('222222');

    const iterator : AbstractIterator = aggregate.createIterator();
    while(iterator.hasNext()) {
        console.log(iterator.next());
    }
}

main();

4.5 觀察者模式

// 觀察者模式
interface AbstractSubject {
    registerObserver(observer : Observer) : void;
    remove(observer : Observer) : void;
    notifyObservers() : void;
}

class ConcreteSubject implements AbstractSubject {
    private observers : Array<Observer>;

    constructor() {
        this.observers = [];
    }

    public registerObserver(observer : Observer) : void {
        this.observers.push(observer);
    };

    public remove(observer : Observer) : void {
        const observerIndex = this.observers.findIndex(value => {
            return value == observer;
        })

        observerIndex >= 0 && this.observers.splice(observerIndex, 1);
    };

    public notifyObservers() : void {
        this.observers.forEach(observer => observer.update())
    };
}

interface Observer {
    update() : void;
}

class ConcreteObserver1 implements Observer {
    public update() : void {
        console.log('已經執行更新操做1,值爲');
    }
}
class ConcreteObserver2 implements Observer {
    public update() : void {
        console.log('已經執行更新操做2,值爲');
    }
}

function main() {
    const subject : AbstractSubject = new ConcreteSubject();
    const observer1 : Observer = new ConcreteObserver1();
    const observer2 : Observer = new ConcreteObserver2();
    
    subject.registerObserver(observer1);
    subject.registerObserver(observer2);

    subject.notifyObservers();
}

main();
// 發佈訂閱模式
interface Publish {
    registerObserver(eventType : string, subscribe : Subscribe) : void;
    remove(eventType : string, subscribe ?: Subscribe) : void;
    notifyObservers(eventType : string) : void;
}
interface SubscribesObject{
    [key : string] : Array<Subscribe>
}
class ConcretePublish implements Publish {
    private subscribes : SubscribesObject;

    constructor() {
        this.subscribes = {};
    }

    registerObserver(eventType : string, subscribe : Subscribe) : void {
        if (!this.subscribes[eventType]) {
            this.subscribes[eventType] = [];
        }

        this.subscribes[eventType].push(subscribe);
    }

    remove(eventType : string, subscribe ?: Subscribe) : void {
        const subscribeArray = this.subscribes[eventType];
        if (subscribeArray) {
            if (!subscribe) {
                delete this.subscribes[eventType];
            } else {
                for (let i = 0; i < subscribeArray.length; i++) {
                    if (subscribe === subscribeArray[i]) {
                        subscribeArray.splice(i, 1);
                    }
                }
            }
        }
    }

    notifyObservers(eventType : string, ...args : any[]) : void {
        const subscribes = this.subscribes[eventType];
        if (subscribes) {
            subscribes.forEach(subscribe => subscribe.update(...args))
        }
    }
}

interface Subscribe {
    update(...value : any[]) : void;
}

class ConcreteSubscribe1 implements Subscribe {
    public update(...value : any[]) : void {
        console.log('已經執行更新操做1,值爲', ...value);
    }
}
class ConcreteSubscribe2 implements Subscribe {
    public update(...value : any[]) : void {
        console.log('已經執行更新操做2,值爲', ...value);
    }
}

function main() {
    const publish = new ConcretePublish();
    const subscribe1 = new ConcreteSubscribe1();
    const subscribe2 = new ConcreteSubscribe2();

    publish.registerObserver('1', subscribe1);
    publish.registerObserver('2', subscribe2);

    publish.notifyObservers('2', '22222');
}

main();

4.6 中介者模式

abstract class Colleague {
    public abstract onEvent(eventType : string) : void;
}

class ConcreteColleagueA extends Colleague{
    private mediator : Mediator;
    constructor(mediator : Mediator) {
        super();
        this.mediator = mediator;
    }
    public onEvent(eventType : string) : void {
        this.mediator.doEvent(eventType);
    }

    // 本身的一些事情
    public doSomething() : void {
        console.log('A被運行了');
    }
}

class ConcreteColleagueB extends Colleague {
    private mediator : Mediator;
    constructor(mediator : Mediator) {
        super();
        this.mediator = mediator;
    }

    public onEvent(eventType : string) : void {
        this.mediator.doEvent(eventType);
    }

    // 本身的一些事情
    public doSomething() : void {
        console.log('B被運行了');
    }
}

abstract class Mediator {
    protected _colleagueA ?: ConcreteColleagueA;
    protected _colleagueB ?: ConcreteColleagueB;

    set colleagueA(colleagueA : ConcreteColleagueA) {
        this._colleagueA = colleagueA;
    }

    set colleagueB(colleagueB : ConcreteColleagueB) {
        this._colleagueB = colleagueB;
    }
    public abstract doEvent(eventType : string) : void;
}

class ConcreteMediator extends Mediator {
    //1. 根據獲得消息,完成對應任務
    //2. 中介者在這個方法,協調各個具體的同事對象,完成任務
    public doEvent(eventType : string) : void {
        switch (eventType) {
            case "A": {
                this.doColleagueAEvent();
                break;
            }
            case "B": {
                this.doColleagueBEvent();
                break;
            }
            default: {

            }
        }
    }

    // 相應業務邏輯
    public doColleagueAEvent() : void {
        super._colleagueA && super._colleagueA.doSomething();
        super._colleagueB && super._colleagueB.doSomething();
        console.log('A-B執行完畢');
    }

    public doColleagueBEvent() : void {
        super._colleagueB && super._colleagueB.doSomething();
        super._colleagueA && super._colleagueA.doSomething();
        console.log('B-A執行完畢');
    }
}


function main() {
    const mediator : Mediator = new ConcreteMediator();
    const myColleagueA : ConcreteColleagueA = new ConcreteColleagueA(mediator);
    const myColleagueB : ConcreteColleagueB = new ConcreteColleagueB(mediator);
    mediator.colleagueA = myColleagueA;
    mediator.colleagueB = myColleagueB;

    myColleagueA.onEvent('A');
    myColleagueB.onEvent('B');
}

main();

4.7 備忘錄模式

class Originator {
    private _state : string = '';
    constructor() {}

    get state() {
        return this._state;
    }

    set state(value) {
        this._state = value;
    }

    // 建立一個備忘錄
    public createMemento() : Memento {
        console.log('建立了一個備忘錄!');
        return new Memento(this._state);
    }

    // 恢復一個備忘錄
    public recoverMemento(memento : Memento) {
        console.log('恢復了一個備忘錄!');
        this.state = memento.state;
    }
}

class Memento {
    private _state : string;
    constructor(state : string) {
        this._state = state;
    }

    get state() : string {
        return this._state;
    }
}

class Caretaker {
    // 保存一次狀態用此,保存屢次用數組
    private memento ?: Memento;

    public getMemento() : Memento | undefined {
        return this.memento;
    }

    public setMemento(memento : Memento) {
        this.memento = memento;
    }
}

function main() {
    // 定義發起人
    const originator : Originator = new Originator();
    // 定義守護者
    const caretaker : Caretaker = new Caretaker();
    // 建立一個備忘錄
    const memento : Memento = originator.createMemento();
    // 將備忘錄存儲到守護者
    caretaker.setMemento(memento);
    // 恢復一個備忘錄
    originator.recoverMemento(memento);
}

main();

4.8 解釋器模式

// 如下是一個規則檢驗器實現,具備 and 和 or 規則,經過規則能夠構建一顆解析樹,用來檢驗一個文本是否知足解析樹定義的規則。

// 例如一顆解析樹爲 D And (A Or (B C)),文本 "D A" 知足該解析樹定義的規則
abstract class Expression {
    public abstract interpreter(str : string) : boolean;
}

class TerminalExpression extends Expression {
    private literal : string;
    constructor(str : string) {
        super();
        this.literal = str;
    }

    public interpreter(str : string) : boolean {
        for (let charVal of str) {
            if (charVal === this.literal) {
                return true;
            }
        }

        return false;
    }
}

class AndExpression extends Expression {
    private expression1 : Expression;
    private expression2 : Expression;

    constructor(expression1 : Expression, expression2 : Expression) {
        super();
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    public interpreter(str : string) : boolean {
        return this.expression1.interpreter(str) && this.expression2.interpreter(str);
    }
}

class OrExpression extends Expression {
    private expression1 : Expression;
    private expression2 : Expression;

    constructor(expression1 : Expression, expression2 : Expression) {
        super();
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    public interpreter(str : string) : boolean {
        return this.expression1.interpreter(str) || this.expression2.interpreter(str);
    }
}

function buildInterpreterTree() {
    const terminal1 : Expression = new TerminalExpression('A');
    const terminal2 : Expression = new TerminalExpression('B');
    const terminal3 : Expression = new TerminalExpression('C');
    const terminal4 : Expression = new TerminalExpression('D');

    // B And C
    const alternation1 : Expression = new AndExpression(terminal2, terminal3);
    // A Or (B C)
    const alternation2 : Expression = new OrExpression(terminal1, alternation1);
    // D And (A Or (B C))
    return new AndExpression(terminal4, alternation2);
}

function main() {
    const define : Expression = buildInterpreterTree();
    const context1 : string = "D A";
    const context2 : string = "D B C";
    console.log(define.interpreter(context1));
    console.log(define.interpreter(context2));
}

main();

4.9 狀態模式

abstract class State {
    public abstract handle1() : void;
    public abstract handle2() : void;
}

class ConcreteState1 extends State {
    private context : Context;
    constructor(context : Context) {
        super();
        this.context = context;
    }

    // 本狀態下須要處理的邏輯
    public handle1() : void {
        console.log('State1的狀態須要處理的邏輯');
    }

    // 將進行狀態轉移
    public handle2() : void {
        this.context.currentState = this.context.STATE2;
        console.log('由狀態state1轉爲state2');
    }
}

class ConcreteState2 extends State {
    private context : Context;
    constructor(context : Context) {
        super();
        this.context = context;
    }

    // 進行狀態轉移
    public handle1() : void {
        this.context.currentState = this.context.STATE1;
        console.log('由狀態state2轉爲state1');
    }

    // 本狀態下的處理邏輯
    public handle2() : void {
        console.log('State2的狀態須要處理的邏輯');
    }
}

class Context {
    public STATE1 : State = new ConcreteState1(this);
    public STATE2 : State = new ConcreteState2(this);
    public currentState : State;

    constructor() {
        this.currentState = this.STATE1;
    }

    public doOperation1() {
        this.currentState?.handle2();
    }
    public doOperation2() {
        this.currentState?.handle1();
    }
}

function main() {
    const context : Context = new Context();
    context.doOperation1();
    context.doOperation2();
}

main();

4.10 策略模式

interface Strategy {
    // 策略模式運算法則
    doSomething() : void;
}

class ConcreteStrategy1 implements Strategy {
    public doSomething() : void {
        console.log('使用的策略1');
    }
}

class ConcreteStrategy2 implements Strategy {
    public doSomething() : void {
        console.log('使用的策略2');
    }
}

class ContextofStrategy {
    private _strategy : Strategy;
    constructor(strategy : Strategy) {
        this._strategy = strategy;
    }

    set strategy(strategy : Strategy) {
        this._strategy = strategy;
    }

    //封裝後的策略方法
    doOperation() : void {
        this._strategy.doSomething();
    }
}

function main() {
    const strategy1 : Strategy = new ConcreteStrategy1();
    const strategy2 : Strategy = new ConcreteStrategy2();
    const context : ContextofStrategy = new ContextofStrategy(strategy1);
    context.doOperation();
    context.strategy = strategy2;
    context.doOperation();
}

main();

4.11 職責鏈模式

abstract class Handler {
    // 下一個處理者
    public successor ?: Handler;
    public name : string;
    constructor(name : string) {
        this.name = name;
    }

    public abstract handleRequest(request : MyRequest) : void;

    public setNext(successor : Handler) : void {
        this.successor = successor;
    }
}

class ConcreteHandler1 extends Handler {
    constructor(name : string) {
        super(name);
    }

    public handleRequest (request : MyRequest) : void {
        // 首先判斷當前級別是否可以處理,不可以處理則交給下一個級別處理
        if (request.level <= 1) {
            console.log('被一級處理');
        } else {
            // 交給下一級處理
            this.successor && this.successor.handleRequest(request);
        }
    }
}

class ConcreteHandler2 extends Handler {
    constructor(name : string) {
        super(name);
    }

    public handleRequest (request : MyRequest) : void {
        // 首先判斷當前級別是否可以處理,不可以處理則交給下一個級別處理
        if (request.level > 1 && request.level <= 2) {
            console.log('被二級處理');
        } else {
            // 交給下一級處理
            this.successor && this.successor.handleRequest(request);
        }
    }
}

class ConcreteHandler3 extends Handler {
    constructor(name : string) {
        super(name);
    }

    public handleRequest (request : MyRequest) : void {
        // 首先判斷當前級別是否可以處理,不可以處理則交給下一個級別處理
        if (request.level > 2) {
            console.log('被三級處理');
        } else {
            // 交給下一級處理
            this.successor && this.successor.handleRequest(request);
        }
    }
}

class MyRequest {
    private _level : number;
    constructor(level : number) {
        this._level = level;
    }

    get level() : number {
        return this._level;
    }

    set level(value : number) {
        this._level = this.level;
    }
}

function main() {
    // 建立一個請求
    const request : MyRequest = new MyRequest(5);

    // 建立相關處理人
    const handler1 : Handler = new ConcreteHandler1('lili');
    const handler2 : Handler = new ConcreteHandler2('linlin');
    const handler3 : Handler = new ConcreteHandler3('shunshun');

    // 設置下級別審批,構成環形結構
    handler1.setNext(handler2);
    handler2.setNext(handler3);
    handler3.setNext(handler1);

    handler1.handleRequest(request);
}

main();
相關章節<br/>
圖解JavaScript————基礎篇<br/>
圖解JavaScript————進階篇<br/>

歡迎你們關注公衆號(回覆「設計模式」獲取本節的思惟導圖,回覆「書籍」獲取大量前端學習資料,回覆「前端視頻」獲取大量前端教學視頻)
前端

相關文章
相關標籤/搜索