要するに、「new」を使用するときはいつでも、このコードを含むクラスを作成中のオブジェクトに緊密に結合します。これらのオブジェクトの1つをインスタンス化するために、インスタンス化を行うクラスは、インスタンス化される具象クラスを知っている必要があります。そのため、「新規」を使用する場合、インスタンス化を配置するクラスがその知識が存在する「良い」場所であるかどうかを検討する必要があります。インスタンス化されているオブジェクトが変更されました。
密結合、つまり別の具体的なクラスの知識を持つオブジェクトは、常に回避されるべきではありません。あるレベルでは、どこかから何かのコピーを与えられて他のすべてのものがオブジェクトを扱う場合でも、このオブジェクトを作成する方法を知っている必要があります。ただし、作成中のクラスが変更された場合、そのクラスの具体的な実装を知っているクラスは、そのクラスの変更を正しく処理するように更新する必要があります。
あなたが常に尋ねるべき質問は、「このクラスにこの他のクラスを作成する方法を知ってもらうことは、アプリをメンテナンスする際の責任になりますか?」です。両方の主要な設計手法(SOLIDとGRASP)は、微妙に異なる理由で、通常「はい」と答えます。ただし、これらは方法論にすぎず、どちらも独自のプログラムの知識に基づいて定式化されていないという極端な制限があります。そのため、注意が必要なのは誤りであり、密結合のポイントがあると、このポイントの片側または両側に変更を加えることに関連する問題が発生する可能性があると想定しています。3つのことを知って最終決定を下す必要があります。理論上のベストプラクティス(何かが変化する可能性があるため、すべてを疎結合すること)。理論的なベストプラクティスを実装するコスト(1つのタイプの変更を緩和し、別のタイプの変更を妨げる抽象化のいくつかの新しいレイヤーを含む場合があります)。そして、あなたが予想している変化のタイプがこれまでに必要になるという現実世界の確率。
一般的なガイドライン:
コンパイルされたコードライブラリ間の密結合を避けます。DLL(またはEXEとそのDLL)間のインターフェイスは、密結合が不利になる主な場所です。DLL XのクラスAを変更し、メインEXEのクラスBがクラスAを認識している場合、両方のバイナリを再コンパイルしてリリースする必要があります。単一のバイナリ内では、変更を行うためにバイナリ全体を再構築する必要があるため、通常、より密な結合が許容されます。複数のバイナリを再構築することが避けられない場合もありますが、特に帯域幅が限られている状況(モバイルアプリの展開など、アップグレードで新しいDLLをプッシュする方がはるかに安価な場合)で、可能な限り回避できるようにコードを構成する必要がありますプログラム全体をプッシュするよりも)。
プログラムの主要な「ロジックセンター」間の密結合を避けます。よく構造化されたプログラムは、水平スライスと垂直スライスで構成されていると考えることができます。水平スライスは、UI、コントローラー、ドメイン、DAO、データなどの従来のアプリケーション層です。垂直スライスは、個々のウィンドウまたはビュー、または個々の「ユーザーストーリー」(基本的なタイプの新しいレコードの作成など)に対して定義できます。適切に構造化されたシステムで上下左右に移動する呼び出しを行う場合、通常、その呼び出しを抽象化する必要があります。たとえば、検証でデータを取得する必要がある場合は、DBに直接アクセスする必要はありませんが、データ取得のためのインターフェイスを呼び出す必要があります。一部のUIコントロールが別のウィンドウを含む高度なロジックを実行する必要がある場合、イベントやコールバックを介してこのロジックのトリガーを抽象化する必要があります。結果として何が行われるかを知る必要がないため、それをトリガーするコントロールを変更せずに何を行うかを変更できます。
いずれにせよ、変更がどれだけ簡単または難しいか、そしてその変更がどれほど起こりそうかを考えてください。作成中のオブジェクトが1か所からしか使用されておらず、変更することを予見しない場合、一般に密結合はより許容され、この状況では疎結合よりも優れている場合があります。疎結合には抽象化が必要です。抽象化は、依存関係の実装を変更する必要がある場合に依存オブジェクトへの変更を防ぐ追加のレイヤーです。ただし、インターフェイス自体を変更する必要がある場合(新しいメソッド呼び出しの追加、または既存のメソッド呼び出しへのパラメーターの追加)、インターフェイスは実際に変更を行うために必要な作業量を増やします。さまざまな種類の変更が設計に影響を与える可能性を検討する必要がありますが、