2009-07-08 3 views
0

シーケンスダイアグラムを実装するときなど、設定された順序で実行する必要のある操作の一覧があることがあります。シーケンスの変更によって微妙なバグを導入するリファクタリングを防ぐために、コード実行順序を強制する最良の方法は何ですか?コード実行シーケンスを適用する

foo()とbar()の実行順序を次のように変更したことで、既存の単体テストで問題が発生しないとしましょう。私が見て使ってきた方法の

数:

  1. コメント(それらを理解&を読んだ人に依存しています):

    // do this
    foo();
    // then this
    bar();

  2. 流暢文法(コードを英語のように読むようにして、無慈悲なリファクタリングを避ける):

    obj
    .Do
    .foo()
    .Then
    .bar();

  3. 状態変数& balking(あまりにも精巧):関数に論理ブロックをグループ化

    foo_done=false;
    if(foo()) foo_done=true;
    if(foo_done) bar(); else throw_an_exception;

  4. void foo_bar()
    {
    foo();
    bar();
    }

...と説明するにはあまりにも醜い、より多くの(関数ポインタの入れ子、イベント、配列を、命名関数は(開始)、中東()とEnd()...) 。

このようなことを行うための改良されたパターンはありますか?

+1

もっと具体的な例が、より良い回答を引き出すかもしれないと思います。物事を成就させる必要のある順番はどれほど厳格ですか?正確なシーケンスでいくつかのメソッドを常に呼び出す必要がある場合、正しい順序ですべてのメソッドを呼び出すvoid doEverything()に何が問題なのかのエラーです。アドホック・オーダーでオペレーションを呼び出す必要がある場合、そこにはどんな制約がありますか?なぜ彼らは特定の順序で呼び出される必要がありますか?彼らはいくつかの共通の状態で動作しますか?ユニットテストではない副作用がありますか? –

答えて

1

ユニットテストがそれらを捕まえず、依存関係がコード内に明示的でない場合、なぜその順序が重要であるのか混乱します。副作用はfoo()とbar()の操作の重要な部分であることを意味します。 この場合、最適なデザイン戦略は、これらの副作用を明示的にすることです。

+0

依存関係を明示的にするにはどうすればいいですか?コード本体の外側にテストを渡す順序を保証する唯一の方法はありますか?または、シーケンスを明示的にする方法はありますか? – lotsoffreetime

+0

Eh?私は可能な限り文字通りの意味で意味します: ファイルハンドル= function_a(ファイル名); レコード数= function_b(ファイルハンドル)。 データ構造= function_c(ファイルハンドル、レコード数)。 誰もそれらの順序を変更するつもりはありません... –

+0

すべてのシーケンスがかなり明白であるわけではありません。 get_price()はどうですか? apply_discount(10%); add_tax();税が追加された後に割引が適用されると、問題が発生し、単体テスト(ビジネスロジックの理解)だけがあなたを救うでしょう。たぶん、「シーケンシング・ビジネス・ロジック」は私が後にしている言葉です。 – lotsoffreetime

0

プロシージャをコールした後に起こったこと(状態、属性の変更)をチェックするために単体テストを書くので、メソッドが呼び出されたかどうかを確認する必要はありません。

また、テストを何らかの方法に結びつけると、後でfoo()と同じ効果を持つ別のメソッドを使用するようにシステムを変更すると、システムが正しいことを行っているときでもテストは失敗します。

関連する問題