将* interface *或* object *作为参数传递给函数会更好吗?

时间:2009-06-16 18:00:08

标签: language-agnostic oop parameters interface information-hiding

我试图说服一位同事,一个函数应该将接口作为参数,而不是对象本身。我认为小对象可以很好地传递,但是对于大对象,我会给它们一个接口,只是传递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(); }
};

5 个答案:

答案 0 :(得分:12)

您在面向对象开发中学到的第一个原则之一:

  

编程到界面,而不是   实施

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

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

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

答案 1 :(得分:7)

Dependency Inversion Principle可以概括为:最好依赖于抽象而不是结核。

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

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

答案 2 :(得分:3)

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

  

软件模块A的界面   故意与...分开   该模块的实施。该   后者包含了实际的代码   中描述的程序和方法   界面,以及其他   “私人”变量,程序等。   任何其他软件模块B(可以   被称为A)的客户   与A的交互被迫这样做   只能通过界面。一   这个的实际优势   安排是取代   另一个实施A.   符合相同规格的   界面不应该导致B到   失败 - 只要它的使用符合   与规格   界面(另见Liskov   替代原则)。

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

答案 3 :(得分:3)

为了创建界面,我宁愿避免创建和界面。如果你可以在多个地方使用该界面,那么你就有了胜利者 - 或者如果这是一个公共功能和类,你特别希望简化。

答案 4 :(得分:1)

另一个问题是你的大班本身。这可能不在你正在做的范围内,但是一个非常大的类意味着它可能在一开始就做得太多了。你可以将它重构为较小的classess,你所调用的函数中所需的信息是否封装在它自己较小的类中?如果您创建一个针对该类的接口,您可能会发现它比您当前拥有的非常大的类更具可重用性。