デカップリングとは何ですか?また、どの開発分野に適用できますか?[閉まっている]


21

私は最近、デカップリングが質問のトピックであることに気付き、それが何であり、どこで適用できるかを知りたいです。

「どこに適用できる」とは、次のことを意味します。

CやJavaのようなコンパイルされた言語が関係する場合にのみ関係がありますか?

ウェブ開発者としてそれを知って勉強すべきですか?


少し調査して、定義の不明確な部分に基づいて質問をすると役立ちます。
ジェフ14年

2
@JeffO-世界は、特定のニュアンスの質問から得られるのと同じくらい、完全な概念の質問から恩恵を受けると思います。「なぜ空は青いの?」細目を極端に詳細に説明することなく、コンセプト自体をカバーする回答を許可します。だから私は先に進み、調査せずに質問をした。

あなたが抱えている具体的な問題は何ですか?それが今立っているとして、あなたの質問は非常に広すぎます。現在の形式では、答えは基本的にストラクチャードデザインの全文です。エドワード・ユアドンとラリー・コンスタンティンによるコンピュータープログラムとシステムデザインの分野の基礎
ヨルグWミッターク14年

ここでの答えは、コンセプトを説明する完璧な仕事だと思います。「プログラミングに関連してこの言葉の定義は何ですか」と尋ねるようなものです。@ GlenH7

1
@ jt0dd私は同意する必要があります。本で何かを説明できるからといって、より簡潔な答えに価値がないという意味ではありません。プログラミングに関する文献では、人々はしばしば、きちんとした高レベルの概要を説明する前に、詳細をあなたに押し付けます。「OOPとは」広すぎるでしょう。しかし、これはかなり具体的なトピックIMOです。
エリックReppen 14年

回答:


57

「結合」は、ソフトウェアシステム内の2つのエンティティ(通常はクラス)間の関係を表す用語です。

クラスが別のクラスを使用する場合、またはクラスと通信する場合、その別のクラスに「依存する」と言われるため、これらのクラスは「結合」されます。そのうちの少なくとも1人は、もう一方について「知っている」。

考えは、システム内のクラス間の結合を可能な限り「緩い」状態に保つようにすることです。したがって、「緩い結合」または「デカップリング」(英語では「デカップリング」は「カップリングなし」を意味しますが、多くの場合、エンティティ間の「疎結合」を意味するために使用します)。

だから、実際には疎結合と強結合とは何ですか?また、エンティティを疎結合にする必要があるのはなぜですか?


結合は、あるエンティティと別のエンティティとの間の依存度を表します。多くの場合、クラスまたはオブジェクト。

ClassAがClassBに大きく依存している場合、ClassBが変更されたときにClassAが影響を受ける可能性が高くなります。これは強い結合です。

ただし、ClassAがClassBに軽く依存している場合、ClassAがClassBのコードの変更によって何らかの影響を受ける可能性は低くなります。これは疎結合、または「分離」関係です。

疎結合は、システムのコンポーネントが互いに大きく依存することを望まないため、適切です。システムのモジュール化を維持したいので、一方の部分に影響を与えることなく安全に変更できます。

2つのパーツが疎結合されている場合、それらは互いにより独立しており、他のパーツが変更されたときに破損する可能性は低くなります。

たとえば、車を作るとき、エンジンの内部の変更がハンドルの何かを壊したくはないでしょう。

これは車を作るときに偶然起こることはありませんが、同様のことがプログラマーに常に起こります。疎結合は、こうした事態が発生するリスクを減らすことを目的としています。

エンティティB.についてのエンティティAがあまりにも多くを知っている時に強力な結合は、通常発生した場合、エンティティAがエンティティBの変化が実体A.影響するという危険性が高いよりも、エンティティBは、それが構築されているどのように動作や方法については、あまりにも多くの仮定になりこれをこれは、エンティティBに関する前提の1つが誤っているためです。

たとえば、ドライバーとして、あなたの車のエンジンがどのように機能するかについて特定の仮定をすることを想像してください。

エンジンの動作が異なる(または何らかの理由でエンジンが交換された)新しい車を購入した日は、以前の仮定が間違っていました。コンピューターでコードを作成していた場合、正しく動作しない不適切なコードになります。

ただし、運転手として車について行った仮定がすべてAである場合、A-ハンドルがあり、B-ブレーキとアクセルペダルがあること、車の変化はあなたにいくつかの仮定がある限り影響しません常に正しい これは疎結合です。


疎結合を実現するための重要な手法は、カプセル化です。アイデアは、クラスが他のクラスから内部の詳細を隠し、他のクラスと通信するために厳密に定義されたインターフェースを提供するというものです。

あなたはクラスの車を定義したのであれば、たとえば、それのインターフェイス(パブリックメソッド)は、おそらくだろうdrive()stop()steerLeft()steerRight()getSpeed()。これらは、他のオブジェクトがCarオブジェクトで呼び出すことができるメソッドです。

Carクラスの他のすべての詳細:エンジンの動作方法、使用する燃料の種類などは、他のクラスから隠されています-Carについてあまり知りすぎないようにするためです。

クラスAがクラスBについて多くのことを知っている瞬間:クラスAはクラスBに依存しすぎており、クラスBの変更はクラスAに影響を与える可能性が高いため、システムの拡張と保守を難しくします。

2つのエンティティ間の関係は、互いについてほとんど知らない(必要なもののみ)-疎結合または分離された関係です。


3

一般的に、デカップリングとは、2つのことが密接に連携する必要があるかどうか、またはさらに独立させることができるかどうかを確認することです。独立性は、これらのものを簡単に変更したり、他の場所で使用したりできるため、素晴らしいです。開発だけでなく、多くの分野でデカップリングを適用できます。これは、一時的なデカップリングの場合に特に当てはまります。また、ソフトウェア開発には考慮すべき多くのタイプのカップリングがあり、すべてが回答でカバーされるわけではありません。あなたの研究を行う必要があります。

2つのものABは、それらの間に依存関係がある場合に結合されます。AがBに依存している場合、Aを考慮せずにBを使用できます。Aを使用する場合は、Aが依存するため、Bも持ち越さなければなりません。

ソフトウェア開発では、通常、コンポーネント間の結合を完全に削除することはできません。そのコンテキストでのデカップリングは、通常、既存のカップリングを緩めることを意味します。つまり、各コンポーネントがその周りの他のコンポーネントについて可能な限りほとんど知らないようにします。

これはおそらく、野生で見られる最も一般的なタイプのカップリングです。

//Inside a class meant to display info for a particular Facebook user.
void DisplayFriends(FacebookUser user, FacebookClient client)
{
     Friend[] = (Friend[])client.GetConnection().ExecuteCommandForResult("getFriends:" + user.Name);
     ...
}

ここで、DisplayFriendsは、必要なものを取得するために、Facebookクライアントの背後の接続を不必要に手動で操作しています。DisplayFriendsクラスは両方に結合されているFacebookClientConnection。FacebookClientが使用する接続の種類を突然変更すると、アプリはFacebookの友達を取得できなくなります。FacebookClientに必要なものを提供するように依頼することで、DisplayFriendsのクラスとConnectionの間のカップリングを削除できます。

//Inside a class meant to display info for a particular Facebook user.
void DisplayFriends(FacebookUser user, FacebookClient client)
{
     Friend[] = client.GetFriends(user);
     ...
}

FacebookClientが友人をどのように取得するかはあまり気にしません。私たちが本当に気にするのは、それが彼らを獲得するという事実です。内部の振る舞いに変更を加えても、私たち自身のクラスにダメージを与えることはありません。

この種のデカップリングは、関数のデメテルの法則に従うことで簡単に達成できます(Wikipediaを引用)。

関数のDemeterの法則では、オブジェクトOのメソッドmは、次の種類のオブジェクトのメソッドのみを呼び出すことができます。

  • O自体
  • mのパラメーター
  • m内で作成/インスタンス化されたオブジェクト
  • Oの直接コンポーネントオブジェクト
  • Oでアクセス可能な、mのスコープ内のグローバル変数

回答の冒頭で一時的な結合について言及したので、簡単に説明します。

通常、アルゴリズムを並行して実行するアプリケーションを設計する際には、時間的結合が考慮されます。2つの実行可能ユニット(実際の命令、メソッド、またはユニットと見なすもの)を検討してください。Aを実行する前にBを実行する必要がある場合、AはBに一時的に結合されます。AがBに一時的に結合されていない場合、AとBは同時に実行できます。これのためにあなた自身の例を構築してください:あなたがあなたの日常生活でする通常のことを考えてください。次から次へと行うことは2つありますが、同時に行うことができますか?

最後に、最後のビットに答えます:

ウェブ開発者としてそれを知って勉強すべきですか?

はい。たとえば、Web開発(MVC)の最も一般的なデザインパターンの1つは、すべて分離です。


1

他の答えは、デカップリングが何であるかを説明するのに適しています。最後の質問について話したいと思いました。

ウェブ開発者としてそれを知って勉強すべきですか?

答えはイエスです。あなたがどんな開発者であるかは関係ありません。Web開発者または組み込みシステム開発者になることができます。

Webページに配置されるカスタムURLを生成するクラスがあるとしましょう。クラスにURLを直接ページに書き込み、aタグのhrefに配置させたいと思うかもしれません。これは最初は簡単に見えるかもしれません。しかし、リンクをメールに入れてユーザーに送信するために変更を加える必要がある場合はどうなりますか?URLジェネレーターは、使用しているWebフレームワークと密結合しているため、現在のコードは機能しません。

より良いオプションは、URLを文字列として返すURLジェネレータークラスを持つことです。これはWebコードで使用でき、メールコードでも使用できます。分離されたコードを作成することは前もってより多くの作業のように思えるかもしれませんが、その努力は時間の経過とともに報われます。

モジュール化および分離されたコードを使用すると、どのプログラミングドメインで作業していても、コードがより理解しやすく、テストしやすく、保守しやすくなります。


これと他の2つの答えの後、私は本当にこれを取得し、どのように使用できるかを確認します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.