想定:
IA
であるモジュールがいくつかあります。B
のインスタンスをパラメータとして受け取り、その動作がそのIA
のタイプに依存するいくつかのモジュールIA
があります。意味(疑似コード、特定の言語なし)
_class B{
IA ia;
B(IA ia){
this.ia = ia;
}
doStuff(){
if(type(this.ia)==A1){
print("A1");
}
if(type(this.ia)==A2){
print("A2");
}
}
}
_
いくつかのパブリックメソッドfoo
をia
に追加できることを理解しているため、コードは
_class B{
IA ia;
B(IA ia){
this.ia = ia;
}
doStuff(){
this.ia.foo();
}
}
_
私の質問は2つあります:
(何らかの理由で)IA
を変更できない、つまりfoo()
を追加できない場合にこれを実現するための正しい設計は何ですか?
IA
を変更することが許可されているが、同じ問題が_A1
_、_A2
_などで繰り返される場合、正しい(スケーラブルな)設計とは何ですか。
最終的に望ましい動作は
_class B{
IA ia;
B(IA ia){
this.ia = ia;
}
doStuff(){
if(type(this.ia)==A1){
if(type(this.ia.iz)==Z1){
print("A1Z1");
print("unique treatment");
}
if(type(this.ia.iz)==Z2){
print("A1Z2");
print("special treatment");
}
}
if(type(this.ia)==A2){
if(type(this.ia.iz)==Z1){
print("Z1A2");
print("one of a kind treatment");
}
if(type(this.ia.iz)==Z2){
print("Z2A2");
print("Wow treatment");
}
}
}
}
_
さらに繰り返すことができます。
Z1とZ1はA1とA2で同じであることに注意してください!。繰り返しになりますが、IZ
にはいくつかのタイプのIX
を含めることができ、独自の動作があります
ケース2はモジュール型とはまったく別のものなのでしょうか。つまり、動作はすべての型の組み合わせで一意であり、実際には動作をより抽象的なレベルに抽出することはできません。
私はまだ型チェックが好きではないので、見栄えの良い方法があるかどうか疑問に思います。
ここでの1つのオプションは、foo()
を使用して新しいインターフェイスを作成し、そのインターフェイスのラッパータイプに、各タイプに必要な特定のロジックを含めることです。その後は、各IAインスタンスをラップするだけです。
これらのIA
インスタンスの作成方法によっては、ラッピングの時点でタイプをチェックしないと、これを実行できない場合があります。したがって、これは型チェックを行う必要性を排除しないかもしれませんが、それはあなたが他に何もしないメソッドに制限されたそのいらいらさを保つことを可能にします。次に、B
クラスを希望どおりに動作させることができます。
同様であるが異なるアプローチは、異なる方法で処理したい各IAタイプに対応するBクラスを作成することです。次に、上記と同様に、適切なBタイプを取得するためにIAのタイプをチェックするコードが必要ですが、アプリケーションロジックとは別のものです。
訪問者のデザインパターンを調べます。それはあなたが解決しようとしている問題に適用されるかもしれないと私には思われます、それによってあなたのIAはあなたが訪問したい複雑なデータ構造のルートであり、その静的および/または動的な型の形状に依存するロジックと、一見進化の対象です。