以下に定義する言語翻訳用のインターフェースがあります。
public interface TranslationService {
public TranslationResult translate(TranslationRequeset req);
public int maxTranslatableCount();
}
また、次のように、Google、Bing ...などを使用したインターフェイスの実装がいくつかあります。
public class BingTranslationServiceImpl implements TranslationService {
public TranslationResult translate(TranslationRequeset req){}
public int maxTranslatableCount(){return 10000;}
}
public class GoogleTranslationServiceImpl implements TranslationService {
public TranslationResult translate(TranslationRequeset req){}
public int maxTranslatableCount(){return 2000;}
}
public class FooTranslationServiceImpl implements TranslationService {
public TranslationResult translate(TranslationRequeset req){}
public int maxTranslatableCount(){return 50000;}
}
次に、クライアント コードで、特定の翻訳サービスが失敗した場合にフェイルオーバーを実行する必要がありました。
それを実現するために、次のようにリストでフェイルオーバー戦略を定義する「TranslationProxy」を導入しました。
基本的に、特定のサービスが翻訳に失敗した場合、これはリストを反復処理します。
public class TranslationProxy implements TranslationService {
private List<TranslationService> services;
TranslationResult translate(TranslationRequeset req) {
//
}
public List<TranslationBusinessLogic> getServices() {
return services;
}
public void setServices(List<TranslationBusinessLogic> services) {
this.services = services;
}
}
次に、Spring 構成で、サービスの実装を次のように定義しました。
<bean id="bing" class="com.mycompany.prj.BingTranslationServiceImpl" scope="singleton"/>
<bean id="google" class="com.mycompany.prj.GoogleTranslationServiceImpl" scope="singleton"/>
<bean id="foo" class="com.mycompany.prj.FooTranslationServiceImpl" scope="singleton"/>
そして、フェイルオーバー戦略ごとに、「TranslationProxy」Bean を次のように定義します。
<bean id="translationProxy_Bing_Google" class="com.mycompany.prj.TranslationProxy" scope="singleton">
<property name="services">
<list>
<ref bean="bing"/>
<ref bean="google"/>
</list>
</property>
</bean>
<bean id="translationProxy_Foo_Bing_Google" class="com.mycompany.prj.TranslationProxy" scope="singleton">
<property name="services">
<list>
<ref bean="foo"/>
<ref bean="bing"/>
<ref bean="google"/>
</list>
</property>
</bean>
クライアント コード内:
class SomeBusinessLogic {
@Autowired
@Qualified("translationProxy_Bing_Google")
private TranslationService translationService;
public void some_method_which_uses_translation() {
result = translationService(request);
}
}
他の場所 :
class SomeAnotherBusinessLogic {
@Autowired
@Qualified("translationProxy_Foo_Bing_Google")
private TranslationService translationService;
public void some_method_which_uses_translation_with_different_failover_stradegy() {
result = translationService(request);
}
}
これは、このフェールオーバー戦略を実装する最もクリーンな方法ではありませんか?
フェールオーバー戦略をクライアント コードに移すように依頼されました。
次のようなもの(春には不可能です):
class SomeBusinessLogic {
@Autowired
@SomeAnnotationDefiningTheStradegy("bing","google")
private TranslationService translationService;
public void some_method_which_uses_translation() {
result = translationService(request);
}
ここで、「SomeAnnotationDefiningTheStradegy」は、引数で定義された Bean でリストを埋める注釈です。