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

发布于 2024-07-24 07:02:35 字数 622 浏览 10 评论 0原文

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

I'm trying to convince a colleague that a function should take an interface as a parameter, and not the object itself. I think small objects can be fine to pass across, but for large ones I would give them an interface and just pass the i/f over, not the whole thing.

Note that there will only ever be one of these large classes - the i/f will never be used for a different object. This is merely for hiding the implementation of an object.

Would you agree that separating a large class into an interface(s) is good practice?
Are there any disadvantages to doing this?

Example:

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(); }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

只是一片海 2024-07-31 07:02:35

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

对接口编程,而不是对
实施。

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

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

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

One of the first principles you learn in OO development:

Program to an interface, not an
implementation.

You indicate that "there will only ever be one of these large classes - the i/f will never be used for a different object". This might be true in your case, but I wish I had a nickel for every time such a statement turned out to be wrong.

In addition to considering whether there might be multiple implementations of your interface, you should also consider whether your concrete object exports (or might export) additional methods that do not share a logical affinity with the operations declared in the interface. In such a case, you could simply declare the additional operations in one or more additional interfaces. A client, then, need only couple with the interface that exports the operations in which it is interested.

Put simply, interfaces provide a means of managing the coupling between clients and providers.

情场扛把子 2024-07-31 07:02:35

依赖倒置原则可以总结为:依赖抽象更好比结核。

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

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

The Dependency Inversion Principle can be summed up as: It is better to depend on abstractions than concretions.

It's almost always better to pass an interface than it is to pass a concrete class.

That said, high cohesiveness against internal types is ok within a particular module, but that's very subjective as to when and how you should pass concrete objects.

羁绊已千年 2024-07-31 07:02:35

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

I'd prefer to avoid creating and interface for the sake of creating an interface. If you can use that interface in more than one place, then you have a winner - or if this is a public function and class and you specifically want to simplify.

梦毁影碎の 2024-07-31 07:02:35

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

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

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

If you pass an implementation, you kind of loose one of the advantages of using interfaces, meaning separating the logic from the actual implementation.

The interface of a software module A
is deliberately kept separate from the
implementation of that module. The
latter contains the actual code of the
procedures and methods described in
the interface, as well as other
"private" variables, procedures, etc..
Any other software module B (which can
be referred to as a client to A) that
interacts with A is forced to do so
only through the interface. One
practical advantage of this
arrangement is that replacing the
implementation of A by another one
that meets the same specifications of
the interface should not cause B to
fail—as long as its use of A complies
with the specifications of the
interface (see also Liskov
substitution principle).

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

年少掌心 2024-07-31 07:02:35

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

The other issue is your very large class itself. This may not be within the scope of what you're doing, but a very large class implies that it might be doing too much in the first place. Can you refactor it into smaller classess, where the information required within the function you're calling is encapsulated in its own smaller class? If you create an interface against that class you may find it that much more re-usable than against the very large class you currently have.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文