使用带有 Typescript 的参数字符串选择和实例化 Class

Picking and Instancing a Class using a parameter String with Typescript

这是我第一次使用 TypeScript 和 OOP。 我已经为常见的经纪人方法创建了一个接口。 (买入,卖出,卖出限价,买入限价)

然后我与我的经纪人 API 实现了这个接口。 GBM、Bitso、IB、AmeriTrade 等我想通过接收到的字符串在我的端点实例化正确的 class

示例:“/api/broker/:brokername” 所以我创建了以下代码:

class BrokerIgniter {
    
    private instance: any;

    constructor(broker: string) {

        const brokerClass: any = this.pick(broker);
        if(brokerClass) {
            this.run(brokerClass);
        }
    }

    run(ctor: new () => IExecution | IGBMExecution) {
        this.instance = new ctor();
    }

    pick(className: string) {
        const magicWand: { [K: string]: any } = {
            GBM: GBMBroker,
         };
         if (magicWand[className]) {
            return magicWand[className];
        }
        return null;
    }

    get execute() {
        return this.instance;
    }

}

pick 方法中的“magicWand 变量包含一个 classes 列表,它在我的 express post 中实现了我的通用接口(在这种情况下,目前只有一个..)方法:

const BrokerName = req.params.broker;
if(BrokerName) {
    const Broker = new BrokerIgniter(BrokerName);
    const hash = Broker.execute.createOrderHash('SPXL *', 100, 1);

    super.sendSuccess(res, hash, 'fine');
}

我的问题是:

这是制作我想要的东西的好方法吗? 有这个名字或模式吗? 可以改进吗?

如果有这个或模式的名称,您可以给它命名,以便我可以了解更多吗?我一直在检查 javascript 模式,但没有找到与此相关的内容。

干杯。

您似乎希望能够传入 string 作为代理密钥,因为这是来自 API 输入。

这意味着您可以在 BrokerIgniter class 之外声明支持的 classes 及其键的列表(尽管静态字段也可以)。

// Sort of guessing at your types here since your example is incomplete.
const brokers: Record<
  string,
  typeof IExecution | typeof IGBMExecution | undefined
> = {
  GBM: GBMBroker
}
这里的

brokers被打成以任意字符串为索引,return一个IExecution构造函数,一个IGBMExecution构造函数,或者undefined如果他们的键没有值。

现在BrokerIgniter可以简单地变成这样:

class BrokerIgniter {
    private instance: IExecution | IGBMExecution | undefined;

    constructor(broker: string) {
        const brokerClass = this.pick(broker);
        if(brokerClass) {
            this.run(brokerClass);
        }
    }

    run(ctor: new () => IExecution | IGBMExecution) {
        this.instance = new ctor();
    }

    pick(className: string) {
        return brokers[className] ?? null
    }

    get execute() {
        return this.instance;
    }
}

Playground


也就是说,这似乎有点过分了。这基本上是相同的代码。

function igniteBroker(brokerKey: string) {
  const brokerClass = brokers[brokerKey]
  return brokerClass ? new brokerClass() : null
}

而且简单多了。也许您打算对 BrokerIgniter class 进行大量扩展。但如果没有,那么简单的函数式方法将为您提供更好的服务。

Playground