5

特定の汎用トランザクションの永続化メカニズムを管理する境界クラスにイベント ハンドラーがあります。

void MyBoundaryClass::MyEventHandler(...)
{
  //retrieve stuff from the UI
  //...
  //declare and initialize trasaction to persist
  SimpleTransaction myTransaction(.../*pass down stuff*/);
  //do some other checks
  //...
  //declare transaction persistor
  TransactionPersistor myPersistor(myTransaction, .../*pass down connection to DB and other stuff*/);
  //persist transaction
  try
  {
    myPersistor.Persist();
  }
  catch(...)
  {
    //handle errors
  }
}

SimpleTransaction および TransactionPErsistor オブジェクトをラップするために、ある種の TransactionManager を用意したほうがよいでしょうか?

さらにカプセル化する必要があるかどうかを理解するのに役立つ経験則はありますか?

現時点で私が従う経験則は、「メソッドが大きくなりすぎたら、それについて何かをする」です。境界イベント ハンドラーを扱う場合、手続き型とオブジェクト指向の間の適切なバランスを見つけるのが難しい場合があります。

何か意見はありますか?

乾杯

4

3 に答える 3

3

それを考慮して:

  • カプセル化の概念は、コンテナーを定義することです。
  • オブジェクト指向設計は、メッセージ パッシング (メソッドの呼び出し) の概念に基づいています。

APIは、新しい高レベルのカプセル化 (つまり、新しいオブジェクトの定義) の妥当性を示す良い指標であると私は主張します。

この新しいオブジェクトによって提供されるサービス (つまり API) が一貫しており、1 つの特別なオブジェクトに再グループ化されたときにプログラムの残りの部分によりよく公開される場合は、必ず新しいオブジェクトを使用してください。

それ以外の場合は、やり過ぎの可能性があります。

新しいオブジェクトを作成してパブリックAPIを公開するため、同じ操作をテストするために多くのレガシー オブジェクトを作成するよりも、その新しいオブジェクト (および他のいくつかのモックオブジェクト) 内でテストの概念を実行する方が簡単な場合があります。

あなたの場合、トランザクションをテストしたい場合は、UI からデータを取得するために、実際に MyBoundaryClass の MyEventHandler をテストする必要があります。

ただし、TransactionManager を定義すると、MyBoundaryClass に存在するさまざまなアーキテクチャ レベル (GUI とデータ) の結合を減らし、データ管理を専用のクラスにエクスポートする機会が得られます。
次に、独立したテスト シナリオでデータの永続性をテストできます。特に、制限値、データベースの障害、非公称条件などに焦点を当てます。

テストシナリオは、さまざまなオブジェクトの結束( Daokが言及した重要なポイント)を改善するのに役立ちます。テストが単純で首尾一貫している場合は、オブジェクトのサービス境界が明確に定義されている可能性があります。

Coupling と Cohesion は OO Programming の 2 つの基礎であると主張できるため、TransactionManager のような新しいクラスの結合は、それが実行する一連のアクションの観点から評価できます。

凝集性とは、特定のクラスが一連の密接に関連したアクションを実行することを意味します。一方、まとまりの欠如は、クラスがいくつかの無関係なタスクを実行していることを意味します。[...] アプリケーション ソフトウェアは、ますます多くの動作が散らばり、間違った場所に行き着くにつれて、最終的に管理不能になります。

別の方法で複数の異なる場所に実装されている動作を TransactionManager に再グループ化する場合、パブリック API がトランザクションに含まれる明確な手順を表し、さまざまなユーティリティ関数のような「トランザクションに関するもの」ではない場合、問題ありません。クラスのまとまりを判断するには、名前だけでは不十分です。名前とそのパブリック API の組み合わせが必要です。

たとえば、TransactionManager の興味深い側面の 1 つは、Transaction の概念を完全にカプセル化することです。

  • システムの残りの部分によって実質的に知られなくなり、他のクラスと「トランザクション」との間の結合が低下します
  • API をトランザクション ステップ (initTransaction()、persistTransaction() など) に集中させ、Transaction インスタンスの getter または setter を回避することで、TransactionManager のまとまりを強化します。
于 2008-11-01T18:13:55.710 に答える
2

VonC の提案を詳しく説明するには、次のガイドラインを考慮してください。

  • 同じ方法で同じ関数を別の場所で呼び出すことが予想される場合は、それらを新しいオブジェクトにカプセル化するのが合理的です。

  • 1 つの関数 (または 1 つのオブジェクト) が個別に役立つ一連の機能を提供する場合、それをより小さなコンポーネントにリファクタリングするのが合理的です。

API に関する VonC のポイントは、優れたリトマス試験紙です。効果的なインターフェイスを作成すると、オブジェクトがしばしば明らかになります。

于 2008-11-01T18:43:30.130 に答える
1

カプセル化のレベルは、オブジェクトの結合に直接リンクする必要があります。オブジェクトは単一のタスクを実行するか、複数のクラスに分割してすべての動作とプロパティをカプセル化する必要があります。

経験則は、いつオブジェクトをテストするかということです。単体テストを行っていて、複数の異なるもの (同じ領域のアクションではない) をテストしていることに気付いた場合は、それを分割しようとするかもしれません。

あなたの場合、「TransactionManager」のアイデアをカプセル化します。このように、「MyBoundaryClass」ではなく、「TransactionManager」がトランザクションの仕組みを処理します。

于 2008-11-01T19:03:00.603 に答える