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();