接口是否涵盖了每种公共方法的良好做法?

时间:2014-02-28 13:11:33

标签: oop design-patterns coding-style solid-principles

通过接口定义类的实现是一种很好的做法。如果某个类具有任何接口未涵盖的公共方法,则它们可能会泄漏其实现。

E.g。如果类Foo包含方法bar()baz()但接口只涵盖bar(),那么baz()的任何使用都不会使用接口。

感觉想要获得更清晰的代码,这对任何一个都有意义:

  • 如果类必须具有这些方法(例如,单独的接口来覆盖上面baz()的行为),则创建额外的接口。
  • 或理想的重构(例如使用更多组合),因此该类不需要有这么多方法(将baz()放在另一个类中)

界面未涵盖的方法感觉就像代码味道。或者我是不现实的?

3 个答案:

答案 0 :(得分:2)

我认为它是“过度使用”界面。

接口只允许您访问有限的功能,因此最好将更多具有类似功能的类集合到一个List<Interface>并使用它们,例如。

或者如果你想保持松散耦合原则,你宁愿给另一个组件一些接口而不是整个类。

另外一些类应该限制访问另一个类,也可以通过接口来完成。

然而,高内聚原则(通常与松散耦合相关联)并不会阻止您使用类本身,如果两个类是并且应该“强”相互连接。

答案 1 :(得分:1)

我认为这不是接口的目的。如果你真的在谈论类之间的'is-a'和'has-a'关系,那么类不一定需要涵盖接口中的所有公共方法。这就像把概念推得太远了。

一个类可以有描述它行为的方法但是,有些方法并不能完全描述类的行为,而是描述类可以做什么。

如果出现关于“可以做”行为的SRP问题,该类可能会使用组件来执行这些行为而不是在其自身内实现。

例如,我有一个类DataGrid,为什么我需要一个名为IDataGrid的接口来公开所有公共方法。但可能是DataGrid可以执行的其他功能,即导出数据。在这种情况下,我可以让它实现IExportData,并实现ExportData方法,而该方法又不导出数据,而是使用实际完成工作的组件,比如DataExportHelper。 DataGrid仅将数据传递给组件。

我不认为在上面的例子中会违反SRP。

编辑:

我是.Net开发人员,所以希望从MS库类中为您提供示例。例如,类System.Windows.Window没有实现任何具有Close()方法的接口。我不明白为什么它应该成为任何主持人的一部分。

此外,有些东西可能看起来像代码味道,但不一定可能是错误的。代码味道本身并不意味着存在问题,但存在问题的可能性。 我从未在软件设计中遇到任何原则或指南,其中提到类的所有公共成员都需要在某个或其他界面中公开。可能这样做只是为了它可能是一个糟糕的设计。

答案 2 :(得分:0)

不,我绝对不会考虑代码嗅到的界面未涵盖的方法。

看起来这可能依赖于您正在构建的对象基础结构,但在我熟悉的基础结构中,接口的真正意义在于提供一种可管理的多重继承形式。我认为过度使用多重遗传是一种值得注意的气味。

至少在.NET中,抽象类显然是公开抽象(不是接口)的首选构造。 .NET设计指南说:支持在接口上定义类。,这里描述了基本原理http://msdn.microsoft.com/en-us/library/vstudio/ms229013(v=vs.100).aspx

即使在COM中(必须在接口中定义任何外部可见功能),也有充分理由使用非公开函数:限制实现细节的可见性。 COM最初是在C(不是C ++)中定义的,它缺少更新语言所拥有的更丰富的访问修饰符集,但其概念是:发布的接口成员是公共的,其他一切都是内部的。