1

想象一组代表一些 API 的库。通过使用控制机制的反转,具体的实现将被注入到一个消费项目中。

这是一种情况。我有一些 API 库依赖于某些功能的其他 API 库 - 因此 API 库本身在某些时候是耦合的。这种耦合以后可能会成为一个问题,因为改变一个API会导致依赖的API发生变化,相应的实现也需要改变,所以最坏的情况是我们最终需要相当多的项目修改以反映仅其中一个的变化形式。

现在我想到了两种可能的解决方案:

  • 创建一个统一相关 API 库的单体 API 项目。

  • 通过使每个库为依赖于其他 API 的所有功能提供接口来进一步解耦 API ,从而消除直接依赖关系。这可能会导致两个库中的代码相似,但可以自由选择通过 IoC 机制选择的实现,还允许 API 彼此独立改进(当 API 发生更改时,更改将仅影响其实现库,而不影响其他 API 或其实现)。

第二种方法的问题是代码重复,结果可能是需要引用的 api 库过多(例如,在 .NET 应用程序中,每个 API 将是一个单独的 DLL。在某些情况下,例如 Silverlight应用程序,这可能是应用程序大小的问题 - 下载时间和客户端整体性能)。

有没有更好的解决方案。什么时候将一些 API 库合并成一个更大的库更好,什么时候不合并?我知道这是我要问的一个非常普遍的问题,但是让我们暂时忽略到期日期、估计、客户要求和技术,我希望能够基于实现最大可扩展性和最短维护时间来确定正确的方法。那么,选择这两种方法或您可能建议我的另一种方法的充分理由是什么?

编辑:

我觉得我必须澄清一下这个问题。我考虑将 API 彼此分离,而不是将 API 与其实现分离。因此,例如,如果我有用于验证访问权限的安全 API,以及使用(引用)安全 API 的用户帐户 API,则更改安全 API 将需要更改用户帐户 API 以及它们的实现。以这种方式耦合的 API 越多,必须应用的更改就越多。这是我想要避免的。

4

3 回答 3

4

选择是在几个大型图书馆和无数小型图书馆之间。

  • 如果您有一个庞大的库,那么其中的代码将倾向于紧密耦合,因为没有压力以松散耦合的方式设计各种元素。风险在于,该库的发展变得越来越难,因为必须协调如此多的相互依赖关系。以 .NET 基类库为例。
  • 如果你有无数的小库,你可能会冒dll hell的风险。是的,我们在很多年前就被承诺这一切都结束了,但事实并非如此。只需尝试在您的应用程序代码库中使用大量细粒度的开源库,您就会明白我的意思。

尽管如此,单一职责原则也适用于包级别,所以我推荐小型、专注的库而不是大型通用库。这也使得始终选择最佳库变得更加容易。

小库总是可以组合/编译成更大的库(在 .NET 中使用 Assembly Linker / Merger / Repacker 实用程序),而拆分大库要困难得多。

无论您做什么,要记住的最重要的事情是向后兼容性。您引入的重大更改越少,这些库就越容易管理。

于 2012-02-02T21:21:23.567 回答
1

我不认为这是一个问题,真的。一些库将依赖于其他库,这对我来说很好:改进一个库将改进所有依赖项!库的“所有者”有责任在进行更改时不破坏现有代码,但这是正常的,如果代码设计良好,可以轻松处理。

于 2012-02-02T14:09:08.243 回答
1

如果您的所有相关代码都发生了变化,您应该重新考虑您的设计。如果您的库显示某个 API,它应该将其使用者与对底层类或库的更改隔离开来。


更新1:

如果您的应用程序将 Library1 与 API1 一起使用,则不必处理 Library1 使用 Lib2、Lib3、..、LibX 的事实。

例如,Moq 模拟库依赖于 CastleDynamicProxy。你为什么要关心这个?你得到一个已经合并了 DynamicProxy 的程序集,你可以只使用 Moq。您永远不会看到、使用或不必关心 DynamicProxy。因此,如果 DP API 发生变化,这不会影响您使用 Moq 编写的测试。Moq 将您的代码与底层 DP 的 API 更改隔离开来。

更新 2:

发现一个对多个分支有效的问题会导致对所有分支的修改

如果是这种情况,您不会构建一个库,而是一个非常具体的问题的帮助者,永远不要强加于其他项目。共享库倾向于退化为“可能在遥远的未来某处有用”的集合。不!这将永远咬你在一个**!如果您对不止一个地方(如Guard课堂)发生的问题有解决方案:分享它。如果你相信你可能会找到一些解决问题的方法:把它留在项目中,直到你真正遇到这种情况。然后分享一下。永远不要“以防万一”。

于 2012-02-02T14:32:39.443 回答