Language agnostic 将*接口*或*对象*作为参数传递给函数更好吗?

Language agnostic 将*接口*或*对象*作为参数传递给函数更好吗?,language-agnostic,oop,parameters,interface,information-hiding,Language Agnostic,Oop,Parameters,Interface,Information Hiding,我试图说服一位同事,函数应该将接口作为参数,而不是对象本身。我认为小对象可以通过,但对于大对象,我会给它们一个接口,只传递I/f,而不是全部 请注意,这些大型类中只有一个—i/f永远不会用于不同的对象。这仅仅是为了隐藏对象的实现 您是否同意将大型类拆分为接口是一种良好的做法? 这样做有什么缺点吗 例如: public interface class IVeryLargeClass { void DoSomething(); ... }; public ref class Ver

我试图说服一位同事,函数应该将接口作为参数,而不是对象本身。我认为小对象可以通过,但对于大对象,我会给它们一个接口,只传递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(); }
};
其原因可以总结为:依赖抽象比依赖具体更好

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


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

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

编程到一个接口,而不是一个 实施

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

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


简单地说,接口提供了一种管理客户机和提供者之间耦合的方法。

如果通过了一个实现,那么就失去了使用接口的优势之一,这意味着将逻辑与实际实现分离

软件模块a的接口 故意将其与 该模块的实施。这个 后者包含 中所述的程序和方法 界面,以及其他 “私有”变量、过程等。。 任何其他软件模块B(可以 被称为a)的客户 与强制执行此操作的用户进行交互 只有通过接口。一个 这种方法的实际优势 安排是更换 由另一个执行一个 符合相同规格的 接口不应导致B 只要其使用符合 符合 接口(另见Liskov 替代原则)


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

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

但是对于接口,您可以通过模拟接口来测试代码。在许多语言中(尤其是C语言),你不能有效地模仿一个具体的类。@Randolpho-这是一个很好的观点。我要注意的是,接口并没有达到荒谬的程度,也没有以特别的方式创建。作为设计的一部分,它们需要有意义。这也是一个很好的观点。归根结底,我的经验法则是,如果一个类要被其模块之外的东西使用,它会得到一个接口。如果它只在内部使用(即它是一个helper类或类似的东西),则它不需要接口,但通常可以从所有方法都是虚拟的(便于模拟)中获益。总的来说,我认真对待契约式设计。下面的回答很好,但你应该明白,对象的“大小”与这个主题无关。“大”类或“小”类与本讨论无关。该接口用于隐藏实现。这根本不是一个性能问题。@Bill-我同意你的观点,大小无关紧要(ahem)。在这种情况下,我只是用一个大型类来说明如何将一个大型对象传递给一个可能需要在其中使用一两个函数的类。另一个角度是,使用接口可以减少构建时间。在传递对象的示例中,向VeryLargeClass添加一个私有函数将导致重建另一个类。然而,在传递接口的情况下,除非实际接口发生更改,否则不需要重建另一个类。