当前位置: 首页 > 知识库问答 >
问题:

扩展的OOP/Typescript替代方案,在依赖项中维护父上下文

太叔京
2023-03-14

我创建了一个类EventBus。这个类提供了一个接口,用于将on/off/once方法附加到一个类上,扩展它的类可以反过来提供一个可以被监听的可能事件的数组。

目前,为了使其工作,我需要使用EventBus扩展类。我觉得这不是正确的方法;

class Something extends EventBus {
   private events: Array<string> = [
    'ready',
  ];

  constructor() {
    this.registerEventBus(this.events);
  }
}

EventBus使用方法而不是构造函数初始化,但也可以使用构造函数;

class EventBus {
  private eventListeners: EventListeners = {};

  registerEventBus(eventListenersArray: Array<string> = []) {
    eventListenersArray.forEach((listener) => {
      this.eventListeners[listener] = [];
    });
  }
  ...on, off, supporting private methods etc

我想知道正确的方法是什么。我觉得使用EventBus扩展某些东西不是正确的继承,EventBus是一个使用的依赖项。我的问题是事件应该是可链接的,在每次调用后返回正确的上下文;

const someInstance = new Something();

someInstance
  .on('ready', () => {})
  .on('destroyed', () => {});

目前,我正在努力找到一个解决方案,可以使用typescript,我知道应该注入它,但我没有这样做。如果有人知道我应该采取的方法的正确术语,或者我可以用来绕过<code>扩展

共有1个答案

宦兴朝
2023-03-14

是的,你是对的,发布订阅者模式不应该被继承以通过应用程序使用。可以使用 ioc 容器或创建事件总线的单个实例。

TypeScript中的单例模式示例:

class MyEventBus
{
    private static _instance: MyEventBus;

    private constructor()
    {
        //...
    }

    public static get Instance()
    {
        // Do you need arguments? Make it a regular static method instead.
        return this._instance || (this._instance = new this());
    }
}

并像这样使用它:

const MyEventBusInstance = MyEventBus.Instance;

可在此处查看创建事件总线的单个实例的示例

更新:

如果您希望每个类实例都有一个事件总线实例,则可以在类中创建事件总线实例:

class Something  {
    eventBus: EventBus

    constructor() {
        this.eventBus = new EventBus;
    }
}

更新1:

如果您希望EventBus通过类的层次结构可用,则可以创建类的一些层次结构。E、 g.“动物”、“狗”并在基类“动物”中声明事件总线。这样,方法将在所有派生类型中可用。

class EventBus {
    runMe() {
        console.log("EventBus is run!");
    }
}

class Animal {
  eventBus: EventBus = new EventBus();

  move(distanceInMeters: number = 0) {
    console.log(`Animal moved ${distanceInMeters}m.`);
  }
}
 
class Dog extends Animal {
  bark() {
    console.log("Wooof! Wooof! Wooof!");
  }
}

然后像这样运行它:

const dog = new Dog();
dog.bark(); // "Wooof! Wooof! Wooof!" 
dog.move(11); // "Animal moved 11m."
dog.eventBus.runMe() // "EventBus is run!"

更新2:

如果你想拥有可链接的方法,那么你可以使用流畅的接口模式。让我展示一个代码示例:

class EventBus {
    onFoo(eventName: string) {
        console.log("EventName is: ", eventName);
        return this;
    }
}

class Animal extends EventBus {
  eventBus: EventBus = new EventBus();

  move(distanceInMeters: number = 0) {
    console.log(`Animal moved ${distanceInMeters}m.`);
    this.onFoo("Hello").onFoo("World").onFoo("!"); // fluent interface pattern
  }
}
 
const dog = new Animal();
dog.move(10);
 类似资料:
  • 我正在Wordpress中实现一个主题。此主题有一个顶部导航菜单,每个父项下都有水平子菜单。它将“活动”类放在当前已查看的父项上(否则不会显示其子菜单项)。通过在函数中使用这两个函数,我设法在当前父项上维护“活动”类。php。 但是现在我的问题是,当我点击任何父菜单项的子菜单或子菜单项时,它成功地将我带到子页面,但从父菜单中删除“活动”类,并将其放在子菜单项上(因为它是当前查看的页面)。我不希望它

  • 我已经阅读了这个问答,我了解到有一些实用程序库实现了基类中缺少的东西。是否有实现的库类? 例如,我需要执行

  • 我有两个类(实际上是一个基类和许多其他类)。我希望获得子类中的父上下文,而不必每次都填充回< code>super()。它的基本目标是把我的角分量分成多个类。我会试着做一个例子 如您所见,我无法检索<code>这个。canvas并使用它,是否有任何解决方法。我知道我可以将画布传递到方法中,但我更希望像组件中一样使用<code>this<code>关键字来访问全局上下文。 所以基本上我想做的是: 任

  • Fluentd 是另一个 Ruby 语言编写的日志收集系统。和 Logstash 不同的是,Fluentd 是基于 MRI 实现的,并不是利用多线程,而是利用事件驱动。 Fluentd 的开发和使用者,大多集中在日本。 配置示例 Fluentd 受 Scribe 影响颇深,包括节点间传输采用磁盘 buffer 来保证数据不丢失等的设计,也包括配置语法。下面是一段配置示例: <source> t

  • heka 是 Mozilla 公司仿造 logstash 设计,用 Golang 重写的一个开源项目。同样采用了input -> decoder -> filter -> encoder -> output 的流程概念。其特点在于,在中间的 decoder/filter/encoder 部分,设计了 sandbox 概念,可以采用内嵌 lua 脚本做这一部分的工作,降低了全程使用静态 Golang

  • 本节作者:松涛 nxlog 是用 C 语言写的一个跨平台日志收集处理软件。其内部支持使用 Perl 正则和语法来进行数据结构化和逻辑判断操作。不过,其最常用的场景。是在 windows 服务器上,作为 logstash 的替代品运行。 nxlog 的 windows 安装文件下载 url 见: http://nxlog.org/system/files/products/files/1/nxlog