gpt4 book ai didi

oop - 接口(interface)实现(接口(interface)隔离原则)

转载 作者:行者123 更新时间:2023-12-02 02:36:18 31 4
gpt4 key购买 nike

我遇到了一种情况,我需要调用第三方服务来获取一些信息。这些服务对于不同的客户可能会有所不同。我的界面中有一个身份验证功能,如下所示。

interface IServiceProvider {

bool Authenticate(string username, string password);
}

class ABCServiceProvider : IserviceProvider
{
bool Authenticate(string username, string password) { // implementation}
}

class EFGServiceProvider : IserviceProvider
{
bool Authenticate(string username, string password) { // implementation}
}

等等...现在我遇到了一个服务提供商(比如说 XYZServiceProvider),它需要一些附加信息(agentid)进行身份验证。像这样的东西...

class XYZServiceProvider
{
bool Authenticate(string username, string password, int agentid) { // implementation}
}

现在,如果我在接口(interface)中提供另一个具有 3 个参数的 Authenticate 函数,并在除 XYZServiceProvider 之外的所有类中抛出未实现的异常,是否会违反接口(interface)隔离原则?我在代码的其他部分也有类似的情况。谁能告诉我实现这种场景的最佳方法是什么?我真的会非常感激。

最佳答案

解决这个问题的最好方法可能是在接口(interface)中要求 agentId,并且在 ABC 和 DEF 不需要它的情况下简单地忽略它。这样,消费阶层仍然不会知道其中的区别。

实际上,如果要互换使用 ABC、DEF 和 XYZ 提供程序,则最重要的是里氏替换原则; “给定类 X 依赖的类 A,X 应该能够使用从 A 派生的类 B,而不知道其中的区别”。

接口(interface)隔离原则基本上说接口(interface)不应包含其任何使用者不需要的成员,因为如果这些成员的定义发生更改,甚至不使用该方法的类都必须重新编译因为他们所依赖的接口(interface)已经改变了。虽然这是相关的(如果添加重载,则必须重新编译 IServiceProvider 的所有使用者),但如果更改 Authenticate() 的签名,则无论如何都必须这样做,并且从维护的角度来看更紧迫的问题是,如果您添加了 Authenticate() 的重载,您的消费者现在必须知道他们需要使用哪个重载。这要求您的消费类了解公共(public)接口(interface)实现之间的差异,从而违反了 LSP。提供比特定提供者需要的更多信息从来都不是问题,但是在仅提供两个输入的用法中使用 XYZ 就会出现问题。为了避免这些问题,您总是会使用三参数重载,那么为什么要使用两参数重载呢?

现在,如果 IServiceProvider 当前的使用是在没有也不关心 agentId 的区域,因此很难开始提供它,那么我会推荐一个具体 XYZ 提供程序插入的适配器,它实现您当前的 IServiceProvider,并通过其他方式提供 agentId 使新提供程序像旧提供程序一样工作:

public class XYZAdapter: IServiceProvider
{
private readonly XYZServiceProvider xyzProvider;
public XYZAdapter(XYZServiceProvider provider)
{
xyzProvider = provider;
}

public void Authenticate(string username, string password)
{
xyzProvider.Authenticate(username, password, GetAgentId());
}

public int GetAgentId()
{
//Retrieve the proper agent Id. It can be provided from the class creator,
//retrieved from a known constant data source, or pulled from some factory
//method provided from this class's creator. Any way you slice it, consumers
//of this class cannot know that this information is needed.
}
}

如果可行,则同时满足LSP和ISP;不必更改接口(interface)即可支持 LSP,因此可以防止 ISP 通常试图避免的情况(重新编译和重新分发依赖项)。但是,它增加了类数量,并强制 Adapter 中的新功能正确获取所需的 agentId,而无需依赖它通过 IServiceProvider 接口(interface)提供任何它不知道的内容。

关于oop - 接口(interface)实现(接口(interface)隔离原则),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7852418/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com