13

サードパーティのライブラリ クラスに依存するサービスを実装する良い方法を見つけようとしています。また、ライブラリが利用できない場合や回答を提供できない場合に備えて、フォールバックとして使用する「デフォルト」の実装もあります。

public interface Service {

    public Object compute1();

    public Object compute2();
}

public class DefaultService implements Service {

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

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

サービスの実際の実装は次のようになります。

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();
        }
    }
}

現在の実装は、サービスへの実際の呼び出しのみが異なるという点で少し重複しているように見えますが、try/catch とデフォルトのメカニズムはほとんど同じです。また、サービスに別のメソッドが追加された場合、実装はほとんど同じになります。

コードの見栄えを良くし、追加のコピーと貼り付けを少なくするために、ここ ( proxystrategy ) に適用できる設計パターンはありますか?

4

3 に答える 3

3

プロキシはおそらくここであなたを助けることができます. 以下の例はテストされていませんが、何を配置できるかについてのアイデアを提供するはずです。

public class FallbackService implements InvocationHandler {

    private final Service primaryService;
    private final Service fallbackService;

    private FallbackService(Service primaryService, Service fallbackService) {
        this.primaryService = primaryService;
        this.fallbackService = fallbackService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            Object result = method.invoke(primaryService, args);
            if (result != null) return result;
        } catch (Exception ignore) {}
        return method.invoke(fallbackService, args);
    }

    public static Service createFallbackService(Service primaryService, Service fallbackService) {
        return (Service) Proxy.newProxyInstance(
                Service.class.getClassLoader(),
                new Class[] { Service.class },
                new FallbackService(primaryService, fallbackService)
        );
    }
}
于 2015-04-26T11:24:39.783 に答える