私はクラスを持ってA
いextends B
ます。クラスの名前も拡張するものも変更できません。
ただし、 にはメソッドがありA
ますdoSomething
(名前を変更することはできません)。
コンストラクターで送信されたフラグによると、A
I can something or something else.
これらすべての制限を考慮して、フラグに従ってdoSomethingでフォークを処理する方法を提案しますか?
ありがとう
私はクラスを持ってA
いextends B
ます。クラスの名前も拡張するものも変更できません。
ただし、 にはメソッドがありA
ますdoSomething
(名前を変更することはできません)。
コンストラクターで送信されたフラグによると、A
I can something or something else.
これらすべての制限を考慮して、フラグに従ってdoSomethingでフォークを処理する方法を提案しますか?
ありがとう
詳細情報なし:
public Foo doSomething() {
if( flag ) {
return super.doSomething();
} else {
return doSomethingElse();
}
}
戦略パターンを使用することもできますが、数十行のコードが追加され、デザイン パターンを適用したという感覚以外にはほとんどメリットがありません。
メソッド呼び出しで必要な間接化を使用すると、さらに遅くなる可能性があります。
B も拡張する別のクラス C を作成し、必要に応じて A の代わりに使用できないのはなぜですか? 可能であれば、通常は、クラス内のストラテジーの構築を条件付きでハードコーディングしたりハードコーディングしたりすることは避けたほうがよいでしょう。
基本クラスに手を加える必要はありません。別の実装で拡張するだけです。
Strategy
ここでパターンを使用する必要があります
public A(boolean flag){
if(flag == true){
this.service = new DoSomethingStrategy();
}else{
this.service = new DoSomethingElseStrategy();
}
}
コードが論理的に大きくなる場合は、コンストラクターで Factory を使用することをお勧めします。
public A(boolean flag){
this.service = DoSomethingFactory.getService(flag);
}
DoSomethingFactory
;内のコードをコピーします。
そして最後にあなたのdoSomething
方法で
public void doSomething(){
this.service.doSomething();
}
doSomething の動作は戦略構造にカプセル化されます。
私の意見では、次の 2 つのオプションのいずれかを選択できます。
フラグと fordoSomething
をフラグに従って 2 つの内部メソッドに使用します。例えば:
public class A extends B {
private boolean forkFlag;
public A (boolean forkFlag) {
this.forkFlag = forkFlag;
}
public void doSomething() {
if (forkFlag) {
doSomething1();
} else {
doSomething2();
}
}
private void doSomething1() { ... }
private void doSomething2() { ... }
}
戦略の実装を作成します。
public class A extends B {
private boolean forkFlag;
private Runnable doSomethingImpl;
public A (boolean forkFlag) {
if(forkFlag) {
doSomethingImpl = new DoSomethingImpl1();
} else {
doSomethingImpl = new DoSomethingImpl2();
}
}
public void doSomething() {
doSomethingImpl.run();
}
}
public class DoSomethingImpl1 implements Runnable {
public void run() { ... }
}
public class DoSomethingImpl2 implements Runnable {
public void run() { ... }
}
これら 2 つのどちらを選択するかは、ニーズによって異なります。このフォークがマイナーなもので、通常のフローでの使用例にすぎない場合は、最初のオプションを使用します。3 番目のフローが必要になる可能性がある場合は、戦略パターンを使用して、それが提供するデカップリングを楽しんでください。
ストラテジーを使用すると、必要な実装をクラスの外部から注入できdoSomething
、コンストラクターを変更するだけで実装を完全に認識できなくなります。
public A (Runnable doSomething) {
this.doSomething = doSomething;
}
インジェクション パターンはおそらく最も洗練されており、実装からコードを完全に切り離します。また、より堅牢にするためにimplements Runnable
、独自のより具体的なインターフェイスに変更することもできます。public interface DoSomething