ユースケースなしの疎結合はアンチパターンですか?


22

一部の開発者にとって、疎結合は、適切に設計されたソフトウェアの聖杯です。予測可能な将来に発生する可能性のある変更に直面してコードをより柔軟にする、またはコードの重複を回避する場合、それは確かに良いことです。

一方、コンポーネントを疎結合しようとすると、プログラム内の間接参照の量が増え、そのため複雑さが増し、理解が難しくなり、効率が低下することがよくあります。

疎結合のユースケースを使用しない疎結合(コードの重複を回避したり、近い将来発生する可能性のある変更を計画するなど)をアンチパターンと考えていますか?ゆるい結合はYAGNIの傘の下に落ちますか?


1
ほとんどの利点には費用が伴います。利益がコストを上回る場合に使用します。
LennyProgrammers

4
ゆるいカップリングコインの裏側を忘れてしまったhigh cohesionのは、一方が他方なしであるということは、労力の浪費であり、いずれかの理解の根本的な欠如です。

回答:


13

幾分。

いくつかのモジュールの分離を要求する特定の要件がない場合でも、あまり労力をかけずに発生する疎結合で問題ない場合があります。ぶら下がっている果物。

一方で、とんでもない量の変更のためのオーバーエンジニアリングは、多くの不必要な複雑さと労力になります。あなたが言うように、ヤグニは頭にそれを打ちます。


22

プログラミングの練習 Xは良いですか、悪いですか? 明らかに、答えは常に「依存する」です。

コードを見て、どの「パターン」を挿入できるのか疑問に思っているなら、それは間違っています。

無関係なオブジェクトが互いに干渉しないようにソフトウェアを構築している場合は、正しく実行しています。

ソリューションを無限に拡張および変更できるように「エンジニアリング」している場合、実際にはより複雑になっています。

結局のところ、あなたにはただ一つの真実が残っていると思います。オブジェクトを分離するのは多かれ少なかれ複雑ですか?それらを結合することがそれほど複雑でなければ、それは正しい解決策です。それらを分離するのがそれほど複雑でないなら、それは正しい解決策です。

(私は現在、非常に複雑な方法で単純な仕事をするかなり小さなコードベースで作業していますが、それを複雑にするのは、元の部分の「結合」と「凝集」という用語の理解不足です開発者。)


4
先日、これを行いました。「万が一に備えて」2つのクラス間で間接指定が必要だと思いました。それから私は何かをデバッグしようとして頭を痛め、間接性を破り、ずっと幸せでした。
フランクシェラー

3

ここであなたが得ているのは結束の概念だと思います。このコードには良い目的がありますか?その目的を内面化し、何が起こっているかの「全体像」を理解できますか?

多くのソースファイルがあるためだけでなく(これらが別個のクラスであると仮定した場合)、単一のクラスには目的がないように思われるため、追跡が難しいコードにつながる可能性があります。

アジャイルの観点から、このような疎結合はアンチパターンであると示唆するかもしれません。結束力がない場合、またはそのユースケースでさえ、賢明な単体テストを書くことはできず、コードの目的を検証することもできません。現在、アジャイルコードは、たとえばテスト駆動開発が使用されている場合、疎結合につながる可能性があります。しかし、正しいテストが正しい順序で作成された場合、適切な凝集性と疎結合の両方が存在する可能性があります。そして、あなたは明らかに凝集性が存在しない場合についてのみ話している。

繰り返しますが、アジャイルの観点からは、この人工的なレベルの間接化は、おそらくとにかく必要のないものに対する無駄な労力なので、望まないでしょう。必要性が現実にある場合、リファクタリングははるかに簡単です。

全体として、モジュール内での高い結合と、モジュール間の疎結合が必要です。高結合がなければ、おそらく凝集性はありません。


1

このような質問の大部分については、答えは「依存します」です。全体として、理にかなった方法で論理的に疎結合されたデザインを作成できれば、そうすることによる大きなオーバーヘッドはありません。コード内の不必要な結合を避けることは、私の考えでは、完全に価値のある設計目標です。

コンポーネントを論理的に密結合する必要があると思われる状況になると、それらを分割する前に説得力のある議論を探します。

これらのタイプの練習のほとんどで私が取り組む原則は、慣性の1つだと思います。私は自分のコードをどのように機能させたいかについてのアイデアを持っています。もし私がそうすることができれば、人生をより難しくすることなくそれを行うことができます。それを行うと開発が難しくなりますが、メンテナンスと将来の作業が簡単になる場合は、コードの寿命全体でより多くの作業になるかどうかを推測し、それを私のガイドとして使用します。そうでなければ、それは行く価値があるように意図的な設計ポイントである必要があります。


1

簡単な答えは、正しく行われた場合、疎結合は良いということです。

一つの機能の原理、一つの目的が守られているなら、何が起こっているのかを追うのに十分簡単なはずです。また、当然のことながら、ゆるいカップルのコードは何の努力もなしに続きます。

シンプルなデザインルール:1.ファサードインターフェイスを構築している場合を除き、複数のアイテムの知識を単一のポイントに構築しないでください(どこでも指摘されています)。2. 1つの機能-1つの目的(その目的はファサードのように多面的かもしれません)3. 1つのモジュール-相互に関連する機能の明確なセット-1つの明確な目的4.単純な単体テストができない場合、簡単な目的

後でリファクタリングしやすくすることに関するこれらのコメントはすべて、大量のタラです。知識が多くの場所、特に分散システムに組み込まれると、リファクタリングのコスト、ロールアウトの同期、およびその他すべてのコストが考慮されなくなり、ほとんどの場合、システムがそのために廃棄されることになります。

最近のソフトウェア開発に関する悲しいことは、人々の90%が新しいシステムを開発し、古いシステムを理解する能力がないことであり、システムが継続的にリファクタリングを行うためにそのような劣悪な健康状態に陥ったときは決してありません。


0

あるものが他の物と変わらない場合、他の物とどれだけ密接に結びついているかは関係ありません。可能な限りゆるい形のカップリングを達成しようとすることで変更を容易にするよりも、変化する理由を少なくして安定性を追求することに焦点を当てることが、長年にわたって一般的に生産的であることがわかりました。 デカップリングパッケージをデカップリングするために控えめなコードの複製を好むことがあるほど、非常に有用であることがわかりました。基本的な例として、数学ライブラリを使用して画像ライブラリを実装することを選択しました。コピーするのは簡単だったいくつかの基本的な数学関数を複製しませんでした。

これで、私の画像ライブラリは数学ライブラリから完全に独立しているため、数学ライブラリにどのような変更を加えても、画像ライブラリには影響しません。それは何よりもまず安定性を置いています。イメージライブラリは、変更できる他のライブラリから切り離されているため(変更することを期待するC標準ライブラリを除く)、変更する理由が大幅に少なくなったため、より安定しています。おまけとして、それを構築して使用するために他のライブラリの束を引っ張る必要のない単なるスタンドアロンのライブラリである場合にも簡単に展開できます。

安定性は私にとって非常に役立ちます。十分にテストされたコードのコレクションを作成するのが好きです。これは、将来変更される理由がますます少なくなっています。それは単なる夢ではありません。80年代後半からずっと使用し続けているCコードがありますが、それ以降はまったく変更されていません。ピクセル指向やジオメトリ関連のコードのような明らかに低レベルなものですが、私の高レベルなものの多くは時代遅れになりましたが、それでも多くのことを助けてくれるものです。これは、外部にまったく何もない場合でも、ほとんど常に依存するライブラリが少なくなることを意味します。変更する理由がほとんどない、またはまったくない安定した基盤にソフトウェアがますます依存するようになると、信頼性は向上します。実際には可動部品の数が安定部品よりもはるかに多い場合でも、可動部品の数は少ないほうがいいです。

疎結合は同じ流れですが、疎結合は結合なしよりもはるかに安定性が低いことがよくあります。あなたが私がこれまで働いていたよりも心を変えない、はるかに優れたインターフェースデザイナーとクライアントとチームで働いているのでない限り、純粋なインターフェースでさえ、コード全体で連鎖的な破損を引き起こす方法で変更する理由をしばしば見つけます。依存関係を具体的ではなく抽象的に向けることで安定性を実現できるというこの考え方は、インターフェースの設計が実装よりも最初の段階でより適切になりやすい場合にのみ役立ちます。開発者が素晴らしいとはいえないにしても、彼らが満たすべき設計要件を考慮して、非常に優れた実装を作成したかもしれませんが、将来は設計要件が完全に変更されることを見つけるために、しばしば逆になります。

安定性と完全なデカップリングを好むので、少なくとも自信を持って言えるようになりました。 」どんな種類のデザイン変更が外部で要求されようとも、それは正気の小さな断片を私に与えます。

結合と安定性、ECSの例

エンティティコンポーネントシステムも大好きです。システムとコンポーネントの依存関係はすべて、生データに直接アクセスして操作するため、次のように、多くの密結合を導入します。

ここに画像の説明を入力してください

コンポーネントは生データを公開するだけなので、ここのすべての依存関係は非常に厳密です。依存関係は抽象化に向かって流れているのではなく、生データに向かって流れています。つまり、各システムは、アクセスを要求するコンポーネントの各タイプについて最大限の知識を持っています。コンポーネントには、すべてのシステムが生データにアクセスして改ざんする機能はありません。ただし、このようなシステムは非常にフラットであるため、推論するのは非常に簡単です。テクスチャがねじれた場合、レンダリングとペイントシステムのみがテクスチャコンポーネントにアクセスすることがこのシステムですぐにわかります。また、概念からテクスチャのみを読み取るため、レンダリングシステムをすぐに除外できます。

一方、疎結合の代替案はこれかもしれません:

ここに画像の説明を入力してください

...すべての依存関係がデータではなく抽象関数に向かって流れ、そのダイアグラムのすべての要素がパブリックインターフェイスと独自の機能を公開しています。ここでは、すべての依存関係が非常に緩やかな場合があります。オブジェクトは相互に直接依存することさえなく、純粋なインターフェースを介して相互に作用することさえあります。それでも、特に複雑な相互作用の複雑さを考えると、何かがうまくいかない場合、このシステムについて推論することは非常に困難です。また、エンティティは、互いの抽象的なパブリックインターフェイスのみを知っている場合でも、集約するコンポーネントについて知る必要があるため、ECSよりも多くの相互作用(疎結合ではあるものの、より多くの結合)があります。

また、何かに設計変更がある場合、ECSよりも多くのカスケード破損が発生します。また、通常、設計変更の理由と誘惑は多くあります。すべてのものが、優れたオブジェクト指向のインターフェースと抽象化を提供しようとしているためです。それはすぐに、ひとつひとつの小さなものが設計に制約と制限を課そうとし、それらの制約が多くの場合設計変更を正当化するものであるという考えに付随しています。機能性ははるかに制約されており、生データよりもはるかに多くの設計上の仮定を行う必要があります。

上記のタイプの「フラット」ECSシステムは、実際には、ゆるい依存関係の複雑なクモの巣を持つ最も疎結合のシステムよりもはるかに推論が容易であることがわかりました。システムが機能するために必要な適切なデータを提供することを除いて、依存するコンポーネントは一切の責任を持たないため、ECSバージョンが既存のコンポーネントを変更する必要があります。純粋なIMotionインターフェイスと、洗練された機能を提供するインターフェイスを実装する具体的なモーションオブジェクトの設計の難しさと、プライベートデータに対する不変式を維持しようとする問題と、問題の解決に関連する生データのみを提供し、気にしないモーションコンポーネントを比較機能。

機能はデータよりも適切に取得するのがはるかに難しいため、依存関係のフローをデータに向けることが望ましいと考えることが多いのはそのためです。結局のところ、ベクター/マトリックスライブラリはいくつありますか?それらのうち、まったく同じデータ表現を使用し、機能がわずかに異なるものはどれくらいありますか?数え切れないほど多くの機能がありますが、機能が微妙に異なるため、同一のデータ表現にもかかわらず多くの機能があります。画像ライブラリはいくつありますか?それらのうちどれだけが異なるユニークな方法でピクセルを表しますか?ほとんどありませんが、機能が多くのシナリオのデータよりもはるかに不安定で、設計が変更されやすいことを示しています。もちろん、ある時点で機能が必要になりますが、依存関係の大部分がデータに流れるシステムを設計できます。一般的な抽象化や機能性ではありません。これは、カップリングよりも安定性を優先します。

私がこれまでに書いた中で最も安定した関数(80年代後半からまったく使用せずに使用および再利用してきた種類)はすべて、生データに依存するすべての関数でした。複雑な依存山車と整数、ないものMeshオブジェクトまたはIMeshインタフェース、あるいはベクトル/行列の乗算だけに依存しているfloat[]double[]に依存していない1、 FancyMatrixObjectWhichWillRequireDesignChangesNextYearAndDeprecateWhatWeUse

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.