質問
特定の一般的なトランザクションの永続化メカニズムを管理する境界クラスにいくつかのイベントハンドラがあります:
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を使用する方が良いでしょうか?
さらなるレベルのカプセル化が必要かどうかを理解するための有用な経験則はありますか?
現時点で私が従う経験則は、「メソッドが大きくなりすぎた場合-それについて何かをする」です。境界イベントハンドラを処理するときに、手続き型とオブジェクト指向の適切なバランスを見つけるのが難しい場合があります。
意見はありますか
乾杯
解決
考慮事項:
- カプセル化の概念はコンテナの定義に関するもので、
- オブジェクト指向設計は、メッセージの受け渡し(メソッドの呼び出し)の概念に基づいています
API は、新しい高レベルのカプセル化(つまり、新しいオブジェクトの定義)の適切性に関する良い指標であると主張します
この新しいオブジェクトによって提供されるサービス(つまりAPI)が一貫しており、1つの特別なオブジェクトに再グループ化されたときにプログラムの残りの部分にさらされている場合は、必ず新しいオブジェクトを使用してください。
それ以外の場合は、過剰すぎる可能性があります。
新しいオブジェクトを作成して public APIを公開するため、 test の概念はその新しいオブジェクト内で行う方が簡単かもしれません(同じ操作をテストするために多くのレガシーオブジェクトを作成するのではなく、いくつかのその他のモックオブジェクト)。
トランザクションをテストする場合、UIからデータを取得するには、実際にMyBoundaryClassのMyEventHandlerをテストする必要があります。
ただし、TransactionManagerを定義すると、MyBoundaryClassに存在する異なるアーキテクチャレベルのカップリングを下げる(GUIとデータ)、およびデータ管理を専用のクラスにエクスポートする機会が与えられます。< br> 次に、独立したテストシナリオでデータの永続性をテストし、特に制限値、データベース障害、および非名義条件などに焦点を当てます。
テストシナリオは、凝集度の改善に役立ちます( Daok )さまざまなオブジェクト。テストが単純で一貫性がある場合、オブジェクトに明確なサービス境界がある可能性があります。
結合と結合はオブジェクト指向プログラミングの2つの基礎であると主張できるため、 TransactionManagerのような新しいクラスの凝集度は、実行する一連のアクションに関して評価できます。
凝集性とは、特定のクラスが密接に関連する一連のアクションを実行することを意味します。一方、凝集性の欠如は、クラスがいくつかの無関係なタスクを実行していることを意味します。 [...]ますます多くの動作が散在し、間違った場所で終わるようになると、アプリケーションソフトウェアは最終的に管理不能になります。
複数の異なる場所で実装されている動作をTransactionManagerに再グループ化する場合、そのパブリックAPIが「トランザクションに関するもの」ではなく、トランザクションに関係するものの明確なステップを表すのであれば問題ありません。さまざまなユーティリティ関数のように。名前だけでは、クラスの凝集性を判断するには不十分です。名前とそのパブリックAPIの組み合わせが必要です。
たとえば、TransactionManagerの興味深い側面の1つは、次のようなトランザクションの概念を完全にカプセル化することです。
- システムの残りの部分によって事実上不明になり、他のクラスと「トランザクション」の間のカップリングが低下します
- TransactionManagerのAPIをトランザクションステップ(initTransaction()、persistTransaction()など)に集中させることにより、TransactionManagerの凝集性を強化し、Transactionインスタンスのゲッターまたはセッターを回避します。
他のヒント
VonCの提案について詳しく説明します。次のガイドラインを考慮してください。
-
同じ機能を他の場所で同じ方法で呼び出す場合は、それらを新しいオブジェクトにカプセル化するのが妥当です。
-
1つの関数(または1つのオブジェクト)が個々に役立つ一連の機能を提供する場合、それを小さなコンポーネントにリファクタリングするのが合理的です。
APIに関するVonCのポイントは優れたリトマステストです。効果的なインターフェイスを作成すると、多くの場合オブジェクトが明らかになります。
カプセル化のレベルは、オブジェクトの結合に直接リンクする必要があります。オブジェクトは単一のタスクを実行するか、複数のクラスに分割され、そのすべての動作とプロパティをカプセル化する必要があります。
経験則は、オブジェクトをテストするときです。単体テストを実行していて、複数の異なるものをテストしていることに気付いた場合(同じエリアアクションではない)、分割しようとするよりも
あなたの場合、「TransactionManager」のアイデアをカプセル化します。このようにして、「TransactionManager」 &quot; MyBoundaryClass&quot;ではなく、トランザクションの動作を処理します。