如何正确设计界面

时间:2016-11-25 02:35:19

标签: java design-patterns interface

我有两节课。我们称他们为PostClassCommentClass。这两个类都实现了Reportable接口:

public interface Reportable {

    void report();

    boolean isReported();

    . . .

现在我需要为每个类添加两个额外的方法。这些方法在逻辑上适合相同的接口,但需要具有不同的名称。例如:

PostClass会有方法 - > remove()restore()

CommentClass会有方法 - > hide()show()

问题:设计此更改的首选方法是什么?我认为这些选项是:

  1. 创建一个扩展Reportable接口的附加接口。 问题:界面太多
  2. 将所有四个新方法添加到Reportable接口中,然后在每个类中保留不相关的两个方法。 问题:不整洁/丑陋

4 个答案:

答案 0 :(得分:2)

如果他们做同样的事情,那么组成包含该功能的名称;虽然这听起来不像你想要的现有名称。

选项3:创建两个新接口RemovableHideable,并让每个类实现适当的接口。

第二个想法,我可能会建议使用hide()show(),因为这似乎可以捕捉到最好的情况。

答案 1 :(得分:1)

不要担心有更多的接口,只要它们的用途和目的明确。这两个选项有效:

  1. PostClass实施RemovableReportable,扩展Reportable;和 CommentClass实施HideableReportable,其范围为Reportable

  2. PostClass同时实现ReportableRemovable;和 CommentClass同时实现ReportableHideable

  3. 但是将所有四个新方法添加到Reportable接口并在每个类中保留两个未实现的方法非常错误,因为它不会导致代码干净且易于理解并使用。开发人员必须了解在每种情况下使用哪种方法,从而使您的代码更难以使用和修改。如果一些开发人员调用错误的方法会发生什么?如果错误的方法什么也不做,错误可能会被忽视。如果它抛出异常,这只会在运行时捕获错误。如果它调用另一种方法,那么你有两种方法可以做同样的事情,这也是糟糕和令人困惑的。

    界面中未使用的方法是代码气味,可能表明存在设计缺陷。

答案 2 :(得分:0)

虽然这个问题很可能被归类为基于意见的,但我的方法仍然是在界面中添加两个方法(show()hide())并让类实现它。

以下是其他几个选项:

如果您使用的是JDK8,可以尝试在界面中添加上述两种方法default-methods,这样它就不会立即破坏现有的实现。

另外,显然可以从接口中的默认方法调用抽象方法,因此技术上可以有两个通用命名的抽象方法和两个(或者另外四个)特别命名为默认方法但是过度杀戮只会增加混乱。

您可以考虑共有六种新方法。 showhide是抽象的,showPost / hidePostshowCommenthideComment是默认类,而后者又会调用抽象{{1}分别和show。这样,即使某个实现类错误地调用了错误的别名,它仍会调用正确的实现(理论上)。

答案 3 :(得分:0)

无论我在这个答案中描述什么,纯粹是我的观点和主观。

在设计时,必须牢记以下要点

  1. 添加到Reportable(或通常任何超类型)的任何方法都应适用于所有子类型。
  2. 一个方法应该描述一个类的行为,这个类能够做什么'。
  3.   

    第2点解释

    考虑方法postClass.remove(),可以将其视为' A PostClass知道如何删除...'。但删除什么?本身?从哪里来?

    对我来说,'删除'并且'恢复/添加'似乎可以在Collection PostClassCommentClass上完成,而不是这些类自己做的事情。如果我猜对了,确实是这样的,你必须在应用程序中使用PostClassCommentClass(即某种类型的Collection)。现在,PostClassCommentClass可以获得回调onRemove()onRestore()onHide()onShow()来执行必要的操作删除/恢复/隐藏/显示时的每个动作。

    回调的优势是,如果某个班级在行动期间不打算做某些特别的事情,则可以选择致电super

      

    设计1 - Reportable具有隐藏,显示,恢复和删除的行为

    因此,对于所有报告'在您的应用程序中,您可以将这些回调添加到Reportable界面本身。

    public interface Reportable {
        void report();
        boolean isReported();        
        void onRestore();
        void onRemove();
        void onHide();
        void onShow();
    }
    

    用法可能是这样的

    public class User {
        private List<Reportable> reports;
        //... more User related code
    
       public void deleteReport(Reportable report) {
           //give report a chance to cleanup
           report.onDelete();
           //delete from user's list of reports
           this.reports.remove(report);
           //more code
       }
    
      

    设计2 - 具有单独的接口

    public interface Viewable {
        void onHide();
        void onShow();
    }
    
    public interface Disposable {
        void onRemove();
        void onRestore();
    }
    
    public class PostClass implements Reportable, Disposable {
    
    }
    
    public class CommentClass implements Reportable, Viewable {
    
    }
    

    我猜这种用法非常自我解释。

    我更喜欢设计2 ,因为它看起来更干净,并且坚持 SOLID &#39;设计原则。

    希望这有帮助。