【问题标题】:ES6 class and class instance as parameter in constructorES6 类和类实例作为构造函数中的参数
【发布时间】:2018-08-16 06:59:10
【问题描述】:

A 类需要 B 类的实例。 我应该在 A 构造函数中创建 B 实例,还是在启动 A 类的位置创建实例并将实例传递给 A 构造函数?

A 计划:

class A { constructor() { this.b = new B(); } }

B计划:

const b = new B();

class A() { 
    constructor(b) { 
        this.b = b; 
    }
}

const a = new A(b);

【问题讨论】:

  • 理想情况下,A 类应该在需要时在内部创建 B 类的实例。使用 A 类的代码不需要知道该类需要什么依赖
  • 我会说计划 B,因为它对管理依赖注入很有用
  • plan B 很有帮助]
  • 如前所述,这只是一个见仁见智的问题。我真的取决于这些类将如何使用。例如,A 的调用者传递除B 之外的任何内容是否有用?他们是否需要与B 互动?
  • 这个问题实际上无法正确回答,因为您所问的方法完全取决于上下文。

标签: javascript class ecmascript-6


【解决方案1】:

如果

,计划 A 是可以的
  • B 类以后不应被 C 类替换

  • B 类未使用某些外部依赖项,如 ajax 或数据库或其他。

或

  • 您的申请是概念验证,或者您真的有时间限制

B 计划适用于所有其他情况。

它可以让你灵活地动态改变你的 A 类行为,提供更多的通用性,通过模拟这种依赖关系来帮助测试。

所以我会说计划 A 是关于简单性的,计划 B 是关于灵活性和测试的。在每个当前案例中选择您需要的任何内容

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您的 B 计划绝对是更好的方法,因为它使您的 class A 更加灵活,并消除了对 class B 工作方式的依赖。

    【讨论】:

      【解决方案3】:

      第一种策略适用于两个类之间的关系,如果没有彼此的确切形式,它们就毫无意义,并且子实例没有任何特殊特征,否则手动提供它们会有任何好处。

      后一种注入类依赖的策略要灵活得多。这在类型化语言中更为明显,您可以清楚地定义描述对象“外观”而不是实际实现的类抽象或接口,例如使用 TypeScript:

      class Process {
        private storage: StorageInterface;
      
        constructor(storage: StorageInterface) {
          this.storage = storage;
        }
      }
      
      interface StorageInterface {
        store(data: any): Promise<void>;
      }
      

      这里很明显,Process 期望一个提供函数 store 的东西的实例,但它并不关心实际的实现是什么样子 - 由实现 StorageInterface 的类决定:

      class PostgresStorage implements StorageInterface {
        public async store(data: any): Promise<void> {
          // do some postgres query
        }
      }
      
      class FilesystemStorage implements StorageInterface {
        public async store(data: any): Promise<void> {
          // store in the filesystem
        }
      }
      

      现在我们可以完全灵活地决定我们希望 Process 的实例使用什么类型的“存储”,而不是由它自己管理它能够使用的存储,能够创建无限的存储类型而无需修改其余的代码库和更清晰的 Process 正在与之交互的内容。

      // A process that stores something in a Postgres instance.
      const processA: Process = new Process(new PostgresStorage());
      
      // A process that stores something on the filesystem.
      const processB: Process = new Process(new FilesystemStorage());
      

      【讨论】:

        【解决方案4】:

        JS 世界中的 OO 方法与强类型经典语言中的方法有些不同。也许这次平台的改变是一个很好的机会,可以让你重新审视你的思维方式,即如何重用并在考虑到构图的情况下更横向地思考。

        https://en.wikipedia.org/wiki/Composition_over_inheritance

        【讨论】:

          猜你喜欢
          • 2016-09-16
          • 2019-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-26
          • 1970-01-01
          • 2018-07-19
          • 2020-05-10
          相关资源
          最近更新 更多