関数にパラメーターとして* interface *または* object *を渡す方が良いですか?
-
05-07-2019 - |
質問
関数は、オブジェクト自体ではなく、パラメータとしてインターフェイスを取る必要があることを同僚に説得しようとしています。小さなオブジェクトを渡すことは問題ないと思いますが、大きなオブジェクトの場合はインターフェイスを与えて、全体ではなくi / fを渡すだけです。
これらの大きなクラスの1つだけが存在することに注意してください-i / fは別のオブジェクトには使用されません。これは単にオブジェクトの実装を隠すためです。
大きなクラスをインターフェイスに分離するのは良い習慣だと思いますか?
これを行うことには欠点がありますか?
例:
public interface class IVeryLargeClass
{
void DoSomething();
...
};
public ref class VeryLargeClass : public IVeryLargeClass
{
public:
virtual void DoSomething() { ... }
...
};
public ref class AnotherClass
{
public:
AnotherClass(VeryLargeClass^ vlc) { vlc->DoSomething(); }
// OR
AnotherClass(IVeryLargeClass^ vlc) { vlc->DoSomething(); }
};
解決
オブジェクト指向開発で学ぶ最初の原則の1つ:
ではなく、インターフェイスへのプログラム 実装。
「これらの大きなクラスの1つだけが存在することを示します-i / fは別のオブジェクトに使用されることはありません」」。これはあなたの場合には真実かもしれませんが、そのような声明が間違っていることが判明したたびにニッケルがあればいいのにと思います。
インターフェイスの実装が複数あるかどうかを検討することに加えて、具体的なオブジェクトが、インターフェイスで宣言された操作と論理的な親和性を共有しない追加のメソッドをエクスポートする(またはエクスポートする)かどうかも検討する必要があります。このような場合、1つ以上の追加のインターフェイスで追加の操作を宣言するだけで済みます。したがって、クライアントは、対象となる操作をエクスポートするインターフェイスと結合するだけで済みます。
簡単に言えば、インターフェースはクライアントとプロバイダー間の結合を管理する手段を提供します。
他のヒント
依存関係反転の原則は次のように要約できます。コンクリートよりも抽象に依存しています。
ほとんどの場合、インターフェイスを渡す方が、具体的なクラスを渡すよりも優れています。
とはいえ、特定のモジュール内では内部型に対する高い凝集性は問題ありませんが、具体的なオブジェクトを渡すタイミングと方法については非常に主観的です。
インターフェイスを作成するために、インターフェイスの作成を避けたいと思います。そのインターフェイスを複数の場所で使用できる場合、勝者がいます-または、これがパブリック関数およびクラスであり、特に単純化する場合。
実装を渡すと、インターフェイスを使用する利点の1つがゆるくなります。つまり、実際の実装からロジックを分離します。
ソフトウェアモジュールAのインターフェース 故意に そのモジュールの実装。の 後者にはの実際のコードが含まれています で説明されている手順と方法 インターフェース、その他 「プライベート」変数、手順など。 他のソフトウェアモジュールB( A)のクライアントと呼ばれる Aとのやり取りが強制的に行われる インターフェイスを介してのみ。 1 これの実用的な利点 取り決めは 別のものによるAの実装 同じ仕様を満たしている インターフェースがBに Aの使用が準拠している限り、失敗します の仕様で インターフェース(Liskovも参照) 置換原則)。
他の問題は、非常に大きなクラス自体です。これは、あなたがやっていることの範囲内ではないかもしれませんが、非常に大きなクラスは、そもそも多すぎることを意味します。それをより小さなクラスにリファクタリングできますか?あなたが呼び出している関数内で必要な情報はそれ自身のより小さなクラスにカプセル化されていますか?そのクラスに対してインターフェースを作成すると、現在所有している非常に大きなクラスに対してよりもはるかに再利用できることがわかります。