Java后备模式

use*_*657 12 java fallback design-patterns strategy-pattern proxy-pattern

我正在尝试找到一种实现依赖于第三方库类的服务的好方法.如果库不可用或无法提供答案,我还有一个'默认'实现用作后备.

public interface Service {

    public Object compute1();

    public Object compute2();
}

public class DefaultService implements Service {

    @Override
    public Object compute1() {
       // ...
    }

    @Override
    public Object compute2() {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

该服务的实际实现将是这样的:

public class ServiceImpl implements Service {
    Service defaultService = new DefaultService();
    ThirdPartyService thirdPartyService = new ThirdPartyService();

    @Override
    public Object compute1() {
        try {
            Object obj = thirdPartyService.customCompute1();
            return obj != null ? obj : defaultService.compute1();
        } 
        catch (Exception e) {
            return defaultService.compute1();
        }
    }

    @Override
    public Object compute2() {
        try {
            Object obj = thirdPartyService.customCompute2();
            return obj != null ? obj : defaultService.compute2();
        } 
        catch (Exception e) {
            return defaultService.compute2();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当前的实现似乎重复了一些事情,只有对服务的实际调用是不同的,但try/catch和默认机制几乎相同.此外,如果在服务中添加了另一种方法,则实现看起来几乎相似.

是否存在可能适用于此处的设计模式(代理,策略)以使代码看起来更好并且进一步添加更少的复制粘贴?

fgb*_*fgb 3

您可以使用方法引用将公共逻辑提取到单独的方法中,例如:

public class ServiceImpl implements Service {
    Service defaultService = new DefaultService();
    ThirdPartyService thirdPartyService = new ThirdPartyService();

    @Override
    public Object compute1() {
        return run(thirdPartyService::customCompute1, defaultService::compute1);
    }

    @Override
    public Object compute2() {
        return run(thirdPartyService::customCompute2, defaultService::compute2);
    }

    private static <T> T run(Supplier<T> action, Supplier<T> fallback) {
        try {
            T result = action.get();
            return result != null ? result : fallback.get();
        } catch(Exception e) {
            return fallback.get();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)