7

我试图说服一位同事,函数应该将接口作为参数,而不是对象本身。我认为小对象可以很好地传递,但对于大对象,我会给它们一个接口,只是传递 i/f,而不是全部。

请注意,这些大类中只会有一个——i/f 永远不会用于不同的对象。这仅仅是为了隐藏对象的实现。

你同意将一个大类分成一个接口是好的做法吗?
这样做有什么缺点吗?

例子:

public interface class IVeryLargeClass
{
    void DoSomething();
    ...
};

public ref class VeryLargeClass : public IVeryLargeClass
{
public:
    virtual void DoSomething() { ... }
    ...
};

public ref class AnotherClass
{
public:
    AnotherClass(VeryLargeClass^ vlc)  { vlc->DoSomething(); }
 // OR
    AnotherClass(IVeryLargeClass^ vlc) { vlc->DoSomething(); }
};
4

5 回答 5

13

您在 OO 开发中学到的首要原则之一:

编程到接口,而不是实现。

您指出“这些大类中只会有一个 - i/f 永远不会用于不同的对象”。在你的情况下这可能是正确的,但我希望每次这样的陈述被证明是错误的时候我都能得到一分钱。

除了考虑您的接口是否可能有多个实现之外,您还应该考虑您的具体对象是否导出(或可能导出)与接口中声明的操作不共享逻辑亲和性的其他方法。在这种情况下,您可以简单地在一个或多个附加接口中声明附加操作。那么,客户端只需要与导出它感兴趣的操作的接口相结合。

简而言之,接口提供了一种管理客户端和提供者之间耦合的方法。

于 2009-06-16T18:04:08.970 回答
9

依赖倒置原则可以概括为:依赖抽象比依赖具体要好。

传递接口几乎总是比传递具体类更好。

也就是说,在特定模块中,对内部类型的高内聚性是可以的,但是对于何时以及如何传递具体对象,这是非常主观的。

于 2009-06-16T18:02:00.393 回答
3

如果你传递一个实现,你就会失去使用接口的优势之一,这意味着将逻辑与实际实现分开。

软件模块 A 的接口故意与该模块的实现分开。后者包含接口中描述的过程和方法的实际代码,以及其他“私有”变量、过程等。 A 只能通过接口强制执行此操作。这种安排的一个实际优点是,将 A 的实现替换为满足相同接口规范的另一个实现不会导致 B 失败——只要它对 A 的使用符合接口的规范(另见 Liskov 替换原则)。

http://en.wikipedia.org/wiki/Interface_(computer_science)

于 2009-06-16T18:05:26.067 回答
3

为了创建接口,我宁愿避免创建和接口。如果您可以在多个地方使用该接口,那么您就有了赢家——或者如果这是一个公共函数和类并且您特别想简化。

于 2009-06-16T18:06:12.073 回答
1

另一个问题是你非常大的班级本身。这可能不在你正在做的事情的范围内,但是一个非常大的类意味着它可能首先做的太多了。你能把它重构成更小的类,你调用的函数中所需的信息被封装在它自己的更小的类中吗?如果您针对该类创建一个接口,您可能会发现它比针对您当前拥有的非常大的类更具可重用性。

于 2009-06-17T10:20:12.243 回答