web-dev-qa-db-ja.com

1つの大きなオブジェクトを2つの密結合されたオブジェクトに分割する-良い、悪い?

半信頼のユーザーにRPCインターフェイスを提供する複雑なオブジェクト(BusinessLogicと呼びます)があります。 RPCインターフェイスの関数は、呼び出すプロシージャを決定し、その関数の承認を確認し、引数の確認を実行してから、プライベート関数を呼び出して必要な機能を実行し、結果を呼び出し元に返す必要があります。

RPC関数を別のステートレスオブジェクト(AppInterfaceと呼びます)に配置して、懸念事項をある程度分離することでこれを実装することにしました。これにより、BusinessLogicは独自のデータを移動し、AppInterfaceがBusinessLogicのどのメソッドを呼び出して機能を実装するかを決定します。公開します。

これはほとんどの場合非常にうまく機能します。しかし、それは私には少し間違っていると感じます。 BusinessLogicオブジェクトは、承認や引数のチェックなどについて心配する必要がないという利点があります。これは良いことです。しかし、AppInterfaceはBusinessLogicの観点からすべての機能を実装しているため、一部のプロシージャでは薄いラッパーになり(その必要性に疑問を抱きます)、他のプロシージャでは複雑なラッパーになります(その複雑さはどうあるべきか疑問に思います)。 BusinessLogicにはタスクの実行に必要なすべての情報があるため、BusinessLogicにプッシュバックされます)。また、AppInterfaceは、他に何も使用しないためプライベートであるBusinessLogicのメソッドにアクセスする必要があることも意味します。友達はC++で機能すると思います。最後に、有効な出力を取得する唯一の実用的な方法であるため、完全なBusinessLogicオブジェクトを使用せずにAppInterfaceを効果的に単体テストすることはできません。

システムはそのままでいいのですが、そのようなシステムに明らかな改善ができるかどうか知りたいです。

(その価値のために、私はPython 2.7、主にオブジェクト指向のスタイルで使用しています。)

6
Kylotan

あなたは、結合された関係よりもレイヤーの関係を説明しています。 BusinessLogicAppInterfaceに依存して呼び出しを行わない限り、結合されません。あなたの下のレイヤーに多くの依存関係があることは非常に自然で避けられません。 BusinessLogicがデータベースレイヤーにどれだけ依存しているかについて心配する必要はありませんか?

ただし、一部の呼び出しが薄いラッパーであり、一部が厚いという事実から、一部が非常に複雑である理由に疑問が生じます。 BusinessLogic関数とは見た目が異なるインターフェースの場合は、BusinessLogicに移動する必要があります。一部の引数を他の引数よりも検証するのが難しいためである場合は、その懸念を分離する方法を考え出す必要があります。承認についても同じことが言えます。

5
Karl Bielefeldt

2つのオブジェクトを結合するのは良くありません。誰もがそれを保証するでしょう。ただし、2つの結合されたオブジェクトは、1つのモノリシックオブジェクトよりも優れていると思います。

オブジェクトの分割により、進化に対して真に独立していなくても、少なくともコードの管理方法を簡素化できます。

あなたの要素に関する限り、私はあなたがAppInterfaceBusiness Objectに対する逆依存性を連続的に減らすことができるかどうかが最善の策だと感じました。そのように考えることができる簡単なプロセスは、同じAppInterfaceにアクセスする必要があるanotherBusiness objectについて考えることです。 AppInterfaceを可能な限り汎用にするために、2番目のBOの適度に一意で異なる動作/期待を維持するようにしてください。

AppInterfaceをBusinessオブジェクト内にマージして戻すことは絶対にしないでください。ただし、可能な限り汎用的にするようにしてください。

4
Dipan Mehta

すべてのオブジェクトは結合する必要があります。避けたいのはタイトカップリングです。 BusinessLogicオブジェクトはカプセル化を破りますか、それとも特定の順序で呼び出されるメソッドに依存しますか?そうでない場合、それは細かい抽象化状態で存在します。

AppInterfaceは、BusinessLogicオブジェクトがどのように機能するかの詳細に依存しすぎていませんか?次に、AppInterfaceを再設計する必要があります。関数からの合意された戻り値に応じて正しいことに注意してください。

単体テストでは、メソッド呼び出しによって返される「必要がある」ものを適切に文書化し、MockBusinessLogicオブジェクトを作成します。すべて同じメソッドですが、returnステートメントのみです。

1
Spencer Rathbun

これらのオブジェクトを組み合わせて、それらを分割する別の方法を探す必要があると思います。オブジェクトが緊密に結合されている場合は、そのように分離するべきではなく、オブジェクトAとBを常に使用する必要がある理由を将来のプログラマーに混乱させるだけです。一緒に何かを成し遂げるために。

0
Ryathal

BusinessLogicのパブリックインターフェイスを別の基本クラスIBusinessLogicにリファクタリングできます。これは、AppInterfaceに必要なすべての関数を提供します。 AppInterfaceインスタンスを作成するときは、それにIBusinessLogicオブジェクトを渡します。これは、実行中のシステムではBusinessLogicのインスタンスになります。

テストの目的で、BusinessLogicMockから継承するIBusinessLogicクラスを作成することもできます。これで、本格的なAppInterfaceオブジェクトを提供しなくても、BusinessLogicを簡単に単体テストできます。これはあなたが探しているデカップリングの形かもしれません。

0
Doc Brown