包没有硬依赖

时间:2018-01-06 11:17:05

标签: typescript

我正在创建一个基于IObservable接口提供一些抽象的包。为此,我需要两个外部类,其作用类似Subject<T>中的BehaviorSubject<T>rxjs

同时,我不想将我的包与rxjs结合,我想允许其他实现这些接口的包也适合。

我想出了this solution。它适用于我,但我想我可以依赖import语句的行为吗?

那是因为我认为import被提升并且所有都是异步执行的。如果在某些情况下myLibrary将在rxjs和全局设置之前导入,该怎么办?

编辑:

我决定使用init({Subject, ...other_types})函数并更新链接中的要点。现在工作流程如下所示:

import {some_types} from 'some_package'
import {init} from 'myLib'

init(some_types)

// ... now the consumer can import the rest from myLib and use it

我仍然对import s的顺序有疑问,但这是另一个故事......

1 个答案:

答案 0 :(得分:0)

有些SOLID principles可以提供帮助:

  • 界面隔离→在您自己的界面中定义您的需求,可能是Subject<T>BehaviorSubject<T>的条款,但只是您正在使用的内容。
  • 依赖性倒置→依赖于这些抽象类型而不是RxJs类型。应用程序的其余部分将与RxJs分离。
  • TypeScript支持结构类型,如果这些接口与RxJs类型兼容,则第二个可以用作应用程序中的依赖项。否则,需要一些包装器。

使用ES6模块和静态导入,所有模块将按正确的顺序加载(除非有一些奇怪的模块加载器/捆绑器配置)。在以下示例中subjects.ts之后无法加载RxJ (已编辑)

// -- subjects.ts ----
export interface Subject<T> { /*...*/ }
export interface BehaviorSubject<T> { /*...*/ }

// -- create-subjects.ts ----
import * as rx from 'rxjs/Rx';
import { Subject, BehaviorSubject } from './subjects.ts';

// Subject<T> and rx.Subject<T> are compatible
export function createSubject<T>(): Subject<T> {
    return new rx.Subject<T>();
}

// BehaviorSubject<T> and rx.BehaviorSubject<T> are not compatible => wrapper
export function createBehaviorSubject<T>(value: T): BehaviorSubject<T> {
    const wrappee = new rx.BehaviorSubject(value);
    return {
        suscribe: (callback: Function) => wrappee.suscribe(callback),
        /*...*/
    };
}

// -- consumer.ts ----
import { createSubject } from './create-subjects.ts';

const subject = createSubject<string>();
// ...

现在可以轻松切换到另一个流库,只需修改一个文件:create-subjects.ts,提供的XxxSubject接口已经过精心设计,以满足应用程序的自定义需求(问题中缺少这些,所以我现在无法提供更好的例子)而不仅仅是RxJs的副本。