在方法中实现接口(最佳实践)

时间:2018-08-29 15:55:49

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

我有一些回调接口:

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

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

public void methodA(Bar barArg) {
    // some bussiness 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对象保存到数据库中的方法取决于doSomething的{​​{1}}方法的结果;

FooCallback

我的服务类中有很多类似public void saveBar(barArg, cb) { // get Foo object from database if (cb.doSomething(fooFromDB)) { // save barArg into DB } else { // antother logic } } 的方法。匿名代码块也是不好测试的。您能告诉我类似实施的最佳实践是什么吗?我知道将内容从methodA移到另一个方法,但这意味着每个方法都是self methodCallback。你怎么看?我正在使用Java。谢谢你的建议。

1 个答案:

答案 0 :(得分:0)

您是对的,匿名块样式会使测试复杂化,这就是为什么我在这种情况下不推荐这样做的原因。如果您想尽可能地接近于您概述的方法,请创建一个实现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语句,但是至少事情更容易测试,并且最终更容易理解正在发生的事情。