【问题标题】:Implement interface in methods (the best practice)在方法中实现接口(最佳实践)
【发布时间】:2018-08-29 15:55:48
【问题描述】:

我有一些回调接口:

public interface FooCallback {
    boolean doSomething(Foo fooArg);
}

在服务层的方法中作为匿名块实现:

public void methodA(Bar barArg) {
    // some business logic like parsing Foo object from Bar for example

    FooCallback cb = new FooCallback() {
        @Override
        public boolean doSomething(Foo fooArg) {
            // some calculation with fooArg and barArg and return boolean value
        }
    }
    saveBar(barArg, cb);
}

saveBar 是该类中的方法,用于将 Bar 对象保存到数据库中取决于 FooCallbackdoSomething 方法的结果;

public void saveBar(barArg, cb) {
    // get Foo object from database

    if (cb.doSomething(fooFromDB)) {
        // save barArg into DB
    } else {
        // antother logic
    }
}

我的服务类中有很多方法,例如methodA。匿名代码块也很难测试。你能告诉我类似实现的最佳实践是什么吗?我想将内容从doSomething 移动到另一个方法,但这意味着每个方法都将是 self methodCallback。你怎么看?我正在使用java。谢谢你的建议。

【问题讨论】:

    标签: java oop design-patterns interface anonymous-class


    【解决方案1】:

    你说得对,匿名块样式会使测试复杂化,这就是我在这种情况下不推荐它的原因。如果您想尽可能接近您所概述的方法,请创建一个实现 FooCallback 的类,然后将该类的一个实例作为参数提供给包含 methodA() 和 saveBar() 的任何类的构造函数。您不会丢失任何东西,而且您可以选择在测试期间提供具有不同 doSomething() 实现的模拟实例。

    我说您是否愿意喜欢,因为我不确定整个 FooCallback 方法在给定示例中提供了什么优势。如果您完全删除该类及其匿名实现,并且只让 methodA() 返回一个用于确定是否应使用 saveBar() 的布尔值,似乎一切都会更好地组织起来。为什么要创建一个完整的接口只是为了包含一个返回布尔值的方法,而不是直接在 FooSaveHandler 或其他所有调用中处理它?

    编辑以进行评论:

    如果您需要在不同情况下调用 Foo 的 A-X 不同的逻辑集,并且您有有条件地调用这些单独的 A-X 方法的逻辑,为什么不做一些更简单的事情呢?

    handleFooBarLogic(Foo foo){
        boolean saveBar = false;
        //Logic that originally called methodA()
        if(something) {
            return saveBar = doSomethingOriginallyFromMethodA(foo);
        }
        //etc.
        return saveBar
    }    
    
    saveBar(Bar bar) {
           //Just saves a Bar
        }
    

    如果我们谈论的是最佳(或至少更好)的做法,那么您的 saveBar() 所做的远不止保存 Bar,而且到那时应该已经确定需要保存 Bar。从该前提向后工作完全消除了对回调的需要,以及随之而来的接口。你最终会得到一个很大的 if 语句,但至少事情更容易测试,并且最终更容易理解发生了什么。

    【讨论】:

    • 问题是每个方法A,B,C,...X都有不同的doSomething实现,但是由于多态性我们需要该接口并在传递的FooCallback实例上调用doSomething。
    猜你喜欢
    • 2016-07-17
    • 1970-01-01
    • 2017-03-21
    • 2020-09-18
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多