0

假设我们正在制作一个解析器。一种实现可能是:

public sealed class Parser1
{
    public string Parse(string text)
    {
       ...
    }
}

或者我们可以将文本传递给构造函数:

public sealed class Parser2
{
    public Parser2(string text)
    {
       this.text = text;
    }

    public string Parse()
    {
       ...
    }
}

这两种情况的用法都很简单,但是与另一种情况相比,启用参数输入意味着什么?Parser1当他们查看 API 时,我向其他程序员发送了什么信息?此外,在某些情况下是否有任何技术优势/劣势?

当我意识到接口在第二个实现中毫无意义时,另一个问题出现了:

public interface IParser
{
    string Parse();
}

...第一个接口上的接口至少可以达到某种目的。这是否特别表示某个类是否“可接口”?

4

2 回答 2

2

这两种情况的用法都很简单,但是与另一种情况相比,启用 Parser1 的参数输入意味着什么?

如果在构造函数中指定参数,则意味着该参数将在整个类中使用。如果在 setter 方法中指定参数,则意味着在创建类的实例时可能不知道参数的值。

这是一个需要 setter 方法的真实示例。

public class A {
    private B b;
}

public class B {
    private A a;
}

假设类 A 和 B 具有所有适当的 getter 和 setter。构造函数是两个类的空构造函数。

为了初始化这两个类,您必须编写如下所示的代码。

A a = new A();
B b = new B();
a.setB(b);
b.setA(a);

这是否特别表示某个类是否“可接口”?

通常,当可以有多个满足接口要求的具体类时,您编写一个接口。

例如,在 Java 中,List接口由ArrayList和实现LinkedList

编写接口的另一个原因是您希望建立具体类必须实现的所需方法,即使只编写一个具体类。

有时,抽象类是定义基类的更好方法。这取决于您要完成的工作。

于 2013-06-04T19:50:34.907 回答
0

通常,即使您只有一个实现,接口也是一个好主意。它使您的代码更加灵活,特别是因为您可以采用依赖注入原则:在类的构造函数中注入具体实例。它使您的代码也非常可测试,并且您的类的用户知道会发生什么,也知道存在哪些依赖项。这样做可以让您将解析器注入其他类,例如:

public class Worker
{
    private IParser _parser;
    public Worker(IParser parser)
    {
        _parser=parser;
    }
}

针对接口进行编程还将您的代码与实际实现分离。例如:领域层中的类使用存储库接口;但对具体的存储库实现一无所知,因为它们是在运行时注入的。因此,该域独立于基础设施问题。

关于text参数:在您的情况下,操作的参数可能会更好Parse,因为它不会在该操作之外使用,并且您可以Parse使用不同的字符串多次调用该方法。如果您在构造函数中执行此操作,则意味着您可能会有多个可以使用它的操作,因此它更像是操作的全局变量。

于 2013-06-04T19:57:18.190 回答