gpt4 book ai didi

c# - 是否应该在接口(interface)中声明所有公共(public)方法?

转载 作者:太空宇宙 更新时间:2023-11-03 22:34:11 25 4
gpt4 key购买 nike

给定如下界面:

public interface IFoo
{
string Bar();
}

还有一个实现它的类:

public class Foo : IFoo
{
public string Bar()
{
returns "Bar";
}

public string SomeOtherMethod()
{
returns "Something else";
}
}

这段代码有问题吗?我们是否应该将所有方法都添加到接口(interface)中?

一个例子:想象一个私有(private)方法变得复杂到需要单元测试。您能否将其公开(以便可以从测试项目中调用它)但不将其添加到接口(interface)中(因为没有客户端需要调用它)?

最佳答案

如果一个类做的事情足够简单,我们可以同时测试它的公共(public)方法和私有(private)方法,那么我们可以只测试公共(public)方法。

如果私有(private)方法变得如此复杂以至于在公共(public)方法和私有(private)方法之间我们需要太多的测试组合,那么是时候将私有(private)方法分离到它自己的类中了。公开私有(private)方法会破坏类的封装。即使我们不将方法添加到 interface,将类方法设为 public 仍然会将方法添加到类本身的公共(public)接口(interface)

所以如果我们有这个:

public class ClassWithComplexPrivateMethod
{

public void DoSomething(int value)
{
PrivateMethodThatNeedsItsOwnTests(value);
}

private string PrivateMethodThatNeedsItsOwnTests(int value)
{
// This method has gotten really complicated!
return value.ToString();
}
}

我们可能会重构为这样的东西:

public interface IRepresentsWhatThePrivateMethodDid
{
string MethodThatNeedsItsOwnTests(int value);
}

public class RefactoredClass
{
private readonly IRepresentsWhatThePrivateMethodDid _dependency;

public RefactoredClass(IRepresentsWhatThePrivateMethodDid dependency)
{
_dependency = dependency;
}

public string DoSomething(int value)
{
return _dependency.MethodThatNeedsItsOwnTests(value);
}
}

现在一个新类实现了 IRepresentsWhatThePrivateMethodDid

现在,当我们测试重构的类时,我们模拟 IRepresentsWhatThePrivateMethodDid,并且我们为任何实现 IRepresentsWhatThePrivateMethodDid 的类编写单独的单元测试。

将私有(private)方法公开为公共(public)方法会破坏封装,但将其作为自己的独立类公开则不会,这似乎是自相矛盾的。有两个区别:

  • 重构后的类不依赖于包含以前私有(private)方法的新类。这取决于新界面。
  • 重构后的类和接口(interface)之间的交互仍然隐藏在它的方法中。调用其公共(public)方法的其他类并不“知道”它如何使用其依赖项。 (事实上​​,其他类可能会依赖于抽象而不是直接依赖于重构的类。)

当我们本可以通过公共(public)方法测试该类(包括其私有(private)方法)时,也很容易被它冲昏头脑并过早引入单独的依赖项。我已经这样做过很多次了,它会导致很多很多不必要的接口(interface)和额外的类。没有完美,只有我们尽最大努力来平衡它。


还有一个想法:我们倾向于使用接口(interface)来表示依赖关系,但我们不必这样做。如果我们提取的只是一个私有(private)方法,那么也许我们可以用委托(delegate)或 Func 来表示它,如下所示:

public class RefactoredClass
{
private readonly Func<int, string> _dependency;

public RefactoredClass(Func<int, string> dependency)
{
_dependency = dependency;
}

public string DoSomething(int value)
{
return _dependency(value);
}
}

或者我们可以使用委托(delegate),我比 Func 更喜欢它,因为它指示函数的作用。

关于c# - 是否应该在接口(interface)中声明所有公共(public)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55942632/

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