2016-06-17 28 views
0

创建接口这是第一个想到的,而读Interface Implementation (Interface Segregation Principle)接口实现 - 中参数

思想

介绍那会表示方法的参数而不是传递各个参数值​​,新的界面我得到了。如下图所示:

interface IServiceProviderInput 
{ 
    string Username { get; } 
    string Password { get; } 
    string AgentId { get; } // XYZServiceProvider needs this. 
    // Similarly add props here to represent new parameters 
    // required by future service provider implementations. 
} 

interface IServiceProvider 
{ 
    bool Authenticate(IServiceProviderInput parameters); 
} 

class ABCServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

class EFGServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

class XYZServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

问题

请问这是否有意义,或者什么都在这个破绽?有什么想法吗?

编辑

又一想增加更多的特定接口的XYZ提供商:

interface IServiceProviderInput 
{ 
    string Username { get; } 
    string Password { get; } 
} 

interface IXYZServiceProviderInput : IServiceProviderInput 
{ 
    string AgentId { get; } 
} 

class XYZServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IXYZServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

这可能是两种想法是不正确的或有缺陷,我不知道,因此问题。

+0

为什么输入属性有setter?这对我来说很奇怪。您希望服务提供商能够更改输入的属性值吗? – recursive

+0

@recursive服务不会设置它们。调用代码如何设置参数值呢? – niksofteng

+1

调用代码不需要通过此接口专门访问它们。界面的目的是通过责任将相关操作分组在一起。如果这个责任是作为一种输入,那么接口上就不需要一个setter。但这并不意味着setter不能存在于实现或更多派生的接口上。 要使用另一个示例,即使您可以在“List ”上,也不能'将一个项目添加到'IEnumerable '。 – recursive

回答

2

你当然可以做到这一点,但除非所有的方法接受和需要所有参数定义的参数是一个可怕的想法。不要将更多的信息传递给一个方法,否则你不知道什么是工作所需要的,什么不是来自界面。

+0

因此,为了仅提供需要的参数,我提到了思想#2,其中创建了'IXYZServiceProviderInput',但是对于多种方法来说,这样做会更糟或不切实际。那么我们是否认为这实际上是个坏主意,应该严格避免?或等待更多人的想法? – niksofteng

+0

您可能最终会为每个方法参数提供接口。我敢肯定有人会争辩说“做出伟大的单元测试”,但没有具体的理由要做,我不会推荐它。现在,如果我们真的关注OOP,并说所有这些函数都需要一个IPerson并从概念上对IPerson数据起作用,那么它就更加可以接受,但即使如此,您也希望避免在方法可能意外失败的状态下构建一个Person对象的路径,因为用户忘记设置一些领域,没有明显的方法让他们知道是必需的。 –

0

我唯一的问题与你的实现是为什么你使用XYZServiceProvider相同的身份验证方法,但没有实现您定义的接口IServiceProvider

问题是,当您有客户端正在呼叫IServiceProvder进行身份验证时,他们将无法使用XYZServiceProvider,但只能使用其他两个。如果他们想要使用XYZServiceProvider,他们需要按名称(紧密耦合)来指定它。

如果你要更改您的程序,然后从XYZServiceProvider切换到EFGServiceProvider用,那么个人用户还需要改变他们的代码,使他们能够使用新的供应商进行认证。当试图为您的服务创建单元测试时,这是特别麻烦的,因为您将不得不单独创建XYZServiceProvider的测试装置。

如果您打算为XYZServiceProvider提供备用服务类型,我建议您创建另一个接口,如用于其他服务的IServiceProvider

+0

啊,你在我发布我的答案之前就改变了它。这是更好 – ghg565

+0

我改变了它发布你的答案,否则我不会重新思考我错过了。你认为以前的代码版本是有效的。感谢您指出了这一点。你现在对于更新和最终的代码有什么想法? – niksofteng

+0

我仍然认为XYZServiceProvider应该实现IServiceProvider接口。该参数仍然是IServiceParameterInput类型,因此这将允许您对“IServiceProvider.Authenticate(IServiceProviderInput参数)”进行身份验证,然后将具体内容保留在实现中。 – ghg565