oop - 具有可选功能的框架接口(interface)的接口(interface)隔离原则

标签 oop design-patterns interface frameworks

我正在设计一个身份验证框架。我需要框架的用户来实现数据访问逻辑,因为它不是框架的主要目的,并且我想允许多种数据访问方法(SQL、NoSQL、缓存等),但我不在我的框架内实现它。我的框架通过一个名为 IUserStore 的接口(interface)使用此逻辑,但问题是,我的接口(interface)内有某些方法仅在某些功能处于事件状态时使用,否则不使用。例如,仅当启用了双因素身份验证时,框架才会尝试通过 GetTwoFactorInfo 方法访问双因素信息。

我的问题是关于接口(interface)隔离原则。是否可以保留界面原样,并在文档中解释仅当用户想要使用双因素身份验证时才需要实现 GetTwoFactorInfo 并抛出 NotImplementedException 否则?或者我应该为每个可选功能单独提供接口(interface),并在文档中解释用户应该实现该接口(interface)并向服务提供商注册以便能够使用该功能?第二种方法的问题是,当将实现这些接口(interface)的服务注入(inject)构造函数时,我需要检查这些功能是否处于事件状态,否则我会收到错误,因为服务未注册,并且我正在尝试从服务提供者访问这些服务。这导致我的框架类变得额外复杂。

处理这个问题的最佳方法是什么?

最佳答案

您建议的两种方法都存在实际问题,但让客户端抛出 NotImplementedException 的计划要糟糕得多。

让我们来看看它们:

选项 1

leave the interface as it is and explain in the documentation that user needs to implement GetTwoFactorInfo only if user wants to use two factor authentication and throw NotImplementedException otherwise

嗯,这可能适用于您今天遇到的问题,但软件设计是关于您明天将遇到的问题。如果您在框架的 future 版本中添加对不同身份验证方法的支持,会发生什么?如果您遵循此模式,那么您将向 IUserStore 添加新方法...但这会破坏现有客户端,因为它们不会实现它们!

在某些语言中,您可以通过为抛出异常的新方法提供默认实现来解决这个特定问题,但这违背了定义接口(interface)的大部分目的——类型系统不再告诉客户端什么他必须执行。

此外,此模式仅适用于预先存在的接口(interface)。如果您添加一个新的身份验证方法,要求客户端实现一个接口(interface),那么您就会回到考虑第二个选项之类的事情,然后您将得到不一致的版本控制策略组合。恶心。

选项 2

separate interface for each optional feature and explain in the documentation user should implement and register this interface to service provider to be able to use that feature

这要好得多,但也不是很好,因为它引入了框架的客户端必须遵循的隐藏规则。所有了解这些规则的方法都是令人沮丧的——阅读文档、排除错误等等。

尽管这是许多依赖注入(inject)系统中的常见问题,而且很多人似乎并不介意,但随着隐藏规则交互系统的积累,事情变得非常复杂。

选项 3

我现在不知道如何启用此 2 因素功能,但我建议您让您的客户通过调用将隐含依赖项作为参数的方法来启用此功能,例如

void enable2FactorAuth(I2FactorInfoStore store)

然后所有的隐藏规则都消失了。您的系统确保您无法启用该功能,除非您已实现所需的接口(interface)。简单。

如果您认为自己将无法在不编程的情况下配置产品,那么我想提醒您,您拥有该功能。正如您所说,客户端必须编写一些代码才能使用两因素身份验证。他们必须实现商店。要求他们调用一个方法来启用它只会改进这段代码,因为现在很明显为什么他们必须首先实现该存储。

关于oop - 具有可选功能的框架接口(interface)的接口(interface)隔离原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64068527/

相关文章:

design-patterns - "implementing an interface"到底是什么意思?

ruby-on-rails - Rails AngularJS 多态最佳实践

java - 像 Gmail 应用程序一样的 Android Studio 抽屉导航

Java接口(interface)扩展题

java - 阻止要扩展的接口(interface)

c# - 使用 Reflection.Emit 创建一个实现接口(interface)的类

swift - 一个服务应该调用另一个服务还是应该获取它自己的数据

java - 如何访问私有(private)包类的公共(public)成员?

oop - 多重继承批评

python - 如何正确地将计算与渲染解耦