この質問は、Webサービスに特に注意を払ったMicrosoftWCFのコンテキストでのプログラミングとベストプラクティスに関する理論的なものです。
Webサービスの継承
定義する機能がいくつかある状況を考えてみましょう。これらの機能をWebサービスを使用して世界に公開したいと考えています。機能はインターフェースによってモデル化されます(これは、分散システムなどを扱う場合に非常に良い方法です)。したがって、次のようなものがあります。
///
/// Functionalities for a certain context, calling them A functionalities
///
public interface IFunctionalitiesA {
FunctionalityA1ResMsg FunctionalityA1(FunctionalityA1ReqMsg msg);
FunctionalityA2ResMsg FunctionalityA2(FunctionalityA2ReqMsg msg);
FunctionalityA3ResMsg FunctionalityA3(FunctionalityA3ReqMsg msg);
}
///
/// Functionalities for a certain context, calling them B functionalities
///
public interface IFunctionalitiesB {
FunctionalityB1ResMsg FunctionalityB1(FunctionalityB1ReqMsg msg);
FunctionalityB2ResMsg FunctionalityB2(FunctionalityB2ReqMsg msg);
}
///
/// Functionalities for a certain context, calling them C functionalities
///
public interface IFunctionalitiesC {
FunctionalityC1ResMsg FunctionalityC1(FunctionalityC1ReqMsg msg);
FunctionalityC2ResMsg FunctionalityC2(FunctionalityC2ReqMsg msg);
FunctionalityC3ResMsg FunctionalityC3(FunctionalityC3ReqMsg msg);
FunctionalityC4ResMsg FunctionalityC4(FunctionalityC4ReqMsg msg);
}
///
/// Functionalities for a certain context, calling them D functionalities
///
public interface IFunctionalitiesD {
FunctionalityD1ResMsg FunctionalityD1(FunctionalityD1ReqMsg msg);
FunctionalityD2ResMsg FunctionalityD2(FunctionalityD2ReqMsg msg);
}
ここで、これらすべての機能を一部のサービスで実装できると考えてみましょう。ただし、それらすべてを実装するサービスがあることは必須ではありません。サービスはそれらのいくつかを実装でき、別のサービスはそれらの別のサブセットを実装できます。特に、私は次の状況を考慮するように求めています。
///
/// This service implements functionalities A and B.
///
public class ServiceS1 : IFunctionalitiesA, IFunctionalitiesB {
... /* Implementing interfaces methods */
}
///
/// This service implements functionalities C and D.
///
public class ServiceS2 : IFunctionalitiesC, IFunctionalitiesD {
... /* Implementing interfaces methods */
}
特に、これら2つのサービスは、内部的にいくつかの重要なものを作成することに注意してください。つまり、彼らだけがアクセスできるリソースを持っているということです。たとえば、最初のサービスは要素の配列を保持し、2番目のサービスも同様です。つまり、これらはダミーサービスではなく、状態とリソースがあり、外部アクセスから保護されています(つまり、public
またはとして宣言されprotected
ます)。
ここで、すべての機能を実装するサービスを実装したいと考えてみましょう。おそらく別のステーションで実行する必要があります。このサービスは、それぞれの実装されたメソッドを処理するときに、上記の2つとまったく同じように動作します。残念ながら、両方から派生することはできません。したがって、これを行う必要があります。
public class GlobalService :
IFunctionalitiesA, IFunctionalitiesB, IFunctionalitiesC, IFunctionalitiesD {
...
}
カプセル化...それが答えになるのでしょうか?
質問は:
全体的な機能のサブセットを実装する2つのサービス内のロジックを再利用するにはどうすればよいですか?
私はこのようなことをすることを考えてしまいました:
public class GlobalService :
IFunctionalitiesA, IFunctionalitiesB, IFunctionalitiesC, IFunctionalitiesD {
///
/// Encapsulating ServiceS1
///
protected ServiceS1 srvs1;
///
/// Encapsulating ServiceS2
///
protected ServiceS2 srvs2;
public GlobalService() {
this.srvs1 = new ServiceS1();
this.srvc2 = new ServiceS2();
}
///
/// Methods are redirected internally to the reused implementation
/// This is to be done for all methods
///
public FunctionalityA1ResMsg FunctionalityA1(FunctionalityA1ReqMsg msg) {
return thissrvs1.FunctionalityA1(msg);
}
...
}
そうすることで、冗長なコードを何度も作成することなく、実装されたロジックを再利用できます。もちろん、これは一部のケースに限定されたアプローチである可能性がありますが、これらの条件では(結局のところそれほど制限的ではありません)。
これは問題を解決するための良いアプローチですか?あなたは違うと思いますか?