「疎結合」とは何ですか?例を挙げてください


172

「ルーズカップリング」の概念を理解できないようです。「緩い」という言葉が通常否定的な意味を持つことは役に立たないと思うので、疎結合が良いことをいつも忘れますことであることます。

誰かがこの概念を説明する「前」と「後」のコード(または疑似コード)を見せてくれませんか?


これが特定の言語からどのように分離できるかはわかりません。概念の一部は、言語を使用してコード単位が互いに絡み合うのを防ぐ方法です。また、答えのいくつかは、概念を説明するためにコードに頼っていることに注意してください。
オノリオカテナッチ

11
完全に同意しない場合、実用性は言語によって異なる方法で示される可能性があり、動的言語とコンパイルされた言語で特に顕著です。しかし、概念はどちらの方法でも同じです。
オーウェン

ルーズvsタイトカップリングvsデカップリング。一緒にタグ付けすることは、常に良いことではありません。時には、良いこともあれば、そうでないこともあります... 私たちは独自の独立性を持つ必要があるので、クラスもそうします。
bonCodigo 2014年

回答:


180

CartContentsクラスを使用してショッピングカート内のアイテムを追跡する単純なショッピングカートアプリケーションと、購入を処理するためのOrderクラスを考えてみます。Orderは、カートの内容の合計値を決定する必要があります。そのようにする場合があります。

密結合の例:

public class CartEntry
{
    public float Price;
    public int Quantity;
}

public class CartContents
{
    public CartEntry[] items;
}

public class Order
{
    private CartContents cart;
    private float salesTax;

    public Order(CartContents cart, float salesTax)
    {
        this.cart = cart;
        this.salesTax = salesTax;
    }

    public float OrderTotal()
    {
        float cartTotal = 0;
        for (int i = 0; i < cart.items.Length; i++)
        {
            cartTotal += cart.items[i].Price * cart.items[i].Quantity;
        }
        cartTotal += cartTotal*salesTax;
        return cartTotal;
    }
}

OrderTotalメソッド(およびOrde​​rクラス)がCartContentsクラスとCartEntryクラスの実装の詳細にどのように依存しているかに注意してください。このロジックを変更して割引を可能にしようとすると、おそらく3つのクラスすべてを変更する必要があります。また、Listコレクションを使用してアイテムを追跡するように変更した場合は、Orderクラスも変更する必要があります。

これが同じことをするための少し良い方法です:

結合度の低い例:

public class CartEntry
{
    public float Price;
    public int Quantity;

    public float GetLineItemTotal()
    {
        return Price * Quantity;
    }
}

public class CartContents
{
    public CartEntry[] items;

    public float GetCartItemsTotal()
    {
        float cartTotal = 0;
        foreach (CartEntry item in items)
        {
            cartTotal += item.GetLineItemTotal();
        }
        return cartTotal;
    }
}

public class Order
{
    private CartContents cart;
    private float salesTax;

    public Order(CartContents cart, float salesTax)
    {
        this.cart = cart;
        this.salesTax = salesTax;
    }

    public float OrderTotal()
    {
        return cart.GetCartItemsTotal() * (1.0f + salesTax);
    }
}

カートのラインアイテムまたはカートのコレクションまたは注文の実装に固有のロジックは、そのクラスのみに制限されています。したがって、他のクラスを変更せずに、これらのクラスの実装を変更できます。デザインを改善したり、インターフェースを導入したりすることで、このデカップリングをさらに進めることができますが、要点は理解できると思います。


(コンストラクターが理想的であるはずですが)依存性注入を介してさらにデカップリングを導入する答えを拡張できますか?
BAD_SEED 2013

4
@ウェッジ、私Orderがの知識を持っている理由はないと思いますCart。ライブショッピングとファクトレーションは、2つの異なるコンテキストです。クライアントが支払いの準備ができたら、CartEntriesをにとって意味のあるものに変換する責任のあるプロセスを持つことができますOrder。このようにして、Orderクラスはインスタンス化されずに使用されCartます。
plalx 2013年

@ウェッジ私のコメントに反応してくれませんか?
plalx 2013年

まあ、簡単に説明しました。「..OrderTotalメソッド(およびOrde​​rクラス)がCartContentsおよびCartEntryクラスの実装の詳細にどのように依存しているかに注意してください。」
okey_on

この例は明確に示されています。しかし、最近では、この過度にオブジェクト指向のスタイルは悪い習慣であると考える建築家が増えています。CartEntryおよびの「実装」の詳細を非表示にしても意味がありませんCartContents。これらは完全に明確な意味を持っているので、それらは単に死んだデータとしてモデル化されるべきです。データベースの用語では、ここで必要なのはテーブルだけですCREATE TABLE entry (price INTEGER, quantity INTEGER)
Jo So

160

iPodiPadなどの多くの統合製品(特にApple製)は密結合の良い例です:バッテリーが切れると、バッテリーははんだ付けされて固定され、緩まないため、新しいデバイスを購入する必要があります。高価な。疎結合のプレーヤーであれば、バッテリーを簡単に交換できます。

ソフトウェア開発についても同じことが言えます。拡張と置換を容易にするために(そして個々のパーツを理解しやすくするために)疎結合のコードを使用する方が(はるかに)優れています。ただし、ごくまれに、特別な状況下では、複数のモジュールの緊密な統合により最適化が改善されるため、密結合が有利になる場合があります。


疎結合または密結合は良いですか?疎結合または密結合の実装を決定するにはどうすればよいですか?
Sreekanth Karumanaghat、2015

2
この素晴らしい例に感謝します。私は他の回答に多くの時間を費やしましたが、このような価値はあり
ません

1
Sreekanth Karumanaghatさん、バッテリーだけにお金をかけずにiPodをもう一度使えるようにしたいですか、それともiPod全体にたくさんのお金をかけたいですか?
Koshera

1
@SreekanthKarumanaghat通常、疎結合はモジュール性を促進し、コードの保守を容易にするため、より良い方法です。クラス/ライブラリ/コードを密結合する場合、1つのクラスで行う小さな変更は、それを使用するすべてのクラスに実装する必要があります。
ケニーワーデン2017年

56

例としてJavaを使用します。次のようなクラスがあるとします。

public class ABC
{
   public void doDiskAccess() {...}
}

クラスを呼び出すときは、次のようにする必要があります。

ABC abc = new ABC();

abc. doDiskAccess();

ここまでは順調ですね。ここで、次のような別のクラスがあるとします。

public class XYZ
{
   public void doNetworkAccess() {...}
}

見た目はABCとまったく同じですが、ディスク上ではなくネットワーク経由で機能するとします。それでは、次のようなプログラムを書いてみましょう:

if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();

それは機能しますが、少し扱いに​​くいです。これを次のようなインターフェースで簡略化できます。

public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}

これで、コードは次のようになります。

Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();

それを理解するのにどれほどクリーンでシンプルかを見てください。疎結合の最初の基本理念である抽象化を理解したところです。ここからのポイントは、ABCとXYZが、それらを呼び出すクラスのメソッドや変数に依存しないようにすることです。これにより、ABCとXYZを完全に独立したAPIにすることができます。または、言い換えると、それらは親クラスから「分離」または「疎結合」されます。

しかし、2つの間の通信が必要な場合はどうでしょうか。それでは、イベントモデルのようなさらなる抽象化を使用して、親コードが作成したAPIと結合する必要がないようにします。


2
この例でも、かなり高いレベルの結合があります。たった今、単一のクラスに結合される代わりに、2つのクラスから選択できます。この例では、「実行可能な」実装が2つしかないことを前提としています。その場合、インターフェースは不要です。
オーウェン

これらのRun *とDo *という名前のメソッドは、私にとってコードの巨大な匂いです。IHandleStuffまたはIFrobnicateThingsを使用してこれをリファクタリングすることもできます。この場合、Runnableは非常に一般的な用語です。
ウェッジ

8
オーウェン、赤ちゃんが私の友達を踏みます。彼がカップリングを理解していない場合、彼は工場のパターンが彼を購入するものをどのように理解するでしょうか?このコード例は、彼を正しい軌道に乗せています。その意図は、彼が問題をよりよく理解し、オブジェクトの作成を抽象化する方法を理解することです。
64BitBob 2008年

6
ABCとXYZがDiskAccessorandのような名前に変更された場合、これはより読みやすくなりNetworkAccessorますか?私はJavaを
知ら

工場設計パターンも使用していますか?必要に応じて、新しいXYZまたはABCオブジェクトを作成しているからです。
munmunbb

37

申し訳ありませんが、「疎結合」はコーディングの問題ではなく、設計の問題です。「疎結合」という用語は、「高い凝集力」の望ましい状態と密接に関連しており、反対ですが相補的です。

疎結合とは、個々の設計要素を構築して、他の設計要素について知る必要のある不要な情報の量を減らすことを意味します。

高い凝集力は一種の「密結合」のようなものですが、高い凝集力は、お互いについて本当に知る必要のある設計要素がクリーンでエレガントに連携するように設計されている状態です。

重要なのは、一部の設計要素は他の設計要素の詳細を知っている必要があるため、誤ってではなく、そのように設計する必要があるということです。他の設計要素は他の設計要素の詳細を知らないはずなので、ランダムにではなく、そのように意図的に設計する必要があります。

これを実装することは、読者の練習問題として残します:)。


33

密結合コードは、具体的な実装に依存しています。コードに文字列のリストが必要で、これを次のように宣言した場合(Javaの場合)

ArrayList<String> myList = new ArrayList<String>();

その後、私はArrayListの実装に依存しています。

それを疎結合コードに変更したい場合は、参照をインターフェース(または他の抽象)タイプにします。

List<String> myList = new ArrayList<String>();

これによりメソッドを呼び出せなくなりますmyListそれは、ArrayListの実装に固有です。Listインターフェースで定義されているメソッドのみに制限されています。後でLinkedListが本当に必要だと判断した場合は、新しいリストを作成した1か所でコードを変更するだけでよく、ArrayListメソッドを呼び出した100か所では変更しません。

もちろん、あなたができる最初の宣言を使用してのArrayListをインスタンス化し、Listインタフェースの一部ではない任意のメソッドを使用していないから自分を抑えるが、2番目の宣言を使用すると、コンパイラが正直なあなたを保つことができます。


これはほとんど「カップリング」は、実際にどのように関係ないです。良い答えについては、stackoverflow.com / questions / 39946 / coupling-and-cohesionを参照してください。
ホジェリオ

@ロジェリオ:私はそれが関係していると思います。「カップリング」の他の定義に混乱しているかもしれませんが、ルーズカップリングをお読みください。「強い結合は、依存クラスに必要な動作を提供する具象クラスへのポインターが直接含まれている場合に発生します。疎結合は、依存クラスがインターフェースへのポインターのみを含む場合に発生し、1つまたは複数の具象クラスによって実装できます。 」私の例では、私のコードは、Listインターフェイスを介してArrayListに疎結合されます。
、トカゲに請求します。

@ビル:リンクをありがとう、しかしその記事は私には完全に偽物に思えます。別のドメイン(組織の振る舞い)からのアイデアを「再解釈」し、Larry Constantineによる元のソフトウェア固有の定義(en.wikipedia.org/wiki/Coupling_(computer_science))と矛盾する「疎結合」の定義を示しているようです。
ホジェリオ

@Rogerio:コンスタンティンの論文は1974年に書かれました。過去36年間に多くの再解釈が進んでいたと思われますが、ウィキペディアの記事がその出典であるとは思いません。たとえば、Dependency Injectionのようなパターンは、答えで説明したように、結合を緩めるためにインターフェースに依存しています。
、トカゲ

2
@ビル:確かに、構造化設計に関するコンスタンティンの仕事は古いものですが、私はそれを無効にするか根本的に再解釈する理由を見つけることができません。結合と結合の元の概念は、継承とポリモーフィズムと同じように、オブジェクト指向デザインの中核です。DI(より優れた記事はmartinfowler.com/articles/injection.html)は、プラグインの外部構成(実行時に構成コードを介して実装が選択された抽象インターフェース)のための手法にすぎません。別のそのような手法は、Service Locatorパターンです。DIとカップリングは独立した概念です。
ホジェリオ

26

ここでの答えの違いの程度は、なぜそれを理解するのが難しいが、私がそれを説明できるほど単純にそれを置くのが難しいのかを示しています。

私があなたにボールを投げたら、あなたはそれを捕まえることができることを私が知るために、私は本当にあなたが何歳であるかを知る必要はありません。私はあなたが朝食に何を食べたかを知る必要はありません、そして私はあなたの最初の片思いが誰であったか本当に気にしません。私が知る必要があるのは、あなたが捕まえることができるということだけです。私がこれを知っているなら、私があなたやあなたの兄弟にボールを投げているかどうかは気にしません。

c#やJavaなどの非動的言語では、インターフェイスを介してこれを実現します。したがって、次のインターフェイスがあるとします。

public ICatcher
{
   public void Catch();
}

そして、次のクラスがあるとしましょう:

public CatcherA : ICatcher
{
   public void Catch()
   {
      console.writeline("You Caught it");
   }

}
public CatcherB : ICatcher
{
   public void Catch()
   {
      console.writeline("Your brother Caught it");
   }

}

これで、CatcherAとCatcherBの両方がCatchメソッドを実装するため、Catcherを必要とするサービスはこれらのいずれかを使用でき、実際にどちらであるかを決定することはできません。したがって、緊密に結合されたサービスは、キャッチされたIEを直接インスタンス化する可能性があります。

public CatchService
{
   private CatcherA catcher = new CatcherA();

   public void CatchService()
   {
      catcher.Catch();
   }

}

したがって、CatchServiceは、設定したとおりのことを実行できますが、CatcherAを使用し、常にCatcherAを使用します。ハードコードされているため、誰かがやって来てリファクタリングするまでそこに留まります。

ここで、依存性注入と呼ばれる別のオプションを取ります。

public CatchService
{
   private ICatcher catcher;

   public void CatchService(ICatcher catcher)
   {
      this.catcher = catcher;
      catcher.Catch();
   }
}

したがって、CatchServiceをインスタンス化するcalssは、次のことを行う可能性があります。

CatchService catchService = new CatchService(new CatcherA());

または

CatchService catchService = new CatchService(new CatcherB());

これは、CatchサービスがCatcherAまたはCatcherBのいずれとも密結合されていないことを意味します。

IoCフレームワークの使用など、このような疎結合サービスには他にもいくつかの戦略があります。


1
この種のことがビジネスの世界で日常的に発生するため、この例は他の例よりも優れています。Class Personが実行されると、Class Catが実行され、Class Dogが実行されます。実行されるすべてのクラスを詳細に説明する巨大なプログラムになります。しかし、runsと呼ばれるインターフェイスを使用すると、各クラスが同じことを行うため、プログラムの柔軟性と管理性が大幅に向上します。:)
sksallaj 2012

最後の例で依存性注入を使用して実行したことを明確にするために、本当に最初の例も疎結合ですか?
アリサジッド2017

うわー、古い答えは:)にコメントしました。したがって、答えは「いいえ」です。最初の例はCatcherAに強く依存しているため、強く結合されています
Owen

23

(タイトまたはルーズ)カップリングは、特定のクラスを別のクラスへの依存から分離するために必要な文字通りの労力であると考えることができます。たとえば、クラスのすべてのメソッドの最後に、何かをログに記録するためにLog4Netを呼び出す小さなブロックがあった場合、クラスはLog4Netに密結合されていると言えます。クラスに、Log4Netコンポーネントを呼び出す唯一の場所であるLogSomethingというプライベートメソッドが含まれていた場合(および、他のすべてのメソッドが代わりにLogSomethingを呼び出した場合)、クラスはLog4Netに疎結合されていると言えます(それほど多くの時間がかかるわけではないためです)。 Log4Netを引き出して別のものに置き換えるための努力)。


1
では、「疎結合」は実際には依存関係が少ないことを意味しますか?私は正しいですか?
user314362

4
特定のクラスが持つ依存関係の総数とは実際には関係ありません。カップリング(タイトまたはルーズ)は、実際には2つのクラス間の関係の特性です。そのため、他の100個のクラスに疎結合されているクラスや、他の2つのクラス(たとえば)に密結合されているクラスがあるとします。
MusiGenesis

2
悪い例、私は言うでしょう:あなたが持っているのはコードの重複であり、密結合ではありません。そして、優れたリファクタリングツールがあれば、そのような重複は数秒で解消できます。
ホジェリオ

@ロジェリオ:それはおそらく最良の例ではありません。私64BitBobは自分自身の答えが好きです。
MusiGenesis

12

定義

基本的に、結合とは、特定のオブジェクトまたはオブジェクトのセットが、そのタスクを実行するために、別のオブジェクトまたは別のオブジェクトのセットにどれだけ依存しているかを示します。

高結合

車について考えてください。エンジンを始動するには、キーを点火装置に挿入し、回転させ、ガソリンを供給し、火花を発生させ、ピストンを始動させ、エンジンを始動させる必要があります。車のエンジンは他のいくつかのオブジェクトと高度に結合していると言えます。これは高い結合ですが、それは実際に悪いことではありません。

ゆるいカップリング

ユーザーが特定の種類の情報を投稿、編集、表示できるようにするWebページのユーザーコントロールについて考えてみます。単一のコントロールを使用して、ユーザーが新しい情報を投稿したり、新しい情報を編集したりできます。コントロールは、2つの異なるパス(新規および編集)間で共有できる必要があります。コントロールが、そのコントロールを含むページからのある種のデータを必要とするような方法で記述されている場合は、結合が強すぎると言えます。コントロールはそのコンテナーページから何も必要ありません。


7

これはかなり一般的な概念であるため、コード例では全体像がわかりません。

「パターンはフラクタルのようなもので、実際にズームインすると、アーキテクチャレベルにズームアウトすると、パターンを見ることができます。」

ウィキペディアの簡単なページを読むと、この一般性を感じることができます。

http://en.wikipedia.org/wiki/Loose_coupling

特定のコード例まで...

Microsoft.Practices.CompositeUIのものから、最近使用した疎結合の1つを示します。

    [ServiceDependency]
    public ICustomizableGridService CustomizableGridService
    {
        protected get { return _customizableGridService; }
        set { _customizableGridService = value; }
    }

このコードは、このクラスがCustomizableGridServiceに依存していることを宣言しています。サービスの正確な実装を直接参照するのではなく、単にそのサービスの実装が必要であることを示します。次に、実行時に、システムはその依存関係を解決します。

それが明確でない場合は、ここでより詳細な説明を読むことができます:

http://en.wikipedia.org/wiki/Dependency_injection

ABCCustomizableGridServiceが、ここでフックするつもりの実装であると想像してください。

必要に応じて、それを取り出してXYZCustomizableGridServiceまたはStubCustomizableGridServiceに置き換えることができます。この依存関係を持つクラスはまったく変更しません。

ABCCustomizableGridServiceを直接参照していた場合、別のサービス実装でスワップするために、その参照を変更する必要があります。


6

結合は、システム間の依存関係に関係します。システム間の依存関係には、コードのモジュール(関数、ファイル、またはクラス)、パイプラインのツール、サーバークライアントプロセスなどがあります。1つのシステムを変更すると、それに依存する他のシステムを変更する必要があるため、依存関係が一般的でないほど、それらはより「密結合」になります。理想的な状況は、1つのシステムを変更でき、それに依存するシステムが変更なしで機能し続ける「疎結合」です。

疎結合を実現する一般的な方法は、明確に定義されたインターフェースを使用することです。2つのシステム間の相互作用が明確に定義され、両側で守られている場合は、規則に違反しないようにしながら、1つのシステムを変更することが容易になります。よく定義されたインターフェースが確立されていないことが実際に発生し、その結果、デザインがずさんになり、結合が密になります。

いくつかの例:

  • アプリケーションはライブラリに依存します。密結合の下では、アプリは新しいバージョンのlibで中断します。「DLL Hell」のGoogle。

  • クライアントアプリはサーバーからデータを読み取ります。密結合では、サーバーへの変更にはクライアント側での修正が必要です。

  • 2つのクラスがオブジェクト指向階層で相互作用します。密結合では、1つのクラスを変更するには、他のクラスを一致するように更新する必要があります。

  • 複数のコマンドラインツールがパイプで通信します。それらが密に結合されている場合、1つのコマンドラインツールのバージョンを変更すると、その出力を読み取るツールでエラーが発生します。


5

結合とは、さまざまなクラスが互いにどの程度密接に接続されているかを指します。密結合クラスには、多数の相互作用と依存関係が含まれています。

疎結合クラスは、相互の依存関係が最小限に保たれ、代わりに明確に定義された相互のパブリックインターフェイスに依存するという点で、反対です。

レゴ、SNAPが一緒におもちゃを一緒にスナップし、必要なシステムを構築できるため、疎結合と見なされます。ただし、ジグソーパズルには、密結合のピースがあります。1つのジグソーパズル(システム)からピースを取り出して別のパズルにスナップすることはできません。システム(パズル)は、特定の「デザイン」に固有に構築された非常に具体的なピースに大きく依存しているためです。レゴはより一般的な方法で構築されているため、レゴハウスや私のレゴエイリアンマンで使用できます。

リファレンス:https : //megocode3.wordpress.com/2008/02/14/coupling-and-cohesion/


4

2つのコンポーネントがお互いの具体的な実装に依存している場合、これらのコンポーネントは完全に結合されます。

私のクラスのメソッドのどこかにこのコードがあるとします。

this.some_object = new SomeObject();

現在、私のクラスはSomeObjectに依存しており、それらは高度に結合されています。一方、InjectSomeObjectメソッドがあるとします。

void InjectSomeObject(ISomeObject so) { // note we require an interface, not concrete implementation
  this.some_object = so;
}

その後、最初の例では、注入されたSomeObjectを使用できます。これはテスト中に役立ちます。通常の操作では、データベースを使用し、ネットワークを使用する重いクラスなどを使用できますが、テストは軽量のモック実装を通過します。緊密に結合されたコードでは、それを行うことはできません。

依存関係注入コンテナを使用することで、この作業の一部を簡単にすることができます。ウィキペディアでDIの詳細を読むことができます:http : //en.wikipedia.org/wiki/Dependency_injection

これを遠くに取りすぎるのは簡単な場合があります。ある時点で、物事を具体的にする必要があります。そうしないと、プログラムが読みにくく、理解しにくくなります。したがって、この手法は主にコンポーネントの境界で使用し、何をしているのかを理解してください。疎結合を利用していることを確認してください。そうでない場合は、おそらくその場所では必要ありません。DIはプログラムをより複雑にする場合があります。あなたが良いトレードオフを作ることを確認してください。つまり、バランスを保つ。システムを設計するときはいつものように。幸運を!


3

FormAとFormBを備えたWindowsアプリを考えてみましょう。FormAはプライマリフォームで、FormBを表示します。FormBが親にデータを戻す必要があると想像してください。

これを行った場合:

class FormA 
{
    FormB fb = new FormB( this );

    ...
    fb.Show();
}

class FormB 
{
    FormA parent;

    public FormB( FormA parent )
    {
        this.parent = parent;
    }     
}

FormBはFormAと密結合しています。FormBには、フォームAの親以外の親はありません。

一方、FormBにイベントを発行させ、FormAにそのイベントをサブスクライブさせると、FormBはそのイベントを介して、そのイベントが持つサブスクライバーにデータをプッシュバックできます。この場合、FormBは親とのやり取りについても知りません。疎結合により、イベントは単にサブスクライバーと話しているだけです。これで、任意のタイプをFormAの親にすることができます。

rp


3

コンピュータサイエンスでは、ここで他の誰も投稿していない「疎結合」の別の意味があるので、ここに行きます-うまくいけば、あなたが私に投票して、ヒープの下部で失われないようにしてください!確かに私の答えの主題は質問への包括的な答えに属しています...ウィットするには:

「ルーズカップリング」という用語は、マルチCPU構成のCPUアーキテクチャに関する形容詞として使用される用語として最初にコンピューティングに入りました。対応する用語は「密結合」です。疎結合は、CPUが多くのリソースを共有しない場合であり、密結合はそれらを共有する場合です。

「システム」という用語はここでは混乱する可能性があるので、状況を注意深く解析してください。

常にではありませんが、通常、1つのシステム内に存在するハードウェア構成の複数のCPU(個々の「PC」ボックスなど)は、密結合されます。「システム」間で実際にメインメモリを共有するサブシステムを持ついくつかの超高性能システムを除いて、すべての分割可能なシステムは疎結合です。

マルチスレッドおよびマルチコアCPUが発明される前に、密結合および疎結合という用語が導入されたため、これらの用語は、今日の状況を完全に説明するためにいくつかの仲間が必要になる場合があります。そして実際、今日では、1つのシステム全体で両方のタイプを包括するシステムが非常によくあるでしょう。現在のソフトウェアシステムに関しては、2つの一般的なアーキテクチャがあり、それぞれに1つずつありますが、これらはよく知られているはずです。

まず、それが問題であったため、疎結合システムのいくつかの例:

  • VaxClusters
  • Linuxクラスター

対照的に、いくつかの密結合の例:

  • Semetrical-Multi-Processing(SMP)オペレーティングシステム-Fedora 9など
  • マルチスレッドCPU
  • マルチコアCPU

今日のコンピューティングでは、両方が単一のシステム全体で動作する例は珍しくありません。たとえば、Fedora 9を実行する最新のPentiumデュアルまたはクアッドコアCPUを考えてみます。これらは密結合のコンピューティングシステムです。次に、それらのいくつかを疎結合Linuxクラスターに結合すると、疎結合と密結合の両方のコンピューティングが実行されます!ああ、現代のハードウェアは素晴らしいものではありません!


3

単純な言語では、疎結合とは、発生する他のイベントに依存しないことを意味します。独立して実行されます。


1
それは本当ではありません-他の例で述べたように、エンティティ(モジュール、クラス)の間に関係があるかどうかについてはそれほど重要ではありませんが、同じ機能を実装する他のクラスと簡単に交換できるかどうかは関係ありません。たとえば、ViewModelはさまざまなモデルで動作する可能性がありますが、モデルがないと動作しません
Hayden Crocker

ええ、あまり
役に立た

2

ここにいくつかの長い答えがあります。原則は非常に簡単です。私はウィキペディアから冒頭の声明を提出します。

「疎結合とは、ある種の交換関係を持つ2つ以上のシステムまたは組織間の回復力のある関係を表します。

トランザクションの両端では、要件が明確になり、もう一方の端についてはほとんど想定されません。」


1
もしそれがとても簡単だったら、この議論はありません。
brgs

2

コード結合の非常に簡単なテストを提案します。

  1. 正確さを保つためにピースAを強制的に変更する可能性のあるピースBへの変更が存在する場合、ピースAのコードはピースBのコードに密結合されます。

  2. ピースAへの変更を必要とする可能性のあるピースBへの変更がない場合、ピースAのコードはピースBのコードと緊密に結合されていません。

これは、コードの断片間にどの程度の結合があるかを確認するのに役立ちます。その理由については、次のブログ投稿を参照してください。http//marekdec.wordpress.com/2012/11/14/loose-coupling-tight-coupling-decoupling-what-is-that-all-about/


2

を使用してクラスのオブジェクトを作成するとき new他のクラスでキーワードを実際には密結合(悪い習慣)を行っていますが、代わりに疎結合を使用することをお勧めします。

--- A.java ---

package interface_package.loose_coupling;

public class A {

void display(InterfaceClass obji)
{
    obji.display();
    System.out.println(obji.getVar());
}
}

--- B.java ---

package interface_package.loose_coupling;

public class B implements InterfaceClass{

private String var="variable Interface";

public String getVar() {
    return var;
}

public void setVar(String var) {
    this.var = var;
}

@Override
public void display() {
    // TODO Auto-generated method stub
    System.out.println("Display Method Called");
}
}

--- InterfaceClass ---

package interface_package.loose_coupling;

public interface InterfaceClass {

void display();
String getVar();
}

--- MainClass ---

package interface_package.loose_coupling;

public class MainClass {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    A obja=new A();
    B objb=new B();
    obja.display(objb);     //Calling display of A class with object of B class 

}
}

説明:

上記の例では、2つのクラスAとBがあります。

クラスBは、InterfaceClassなどのインターフェースを実装します。

InterfaceClassはBクラスのコントラクトを定義します。InterfaceClassには、Aなどの他のクラスからアクセスできるBクラスの抽象メソッドがあるためです。

クラスAには、InterfaceClassを実装するクラスのオブジェクトを除外できる表示メソッドがあります(この場合はBクラスです)。そして、クラスAのオブジェクトメソッドはクラスBのdisplay()とgetVar()を呼び出しています

MainClassでは、クラスAとBのオブジェクトを作成しました。また、Bクラスのオブジェクト、つまりobjbを渡して、Aの表示メソッドを呼び出します。Aの表示メソッドはBクラスのオブジェクトで呼び出されます。

次に疎結合について話します。将来、クラスBの名前をABCに変更する必要がある場合、クラスBの表示メソッドでその名前を変更する必要はなく、新しいオブジェクト(ABCクラス)を作成して、それをMailClassの表示メソッドに渡すだけです。クラスAで何も変更する必要はありません

参照:http : //p3lang.com/2013/06/loose-coupling-example-using-interface/


0

「疎結合」の一般的な概念について詳しく読むことができます。

つまり、これは2つのクラス間の関係の説明であり、各クラスは互いについて最低限知っており、各クラスは、他が存在するかどうかに関係なく、他の特定の実装に依存することなく、正常に機能し続ける可能性があります。クラス。


-8

一般に、疎結合は、同じワークロードで互いに独立して動作する2つのアクターです。したがって、同じバックエンドデータベースを使用する2つのWebサーバーがある場合、これらのWebサーバーは疎結合されていると言えます。密結合の例として、1つのWebサーバーに2つのプロセッサを搭載することが挙げられます。これらのプロセッサは密結合されています。

少しお役に立てば幸いです。


1
私はあなたが何をしているのかわかりますが、2つの「もの」が独立して存在するときの疎結合と比べて、2つの「もの」が相互に依存している場合と比べて、密結合はそれを説明するのにあまり良い方法ではありません他の「もの」に変更を加えることなく変更されます...
ブライアンレーバイン'22 / 10/22

スティーブ、あなたは正解です。あなたは反対投票に値するものではありませんでした。それはあなたの聴衆があなたの専門用語の準備ができていなかっただけで、このサイトのあまりにも多くは彼らが理解していないことや不慣れなことを投票する傾向があります。-shrug-
リチャードT

スティーブは要点を逃したと思います。疎結合は、必ずしも2つのアクターが同じワークロードで独立して動作することを意味するわけではありません。
ロブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.