TypeScript设计模式浅谈

本文介绍了三种常用的设计模式:工厂模式、单例模式和装饰器模式。工厂模式通过接口调用并传递类型来创建对象;单例模式确保一个类只有一个实例,并提供全局访问点;装饰器模式则用于扩展类的功能。

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

1.工厂模式

通常用于创建对象。使用一个共同的接口来指向新创建的对象

定义一个创建对象的接口,通过接口调用并传递类型来决定去实例化哪一个工厂类。

//工厂模式创建对象类型枚举
export enum DisplayType {
    ONE = 'ONE',
    TWO = "TWO"
}
export class BaseDisplay { baseInit() { } } //工厂对象实例基类
export class GemDisplayOne extends BaseDisplay { init() { } } //工厂对象实例2
export class GemDisplayTWO extends BaseDisplay { init() { } } //工厂对象实例1
//通过调用工厂类创建接口来具体实例化指定类型的对象类
export class DisplayFactory {
    public static build(type: DisplayType): BaseDisplay {
        let ret: BaseDisplay = null;
        switch (type) {
            case DisplayType.ONE: {
                ret = new GemDisplayOne;
                break;
            }
            case DisplayType.TWO: {
                ret = new GemDisplayTWO;
                break;
            }
        }
        return ret;
    }
};

2.单例模式

单一的类,负责自己创建自己的对象。

优点是在内存里只有一个实例,减少内存开销,避免频繁的创建和销毁实例。缺点是所有文件的处理都是采用的同一实例,要考虑多个线程同时调用的问题。

//单例模式
export default class GameManager {
    private static _me: GameManager;
    public static get me(): GameManager {
        if (GameManager._me == null) {
            GameManager._me = new GameManager();
        }
        return GameManager._me;
    }
    public func(): void { }
}
GameManager.me.func();//外部调用方法

3.装饰器模式

用来扩展类,监视类,修改类

a.类装饰器

//a.类装饰器 可修改被装饰类的原型
export function LogClass(params: any) {
    return function (target: any) {
        console.log(params);//装饰器中传入的值
        console.log(target);//被装饰的类本身
        target.prototype.testFunc = function () {//可以在target被装饰的类的原型上添加方法和属性
            console.log('I am testFunc');
            return true;
        }
    }
}

@LogClass("...")
class TestA { }
let objA = new TestA();
console.log(objA.testFunc()); //输出:I am testFunc 说明装饰器对被装饰类原型的修改成功

b.属性装饰器

//b.属性装饰器 可修改被装饰属性的值
function AttrClass(params: any) {
    return function (target: any, attr: any) {
        console.log(params);//装饰器中传入的值
        console.log(target);//被装饰的属性所在的类本身
        console.log(attr);//被装饰的属性 name
        target[attr] = params;//通过装饰器给name赋值
    }
}
class TestB {
    @AttrClass("111")
    public name: string | undefined;
    public getData() {
        console.log(this.name);
    }
}
let objB = new TestB();
console.log(objB.getData());//输出:111

c.方法装饰器

//c.方法装饰器
function Get(params: any) {
    return function (target: any, methodName: any, desc: any) {
        console.log(target);//被装饰的方法所在的类本身
        console.log(methodName);//getData 被装饰的方法的名字
        console.log(desc);//被装饰的方法的属性描述符

        //添加属性和方法
        target.addAttr = "我是修饰器添加的属性";
        target.run() = function () {
            console.log('我是修饰器添加的方法');
        }
    }
}
class TestC {
    public name: string | undefined;
    @Get('222')
    getData() {
        console.log(this.name);
    }
}
let objC = new TestC();
objC.getData();//输出:我是修饰器添加的属性
objC.run();//输出:我是修饰器添加的方法

*实用举例:装饰器判断游戏状态来中断游戏异步工作流

 适用于项目或引擎常驻 但需要中断全部异步流程的情况

export const GameStatusAsyncFlow = function (target: any, name: string, descriptor: any): any {
    const oldValue = descriptor.value;
    descriptor.value = function () {
        if (isGameUnset) {
            // 游戏被重置了
            const nextFunc = arguments[0];
            if (nextFunc && typeof (nextFunc) == 'function') {
                const err = new Error('The game has been reset!');
                return nextFunc.apply(this, [err]);
            } else {
                oldValue.apply(this, arguments);
            }
        }
        else {
            return oldValue.apply(this, arguments);
        }
    };
    return descriptor;
};

import * as async from 'async';
class TestD {
    constructor() {
        async.waterfall(
            [
                (next: Function) => {
                    this._step1(next, 'arguments');
                },
                (next: Function) => {
                    this._step2(next, 'arguments');
                }
            ],
            (err: Error) => {
                //装饰器抛出的Error将会在这里收到
                if (Error) {
                    console.warn(Error);
                    return;
                }
                //next...
            }
        )
    }
    @GameStatusAsyncFlow
    private _step1(next: Function, arguments: string): void {
        next();
    }

    @GameStatusAsyncFlow
    private _step2(next: Function, arguments: string): void {
        next();
    }
}
//test
new TestD();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值