前言
在前一篇文章桥接模式与策略模式的区别与刘伟老师的桥接模式中,我们可以明白桥接模式处理得比较好的一个点是在于Java的反射机制。
那么,假如我们需要再TypeScript中,来实现桥接模式的处理,需要怎么样来实现这个“反射”呢?
注:在策略模式中,该文章的处理全部适用。
思路
反射机制:就是要实现通过一个Key值来创建一个类。
那么在TypeScript中,普通的对象就有key:value的这样的格式,然后TypeScript编译后的源代码是JavaScript,而JS的类创建是通过原型对象来创建的。所以可以利用这样的关系,把TypeScrip中的类(在JS中变现为原型对象),保存在一个普通对象里。
注:普通对象可以用例子变现为:let ClassStorage= {};其中ClassStorage就是我们所说的普通对象。
实现思路需要的类
我们需要
代理类:ProxyClass,来实现从Key转化为具体对象的类。
存储类:StorageClass,用来保存我们的类。
这两个类是实现桥接模式中,反射机制的核心。
然后接下来,需要有模拟桥接模式的测试类,来完成桥接模式的闭环。
测试类:Test,用来通过反射调用不同的类。
被调用基类:ClassBase,定义接口,在Test类中调用。
被调用派生类:***Classs,定义具体行为。
具体代码
ProxyClass.ts:
import { ClassStorage } from "./ClassStorage";
export class ProxyClass {
/**
* 代理构建方法
* @param className 动态类名称
* @param option 动态类创建参数
*/
static getClass(className: string, option?: any) {
//一个简单的异常判断,如果存储类中不存在此类 则抛出异常提醒
if (ClassStorage[className] === undefined || ClassStorage[className] === null) {
console.warn(`未找到 className:${className} 对应实现`);
return null;
}
//从存放对象上找出对应class 创建即可
return new (ClassStorage[className])(option)
}
static checkValidClass(className: string) {
//一个简单的异常判断,如果存储类中不存在此类 则抛出异常提醒
if (ClassStorage[className] === undefined || ClassStorage[className] === null) {
return null;
}
//从存放对象上找出对应class 创建即可
return className
}
}
ClassStorage.ts:
export let ClassStorage: any = {};
Test.ts:
import { ClassBase } from "./ClassBase";
import { ProxyClass } from "./ProxyClass";
export class Test {
constructor() {
// 因为创建的是ProxyClass 类型 所以需要 as 进行类型断言
// 这样ts就可以进行友好提示了!
this.createClass("AClass");
this.createClass("BClass");
this.createClass("CClass");
}
createClass(type: string): ClassBase {
let a: ClassBase = new ProxyClass(type);
a.test();
}
}
ClassBase.ts:
export abstract class ClassBase {
abstract test(): void;
}
AClass.ts:
import { ClassStorage } from "./ClassStorage";
import { ClassBase } from "./ClassBase";
export class AClass extends ClassBase {
test(): void {
console.log("this is AClass");
}
}
ClassStorage["AClass"] = AClass;
BClass.ts:
import { ClassStorage } from "./ClassStorage";
import { ClassBase } from "./ClassBase";
export class BClass extends ClassBase {
test(): void {
console.log("this is BClass");
}
}
ClassStorage["BClass"] = BClass;
CClass.ts:
import { ClassStorage } from "./ClassStorage";
import { ClassBase } from "./ClassBase";
export class CClass extends ClassBase {
test(): void {
console.log("this is CClass");
}
}
ClassStorage["CClass"] = CClass;