1

解決する作業が複雑な場合は、実行を制御する1つの方法がある場合があります。ヌルチェック、if文、型間のマップメソッドの呼び出しなどのために、このメソッドは非常に長くなる可能性があり、簡単にするために苦労しています。メソッド呼び出しの責任は誰にありますか?

例1

public class A 
public string MethodA(string stringA) 
{ 
    var fooResult = _fooService.fooMethod(stringA); 

    if(fooResult) 
    var barResult = _barService.barMethod(fooResult); 

    if(barResult) 
    // And so on.. 

    return someResult; 
} 

Iは、第1の方法は簡単になり、メソッド呼び出しを連鎖できました。しかしこれにより、fooMethodは_barServiceに依存し、barMethodは_someServiceに依存します。

例2(連鎖メソッド呼び出しを超えるがと同じ)

public class B 
public string MethodB(string stringB) 
{ 
    return _fooService.fooMethod(stringB); 
} 

public class Foo 
public string fooMethod(string stringB) 
{ 
    return _barService.barMethod(stringB); 
} 

public class Bar 
public string barMethod(string fooString) 
{ 
    return _someService.someMethod(fooString); 
    // And so on... 
} 

どのように私は私のコードを構造化する必要がありますか?どのメソッドが別のメソッドを呼び出す責任があるのか​​、どのように考えるべきでしょうか?

言い換えれば、私は次のように実行する必要があります。
class A 
{ 
    Execute() 
    { 
    A(); 
    B(); 
    C(); 
    } 

    method A() 
    { 
    ... 
    } 

    method B() 
    { 
    ... 
    } 

    method C() 
    { 
    ... 
    } 
} 

またはこのような

class B 
{ 
    Execute() 
    { 
    A(); 
    } 

    method A() 
    { 
    B(); 
    } 

    method B() 
    { 
    C(); 
    } 

    method C() 
    { 
    ... 
    } 
} 
+0

2番目の例では苦労していることは明確ではありません。ほとんどの場合、メソッドではなくクラスの依存関係を最小化することに気をつけるべきです(疎結合について読む) – Megamozg

+0

@Megamozg私はうまくいけばそれをもっと明確にするために質問を編集しました。例1と例2では同じ結果が得られますが、依存関係は別の場所になります。あなたは例1または2を好むでしょうか?例1を好むなら、その方法を長く管理し、それ以上のことを何とかしていくのですか? – Paul

答えて

1

です。

ステージが適切に定義されている場合は、ほとんどの場合、順番に呼び出す方が便利です。

しかし、例えばBがよく定義されていて、AとCが本当にBに依存するジョブの開始と終了の場合、AとCのどちらも自分自身では意味がなく、名前を付ける/記述するのが難しいまたはそれらが成功したかどうかを評価するために、その場合は、Bを呼び出す単一の方法でAとCを組み合わせる方が理にかなっています。 それぞれが特定のタスクを実行するようにメソッドを分割しますが、その部分的なタスクが独自の意味を持たない場合、タスクの一部だけを分離することは避けてください。

コードをどのようにテストするかを検討する必要があります.1つのデザインで他のデザインよりも簡単です。

コードをどのように維持するかを検討してください。これは、コードの理解の容易さが最も重要な点ですが、バグを修正したり機能を強化するために編集が必要な場合も考慮します。この設計により、最小限の努力と、他のコードへの副作用と、実際に影響を受けてはならない領域の関連する再テストで、これを行うことができますか?

入力や設定に応じて、別のバージョンのBを呼び出すために、今後の手順の1つを変更する必要があるかどうかを考えてください。

再利用性を考慮してください。 AがBを呼び出す場合は、Bを呼びたくない状況でAを再利用することはできません。他のデザインでは、Aを再利用することができます。

この順序でコールする必要がありますかBとCを並行して呼び出して速度を最適化します(BからCを呼び出すことはできません)。

もしBが失敗しても、Cを呼び出そうとしたら(実際には本当にそうなる可能性が高いので、ほとんどの人はそうではないと思われますが、実際の問題に依存しています)。

AからBを呼び出すことに賛成するには、インターフェースでAを公開する必要があります(選択した言語で許可されている場合)BとCを非公開にすることができます。 BがAから呼び出されることを確実にすることははるかに容易であり、したがってBは特定の初期条件のテストを避けることができ、Aの仕事に頼っているだけです。

もちろん、上記は回答より多くの質問です。実際の仕事の内容によってどちらかのデザインが正しいかもしれませんが、上記の考慮事項があなたの判断に役立つことを願っています。

0

は、すべてのタスクのための普遍的な決定はありません。基本的には、メソッドを簡潔に記述し、1つのタスクを実装するように努力する必要があります。適切なメソッド命名はあなたがそれをするのに役立ちます(これはあなたの問題です)。たとえば、ExampleClass.DoWork()ExampleClass.ManageObject(object)のような名前は正確ではなく、複雑で長い実装を誘発するので避けてください。

一般

、それが簡単に読むこととしてより好ましいあなたの最後の2つの例の「シリアル」バージョン、およびA()B()、より多くの些細な実装を持っている可能性がC()、適切に彼らに名前を付けるために容易になるだろう。

具体的なアドバイスについては、コードをCode Reviewに掲載してください。

関連する問題