“Gevşek bağlantı” nedir? Lütfen örnekler verin


172

"Gevşek bağlantı" kavramını çılgına çeviremiyorum. Sanırım "gevşek" kelimesinin genellikle olumsuz bir çağrışımına sahip olmadığına yardımcı olmuyor, bu yüzden her zaman gevşek bağlantının iyi bir şey olduğunu unutuyorum .

Birisi lütfen bu kavramı gösteren bazı "önce" ve "sonra" kodlarını (veya sözde kodu) gösterecek mi?


Bunun belirli bir dilden nasıl ayrılabileceğinden emin değilim, çünkü kavramın bir kısmı kod birimlerinin birbirine çok fazla karışmasını önlemek için nasıl bir dil kullanıyor. Ayrıca cevapların birkaçının konsepti göstermek için kodlamaya başvurduğuna dikkat çekiyorum.
Onorio Catenacci

11
Tamamen katılmıyorum, pratikler farklı dillerde farklı şekillerde gösterilebilir ve özellikle dinamik ve derlenmiş dillerde görülür. Ancak konsept her iki şekilde de aynıdır.
Owen

Gevşek vs Sıkı ve Kaplin vs Ayırma . Birlikte etiketlemek her zaman iyi bir şey değildir, bazen iyi / bazen iyi değildir ... Kendi bağımsızlığımız olması gerektiği gibi , sınıflar da öyle.
bonCodigo

Yanıtlar:


180

Alışveriş sepetindeki öğeleri takip etmek için bir CartContents sınıfı ve bir satın alma işlemini gerçekleştirmek için bir Sipariş sınıfı kullanan basit bir alışveriş sepeti uygulamasını düşünün. Siparişin, alışveriş sepetindeki içeriğin toplam değerini belirlemesi gerekir, bunu şu şekilde yapabilir:

Sıkı Bağlantılı Örnek:

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 yönteminin (ve dolayısıyla Order sınıfının) CartContents ve CartEntry sınıflarının uygulama ayrıntılarına nasıl bağlı olduğuna dikkat edin. İndirimlere izin vermek için bu mantığı değiştirmeye çalışacak olsaydık, muhtemelen 3 sınıfı da değiştirmeliydik. Ayrıca, öğeleri takip etmek için bir Liste koleksiyonu kullanmaya geçersek, Order sınıfını da değiştirmeliyiz.

Şimdi aynı şeyi yapmanın biraz daha iyi bir yolu var:

Daha Az Bağlantılı Örnek:

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);
    }
}

Alışveriş sepeti satır öğesinin veya alışveriş sepeti koleksiyonunun veya siparişin uygulanmasına özgü mantık yalnızca bu sınıfla sınırlıdır. Böylece, bu sınıflardan herhangi birinin uygulanmasını, diğer sınıfları değiştirmek zorunda kalmadan değiştirebiliriz. Bu ayrıştırmayı tasarımı geliştirerek, arayüzler vb. Tanıtarak daha ileriye götürebiliriz, ama bence bu noktayı görüyorsunuz.


Bağımlılık enjeksiyonu yoluyla daha fazla ayrıştırma getirerek cevabı genişletebilir misiniz (yapıcı ideal olsa da)?
BAD_SEED

4
@Wedge, Ordera bilgisine sahip olmak için hiçbir neden göremiyorum Cart. Canlı alışveriş ve gerçekleşme iki farklı bağlamdır. Müşteri ödeme yapmaya hazır olduğunda, CartEntries'i için anlamlı bir şeye çevirmekten sorumlu bir işleminiz olabilir Order. Bu şekilde Ordersınıf, a Cart.
plalx

@Wedge Yorumuma tepki verebilir misiniz lütfen?
plalx

Peki ve basitçe açıkladı. Işığı görmeye başladım ".. OrderTotal yönteminin (ve dolayısıyla Order sınıfının) CartContents ve CartEntry sınıflarının uygulama detaylarına nasıl bağlı olduğuna dikkat edin .."
okey_on 30:15

Bu örnek açıkça sunulmuştur. Ancak bu günlerde, giderek daha fazla mimar bu aşırı nesne yönelimli stilin kötü uygulama olduğu konusunda hemfikir. Arasında "uygulama" ayrıntıları saklamanın bir anlamı yoktur CartEntryve CartContents. Bunların mükemmel bir anlamı olduğu için, basitçe ölü veriler olarak modellenmeleri gerekir. Veritabanı açısından, burada gereken tek şey bir tabloCREATE TABLE entry (price INTEGER, quantity INTEGER)
Jo So

160

Gibi (özellikle Apple tarafından) Birçok entegre ürünler iPod'lar , iPad'ler sıkı bağlantı için iyi bir örnek vardır: Pil Pil sabit lehimlenmiş çünkü siz de yeni bir cihaz satın alabilir ölür ve böylece çok değiştirilmesi yapım gevşek gelmeyecek bir kez pahalı. Gevşek bağlanmış bir oyuncu, pilin zahmetsizce değiştirilmesine izin verecektir.

Aynı şey yazılım geliştirme için de geçerlidir: uzatma ve değiştirme işlemlerini kolaylaştırmak (ve münferit parçaların daha kolay anlaşılmasını sağlamak) için gevşek bir şekilde kodlanmış olması genellikle (çok) daha iyidir. Ancak, çok nadiren, özel koşullar altında sıkı bağlantı avantajlı olabilir çünkü birkaç modülün sıkı entegrasyonu daha iyi optimizasyon sağlar.


Gevşek veya sıkı bağlantı iyi mi? Gevşek kaplin veya sıkı kaplin uygulamaya nasıl karar verilir?
Sreekanth Karumanaghat

2
Bu harika örnek için teşekkürler. diğer cevaplar üzerinde çok zaman geçirdim ama böyle değmez
alamin

1
Sreekanth Karumanaghat, sadece bir batarya için daha az para harcamayı ve tekrar çalışan bir iPod almayı mı tercih edersiniz yoksa tüm iPod için çok para harcamayı mı tercih edersiniz?
Koshera

1
@SreekanthKarumanaghat Tipik olarak gevşek bağlantı daha iyidir çünkü modülerliği arttırır ve böylece kodun bakımını kolaylaştırır. Sınıflarınızı / kitaplıklarınızı / kodunuzu sıkıca birleştirirseniz, bir sınıfta yaptığınız küçük değişikliklerin onu kullanan tüm sınıflara uygulanması gerekir.
Kenny Worden

56

Java'yı örnek olarak kullanacağım. Diyelim ki şöyle bir sınıfımız var:

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

Sınıfı aradığımda şöyle bir şey yapmam gerekecek:

ABC abc = new ABC();

abc. doDiskAccess();

Çok uzak çok iyi. Şimdi buna benzeyen başka bir dersim olduğunu varsayalım:

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

ABC ile tamamen aynı görünüyor, ancak diyelim ki disk yerine ağ üzerinden çalışıyor. Şimdi şöyle bir program yazalım:

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

Bu işe yarıyor, ama biraz hantal. Ben böyle bir arayüz ile bu basitleştirmek olabilir:

public interface Runnable
{
    public void run();
}

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

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

Şimdi kodum şöyle görünebilir:

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

obj.run();

Bunun ne kadar temiz ve anlaşılır olduğunu görün. Gevşek bağlantının ilk temel ilkesini anladık: soyutlama. Buradaki anahtar, ABC ve XYZ'nin onları çağıran sınıfların herhangi bir yöntemine veya değişkenine bağlı olmamasını sağlamaktır. Bu, ABC ve XYZ'nin tamamen bağımsız API'lar olmasını sağlar. Veya başka bir deyişle, ana sınıflardan "ayrıştırılır" veya "gevşek bağlanırlar".

Ama ya ikisi arasında iletişime ihtiyacımız olursa? Üst kodun oluşturduğunuz API'larla hiçbir zaman eşleşmemesini sağlamak için Etkinlik Modeli gibi daha fazla soyutlama kullanabiliriz .


2
Bu örnek hala oldukça yüksek bir bağlantı seviyesine sahiptir. Sadece şimdi tek bir sınıfa bağlanmak yerine, aralarından seçim yapabileceğiniz iki tane var. Bu örnek, yalnızca iki "Çalıştırılabilir" uygulamanın mevcut olacağını varsayar. Bu durumda bir arabirim bile gerekli değildir.
Owen

Bu Run * ve Do * adlı yöntemler benim için büyük bir kod kokusu. Bunu IHandleStuff veya IFrobnicateThings kullanarak yeniden düzenleyebilirsiniz. Runnable çok, bu durumda çok genel bir terimdir.
Kama

8
Owen, bebeğim arkadaşımla görüşür. Kuplajı anlamıyorsa, bir fabrika modelinin onu satın aldığını nasıl anlayacak? Bu kod örneği onu doğru yola koyar. Amaç, sorunu daha iyi anlaması ve nesnelerin yaratılışının nasıl soyutlanacağını fark etmesidir.
64BitBob

6
ABC ve XYZ gibi bir şey değiştirildi olsaydı bu daha okunabilir olur DiskAccessorve NetworkAccessor? I jun no java ...
MusiGenesis

Ayrıca fabrika tasarım deseni kullanıyor mu? Çünkü ihtiyaca göre yeni XYZ veya ABC nesneleri yaratıyoruz.
munmunbb

37

Maalesef, "gevşek bağlantı" bir kodlama sorunu değil, bir tasarım sorunu. "Gevşek bağlanma" terimi, zıt fakat tamamlayıcı olmak üzere arzu edilen "yüksek uyum" durumu ile yakından ilgilidir.

Gevşek kaplin, tek tek tasarım elemanlarının, diğer tasarım elemanları hakkında bilmeleri gereken gereksiz bilgi miktarının azaltılacağı şekilde inşa edilmesi gerektiği anlamına gelir.

Yüksek uyum bir tür "sıkı bağlantı" gibidir, ancak yüksek uyum birbirlerini gerçekten bilmeleri gereken tasarım öğelerinin birlikte temiz ve zarif bir şekilde çalışacak şekilde tasarlandığı bir durumdur.

Mesele şu ki, bazı tasarım öğeleri diğer tasarım öğeleri hakkındaki ayrıntıları bilmelidir, bu yüzden yanlışlıkla değil bu şekilde tasarlanmalıdırlar. Diğer tasarım öğeleri, diğer tasarım öğeleri hakkındaki ayrıntıları bilmemelidir, bu nedenle rastgele değil, bu şekilde tasarlanmalıdır.

Bunu uygulamak okuyucu için bir alıştırma olarak bırakılmıştır :).


33

Sıkı birleştirilmiş kod somut bir uygulamaya dayanır. Kodumdaki dizelerin bir listesine ihtiyacım varsa ve bunu böyle beyan ederim (Java'da)

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

ArrayList uygulamasına bağımlıyım.

Eğer gevşek bağlı kod değiştirmek istiyorsanız, benim referans bir arayüz (veya başka bir soyut) türü yapmak.

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

Bu , ArrayList uygulamasına özgü herhangi bir yöntemi çağırmamı engelliyor myList. Yalnızca Liste arabiriminde tanımlanan yöntemlerle sınırlıyım. Daha sonra gerçekten bir LinkedList ihtiyacım olduğuna karar verirseniz, kodumu ArrayList yöntemlerine çağrı yaptığım 100 yerde değil, sadece yeni Listeyi oluşturduğum bir yerde değiştirmem gerekiyor.

Tabii ki, olabilir ilk bildirisi kullanarak bir ArrayList örneğini ve Liste arayüzünün bir parçası olmayan herhangi yöntemler kullanılarak, ama dürüst tutmak derleyici ikinci bildiriyi yapar kullanmayan kendinizi dizginlemek.


Bu pek "birleştirilmesi" aslında neyi ilgilidir olduğunu . Bazı iyi yanıtlar için stackoverflow.com/questions/39946/coupling-and-cohesion adresine bakın .
Rogério

@ Rogerio: Bence bununla ilgili. Belki diğer "kuplaj" tanımlarıyla karıştırılırsınız ama Gevşek kuplajı okumalısınız . "Bağımlı bir sınıf, gerekli davranışı sağlayan doğrudan bir beton sınıfına bir işaretçi içerdiğinde güçlü bağlanma gerçekleşir ... Gevşek bağlanma, bağımlı sınıf yalnızca bir arabirime bir işaretçi içerdiğinde oluşur; bu, daha sonra bir veya daha fazla somut sınıf tarafından uygulanabilir ." Örneğimde, kodum Liste arayüzü aracılığıyla bir ArrayList'e gevşek bir şekilde bağlanır.
Kertenkele Bill

@Bill: Bağlantı için teşekkürler, ancak bu makale benim için tamamen sahte görünüyor. Görünüşe göre, başka bir alandan (örgütsel davranış) fikirleri yeniden yorumluyor, Larry Constantine tarafından yazılan özgün yazılıma özgü tanımla çelişen "gevşek bağlantı" tanımını veriyor: en.wikipedia.org/wiki/Coupling_(computer_science) .
Rogério

@Rogerio: Constantine'nin makalesi 1974'te yazılmıştır. Son 36 yılda çok fazla yeniden yorumlama yapılması muhtemeldir, ancak Wikipedia makalesinin kaynağı olduğunu düşünmüyorum. Örneğin, Bağımlılık Enjeksiyonu gibi modeller , cevabımda açıkladığım gibi kuplajı gevşetmek için arayüzlere güveniyor.
Kertenkele Bill

2
@Bill: Elbette, Constantine'in Yapısal Tasarım konusundaki çalışmaları eski şeylerdir, ancak geçersiz kılmak veya kökten yeniden yorumlamak için herhangi bir neden göremiyorum. Özgün uyum ve bağlanma kavramları, kalıtım ve çok biçimlilik kadar Nesne Odaklı Tasarımın özünde yer alır. DI (daha iyi bir makale martinfowler.com/articles/injection.html ) yalnızca eklentilerin harici yapılandırması için bir tekniktir (yapılandırma koduyla çalışma zamanında seçilen uygulamalarla soyut arabirimler); bu tür bir başka teknik, Servis Bulucu modelidir. DI ve kuplaj bağımsız kavramlardır.
Rogério

27

Buradaki cevaplar arasındaki farkın derecesi neden kavramanın zor olduğunu, ancak onu tanımlayabildiğim kadar basit bir şekilde ifade etmenin neden zor olduğunu gösteriyor:

Sana bir top atarsam, o zaman onu yakalayabilirsin, gerçekten kaç yaşında olduğunu bilmeme gerek yok. Kahvaltıda ne yediğinizi bilmeme gerek yok ve gerçekten ilk aşkınızın kim olduğu umurumda değil. Bilmem gereken tek şey yakalayabileceğin. Eğer bunu bilersem, o zaman umursamıyorum sana ya da kardeşine bir top atıyorum.

C # veya Java vb. Gibi dinamik olmayan dillerle bunu Arayüzler aracılığıyla başarıyoruz. Diyelim ki aşağıdaki arayüze sahibiz:

public ICatcher
{
   public void Catch();
}

Ve şimdi diyelim ki şu sınıflara sahibiz:

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

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

}

Şimdi hem CatcherA hem de CatcherB, Catch yöntemini uygular, böylece bir Catcher gerektiren hizmet bunlardan herhangi birini kullanabilir ve hangisinin olduğu konusunda bir lanet veremez. Böylece sıkı sıkıya bağlı bir hizmet doğrudan yakalanan bir

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

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

}

Böylece CatchService tam olarak ne yaptığını yapabilir, ancak CatcherA kullanır ve her zaman CatcherA kullanır. Onun sert kodlanmış, bu yüzden birisi gelip refactors kadar orada kalmak.

Şimdi bağımlılık enjeksiyonu adı verilen başka bir seçenek alalım:

public CatchService
{
   private ICatcher catcher;

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

CatchService'i oluşturan calss aşağıdakileri yapabilir:

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

veya

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

Bu, Catch hizmetinin CatcherA veya CatcherB ile sıkı sıkıya bağlı olmadığı anlamına gelir.

Bunun gibi gevşek bağlantı hizmetleri için bir IoC çerçevesinin kullanımı gibi başka sıkıntılar da vardır.


1
Bu örneği diğerlerinden daha çok seviyorum, çünkü bu tür şeyler iş dünyasında günlük olarak oluyor. Class Person koşarsa, Class Cat koşar, Class Dog koşar, vb. Çalışan tüm bu sınıfları detaylandırmak için çok büyük bir program olurdu. Ancak, her sınıfın aynı şeyi yaptığı koşular adlı bir arabirim kullanmak, programınızı daha esnek ve yönetilebilir hale getirir. :)
sksallaj

Gerçekten iyi açıklanmış efendim, sadece son örnekte bağımlılık enjeksiyonu ile yaptığınızı temizlemek için ve ilk örnek de gevşek bir şekilde birleştirildi?
Ali Sajid

Vay, eski cevap yorumladı :). Yani cevap hayır, ilk örnek CatcherA'ya sert bir bağımlılığa sahip, bu yüzden güçlü bir şekilde birleşiyorlar
Owen

23

(Sıkı veya gevşek) bağlamayı, kelimenin tam anlamıyla, belirli bir sınıfı başka bir sınıfa bağımlı olmaktan ayırmanız için gereken çaba miktarı olarak düşünebilirsiniz. Örneğin, sınıfınızdaki her yöntemin sonunda bir şey günlüğe kaydetmek için Log4Net'e çağrı yaptığınız yerde sonunda biraz blok varsa, sınıfınızın Log4Net'e sıkıca bağlandığını söyleyebilirsiniz. Sınıfınız bunun yerine Log4Net bileşeni olarak adlandırılan tek yer olan LogSomething adında özel bir yöntem içeriyorsa (ve bunun yerine LogSomething olarak adlandırılan diğer yöntemler), sınıfınızın Log4Net'e gevşek bir şekilde bağlandığını söyleyebilirsiniz (çok fazla zaman almaz çünkü Log4Net'i dışarı çıkarma ve başka bir şeyle değiştirme çabası).


1
Peki, "gevşek bağlanmış" aslında daha az bağımlılık anlamına mı geliyor? Doğrumuyum?
user314362

4
Bu, belirli bir sınıfın sahip olduğu toplam bağımlılık sayısı ile ilgili değildir. Birleştirme (sıkı veya gevşek) aslında iki sınıf arasındaki ilişkinin bir özelliğidir. Yani 100 başka sınıfa gevşek bağlı bir sınıfa veya sadece 2 sınıfa sıkıca bağlı başka bir sınıfa (örneğin) sahip olabilirsiniz.
MusiGenesis

2
Kötü örnek, söyleyebilirim: ne var kod çoğaltma, sıkı bağlantı değil. Ve iyi bir yeniden düzenleme aracıyla, bu çoğaltma saniyeler içinde ortadan kaldırılabilir.
Rogério

@Rogerio: muhtemelen en iyi örnek değil. 64BitBobCevabını daha iyi seviyorum kendim.
MusiGenesis

12

Tanım

Temel olarak, birleştirme, belirli bir nesnenin veya bir nesne kümesinin görevini yerine getirmek için başka bir nesneye veya başka bir nesne kümesine ne kadar bağlı olduğudur.

Yüksek Kavrama

Bir araba düşünün. Motorun çalışabilmesi için, ateşleme içine bir anahtar sokulmalı, çevrilmeli, benzin bulunmalı, kıvılcım oluşmalı, pistonlar ateşlenmeli ve motor canlandırılmalıdır. Bir araba motorunun diğer birkaç nesneye oldukça bağlı olduğunu söyleyebilirsiniz. Bu yüksek bir bağlantı, ama gerçekten kötü bir şey değil.

Gevşek Kavrama

Kullanıcıların bir tür bilgi yayınlamasına, düzenlemesine ve görüntülemesine izin veren bir web sayfası için kullanıcı kontrolünü düşünün. Tek kontrol, kullanıcının yeni bir bilgi parçası göndermesine veya yeni bir bilgi parçasını düzenlemesine izin vermek için kullanılabilir. Denetim, iki farklı yol arasında paylaşılabilmelidir - yeni ve düzenleme. Denetim, onu içerecek sayfalardan bazı veri türlerine ihtiyaç duyacak şekilde yazılırsa, bunun çok fazla bağlı olduğunu söyleyebilirsiniz. Kontrolün kapsayıcı sayfasından herhangi bir şeye ihtiyacı olmamalıdır.


7

Oldukça genel bir kavram, bu yüzden kod örnekleri tüm resmi vermeyecek.

Buradaki bir adam bana dedi ki, "desenler fraktallar gibidir, gerçekten yakınlaştırdığınızda ve mimari seviyeye çıktığınızda onları görebilirsiniz."

Kısa wikipedia sayfasını okumak size bu genelliğe dair bir fikir verebilir:

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

Belirli bir kod örneği kadar ...

İşte Microsoft.Practices.CompositeUI öğelerinden son zamanlarda birlikte çalıştığım gevşek bir bağlantı.

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

Bu kod, bu sınıfın CustomizableGridService öğesine bağımlı olduğunu bildiriyor. Hizmetin doğrudan uygulanmasına doğrudan başvurmak yerine, o hizmetin BAZI uygulanmasını gerektirdiğini belirtir. Sonra çalışma zamanında, sistem bu bağımlılığı giderir.

Bu net değilse, daha ayrıntılı bir açıklamayı buradan okuyabilirsiniz:

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

ABCCustomizableGridService'in buraya bağlamayı düşündüğüm imlpementation olduğunu düşünün.

Bunu seçersem, bunu dışarı çekebilir ve XYZCustomizableGridService veya StubCustomizableGridService ile bu bağımlılık ile sınıfa hiçbir değişiklik yapmadan değiştirebilirim.

ABCCustomizableGridService'e doğrudan başvurmuş olsaydım, başka bir hizmet uygulamasında takas için bu / bu referanslarda değişiklik yapmam gerekirdi.


6

Kuplaj, kod modülleri (fonksiyonlar, dosyalar veya sınıflar), bir ardışık düzendeki araçlar, sunucu-istemci işlemleri vb. Olabilen sistemler arasındaki bağımlılıklarla ilgilidir. Bağımlılıklar ne kadar az olursa, o kadar "sıkı sıkıya bağlı" hale gelirler, çünkü bir sistemi değiştirmek, ona bağlı olan diğer sistemleri değiştirmeyi gerektirir. İdeal durum, bir sistemin değiştirilebileceği ve ona bağlı olan sistemlerin değiştirilmeden çalışmaya devam edeceği "gevşek bağlantıdır".

Gevşek kuplaj elde etmenin genel yolu, iyi tanımlanmış arabirimlerdir. İki sistem arasındaki etkileşim iyi tanımlanmışsa ve her iki tarafa da bağlıysa, sözleşmelerin bozulmamasını sağlarken bir sistemi değiştirmek daha kolay hale gelir. Pratikte, iyi tanımlanmış bir arayüzün kurulmadığı, özensiz bir tasarıma ve sıkı bağlantıya neden olur.

Bazı örnekler:

  • Uygulama bir kütüphaneye bağlıdır. Sıkı bağlantı altında, uygulama lib'in yeni sürümlerini kırıyor. "DLL Hell" için Google.

  • İstemci uygulaması bir sunucudan veri okur. Sıkı bağlantı altında, sunucuda yapılan değişiklikler istemci tarafında düzeltmeler gerektirir.

  • İki sınıf Nesneye Dayalı bir hiyerarşide etkileşime girer. Sıkı bağlantı altında, bir sınıftaki değişiklikler diğer sınıfın eşleşmesi için güncellenmesini gerektirir.

  • Birden çok komut satırı aracı bir kanalda iletişim kurar. Sıkıca bağlanmışlarsa, bir komut satırı aracının sürümünde yapılan değişiklikler, çıktısını okuyan araçlarda hatalara neden olur.


5

Birleştirme, farklı sınıfların birbirine ne kadar sıkı bağlandığını ifade eder. Sıkı birleştirilmiş sınıflar çok sayıda etkileşim ve bağımlılık içerir.

Gevşek bağlanmış sınıflar, birbirlerine olan bağımlılıklarının minimumda tutulması ve bunun yerine birbirlerinin iyi tanımlanmış kamusal arayüzlerine güvenmesinin tersidir.

Legos, birlikte SNAP oyuncakları gevşek bağlı olarak kabul edilir, çünkü parçaları birleştirebilir ve istediğiniz sistemi kurabilirsiniz. Ancak, bir yapbozun sıkıca birleştirilen parçaları vardır. Bir bilmecenin (sistem) bir parçasını alıp farklı bir bulmacanın içine yapıştıramazsınız, çünkü sistem (bulmacanın) söz konusu “tasarıma” özgü özel olarak yapılmış çok özel parçalara bağımlıdır. Legolar daha genel bir tarzda inşa edilmiştir, böylece Lego Evinizde veya Lego Uzaylı Adamımda kullanılabilirler.

Referans: https://megocode3.wordpress.com/2008/02/14/coupling-and-cohesion/


4

İki bileşen, birbirlerinin somut uygulamalarına bağlı olduklarında yüksek oranda birleştirilir.

Sınıfımda bir yöntemde bir yere bu kodu olduğunu varsayalım:

this.some_object = new SomeObject();

Şimdi benim sınıf SomeObject'e bağlı, ve yüksek oranda birbirine bağlılar. Öte yandan, bir yöntem InjectSomeObject olduğunu varsayalım:

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

O zaman ilk örnek sadece enjekte edilmiş SomeObject kullanabilir. Bu test sırasında kullanışlıdır. Normal çalışma ile, hafif, sahte bir uygulamadan geçen testler için ağır, veritabanı kullanan, ağ kullanan sınıflar vb. Kullanabilirsiniz. Sıkı birleştirilmiş kod ile bunu yapamazsınız.

Bağımlılık enjeksiyon kapları kullanarak bu işin bazı kısımlarını daha kolay hale getirebilirsiniz. DI hakkında Wikipedia hakkında daha fazla bilgi bulabilirsiniz: http://en.wikipedia.org/wiki/Dependency_injection .

Bazen bunu çok ileri götürmek kolaydır. Bir noktada işleri somut hale getirmeniz gerekir, aksi takdirde programınız daha az okunabilir ve anlaşılır olacaktır. Bu yüzden bu teknikleri esas olarak bileşen sınırlarında kullanın ve ne yaptığınızı bilin. Gevşek kuplajdan faydalandığınızdan emin olun. Değilse, muhtemelen bu yere ihtiyacınız yoktur. DI programınızı daha karmaşık hale getirebilir. İyi bir ödün verdiğinizden emin olun. Başka bir deyişle, iyi dengeyi koruyun. Sistem tasarlarken her zaman olduğu gibi. İyi şanslar!


3

FormA ve FormB içeren bir Windows uygulaması düşünün. FormA birincil formdur ve FormB görüntüler. FormB'nin verileri üst öğesine geri aktarması gerektiğini düşünün.

Bunu yaptıysanız:

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

    ...
    fb.Show();
}

class FormB 
{
    FormA parent;

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

FormB, FormA'ya sıkıca bağlıdır. FormB, FormA türünden başka bir üst öğeye sahip olamaz.

Öte yandan, FormB bir olay yayımladıysanız ve FormA bu etkinliğe abone olduysa, FormB o olaydaki verileri o olaydaki aboneye geri gönderebilir. Bu durumda, FormB, ailesiyle konuştuğunu bile bilmiyor; etkinlik gevşek bağlantı üzerinden sadece abonelerle konuşmasını sağlar. Herhangi bir tür artık FormA'nın üst öğesi olabilir.

rp


3

Bilgisayar biliminde başka kimsenin buraya göndermediği "gevşek bağlantı" için başka bir anlam daha vardır, bu yüzden ... İşte gidiyor - umarım bana oylar vereceksin, böylece bu yığının altında kaybolmaz! Elbette cevabımın konusu şu soruya kapsamlı bir cevapta yer alıyor ...

"Gevşek Bağlama" terimi ilk olarak hesaplamaya çoklu CPU yapılandırmasında CPU mimarisi ile ilgili sıfat olarak kullanılan bir terim olarak girdi. Karşı tarafı "sıkı bağlantı" dır. Gevşek Kuplaj, CPU'ların birçok kaynağı ortak paylaşmadığı ve Sıkı Kuplaj ise ortak olduğu zamandır.

"Sistem" terimi burada kafa karıştırıcı olabilir, bu yüzden lütfen durumu dikkatlice ayrıştırın.

Genellikle, ancak her zaman olmasa da, bir sistem içinde var oldukları bir donanım konfigürasyonundaki birden fazla CPU (ayrı "PC" kutularında olduğu gibi) sıkıca bağlanır. Ana belleği gerçekte "sistemler" arasında paylaşan alt sistemlere sahip bazı süper yüksek performanslı sistemler hariç, tüm bölünebilir sistemler gevşek bir şekilde birleştirilir.

Sıkı Bağlantılı ve Gevşek Bağlantılı terimler, çok iş parçacıklı ve çok çekirdekli CPU'lar icat edilmeden önce tanıtıldı , bu nedenle bu terimler bugün durumu tam olarak ifade etmek için bazı arkadaşlara ihtiyaç duyabilir. Ve gerçekten de, günümüzde bir insanın her iki türü tek bir genel sistemde kapsayan bir sistemi olabilir. Mevcut yazılım sistemleri ile ilgili olarak, her çeşitten biri olan ve bunların ortak olması gereken iki ortak mimari vardır.

İlk olarak, sorunun konusu olduğu için, Gevşek Bağlı sistemlerin bazı örnekleri:

  • VaxClusters
  • Linux Kümeleri

Buna karşılık, Sıkıca Bağlı Bazı örnekler:

  • Semetrical-Multi-Processing (SMP) İşletim sistemleri - örneğin Fedora 9
  • Çok iş parçacıklı CPU'lar
  • Çok Çekirdekli İşlemciler

Günümüzün hesaplamalarında, her ikisinin de tek bir genel sistemde çalışmasının örnekleri nadir değildir. Örneğin, Fedora 9'u çalıştıran modern Pentium çift veya dört çekirdekli CPU'ları alın - bunlar sıkıca bağlı bilgi işlem sistemleridir. Daha sonra, birçoğunu gevşek bir şekilde bağlanmış bir Linux Kümesi'nde birleştirin ve şimdi hem gevşek hem de sıkıca bağlı bilgi işlem devam ediyor! Oh, modern donanım harika değil!


3

Basit bir dilde, gevşek bir şekilde bağlı olması, gerçekleşecek başka bir olaya bağlı olmadığı anlamına gelir. Bağımsız olarak çalışır.


1
Bu gerçekten doğru değil - diğer örneklerde belirtildiği gibi, varlıklar (modüller, sınıflar) arasında bir ilişki olup olmadığı değil, aynı işlevselliği uygulayan diğer sınıflar için kolayca değiştirilip değiştirilemeyecekleri hakkında çok fazla şey var. Örneğin, bir ViewModel farklı modellerle çalışabilir, ancak kesinlikle bir tane olmadan çalışmaz
Hayden Crocker

Çok yararlı değil
brgs

2

Burada uzun cevaplar var. Prensip çok basit. Wikipedia'dan açılış konuşmasını sunuyorum :

Msgstr "Gevşek bağlantı, iki veya daha fazla sistem veya kuruluş arasında bir tür değişim ilişkisi olan esnek bir ilişkiyi tanımlar.

İşlemin her iki ucu da gereksinimlerini açıkça ortaya koyar ve diğer ucu hakkında az sayıda varsayım yapar. "


1
Bu kadar basit olsaydı, bu tartışmayı yapmazdık.
brgs

2

Çok basit bir Kod Birleştirme Testi öneriyorum :

  1. B Parçasında, doğruluğu korumak için A Parçasındaki değişiklikleri zorlayacak olası bir değişiklik varsa, kod A parçasının kod B parçasına sıkıca bağlanması.

  2. B Parçasında, A Parçasında değişiklik yapacak olası bir değişiklik yoksa, kod A parçasının kod B parçasına sıkıca bağlanmamış olması.

Bu, kodunuzun parçaları arasında ne kadar bağlantı olduğunu doğrulamanıza yardımcı olacaktır. bunun için akıl yürütme için bu blog gönderisine bakın: http://marekdec.wordpress.com/2012/11/14/loose-coupling-tight-coupling-decoupling-what-is-that-all-about/


2

Kullanarak bir sınıfın nesnesini oluşturduğunuzda new anahtar kelime , aslında sıkı bağlantı (kötü uygulama) yapıyorsunuz, bunun yerine iyi bir uygulama olan gevşek bağlantı kullanmalısınız.

--- 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();
}

---Ana sınıf---

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 

}
}

Açıklama:

Yukarıdaki örnekte, iki A ve B sınıfımız var

Sınıf B, Interface yani InterfaceClass uygular.

InterfaceClass, B sınıfı için bir Sözleşme tanımlar çünkü InterfaceClass, B sınıfı gibi başka herhangi bir sınıf tarafından erişilebilen soyut yöntemlere sahiptir.

A Sınıfında, InterfaceClass uygulayan sınıf nesnesi dışında (bizim durumumuzda B sınıfıdır) görüntüleme yöntemine sahibiz. Ve bu A sınıfı nesne yöntemi B sınıfının display () ve getVar () yöntemlerini çağırıyor

MainClass'ta A ve B Sınıflarının nesnesini yarattık ve B sınıfının nesnesini yani objb'yi geçirerek A'nın görüntüleme yöntemini çağırarak. A görüntüleme yöntemi B sınıfı nesnelerle çağrılır.

Şimdi gevşek bağlantıdan bahsediyoruz. Gelecekte, Sınıf B'nin adını ABC'ye değiştirmeniz gerektiğini varsayalım, o zaman sınıf B'nin görüntüleme yönteminde adını değiştirmek zorunda değilsiniz, sadece yeni (ABC sınıfı) nesnesini yapın ve MailClass'ta görüntüleme yöntemine iletin. A Sınıfı'nda hiçbir şeyi değiştirmek zorunda değilsiniz

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


0

"Gevşek bağlantı" genel konsepti hakkında daha fazla bilgi edinebilirsiniz .

Kısacası, her sınıf diğeri hakkında en azını bilen iki sınıf arasındaki ilişkinin bir açıklamasıdır ve her sınıf, diğerinin mevcut olup olmadığına bakılmaksızın ve diğerinin özel uygulamasına bağımlı olmadan potansiyel olarak iyi çalışmaya devam edebilir. sınıf.


-8

Gevşek bağlantı, genel olarak, aynı iş yükü üzerinde birbirinden bağımsız çalışan 2 aktördür. Aynı arka uç veritabanını kullanan 2 web sunucunuz varsa, bu web sunucularının gevşek bir şekilde bağlandığını söyleyebilirsiniz. Sıkı bağlantı, bir web sunucusunda 2 işlemcinin olmasıyla örneklendirilir ... bu işlemciler sıkıca bağlanır.

Umarım bu biraz yardımcı olur.


1
Ne istediğini görüyorum, ama yine de sıkı bir şekilde birleştiğini açıklamanın çok iyi bir yolu değil, iki 'şey' birbirinden bağımsız olduğunda, iki 'şey' bağımsız olarak var olduğunda - bir 'şey' nerede olabilir? 'şey' de değişiklik yapılmadan değiştirilecek ...
Bryan Rehbein

Steve, sen TAM haklısın - herhangi bir aşağı oyu hak etmedin. Sadece kitleniz terminolojinize hazır değildi ve bu sitedeki çok fazla kişinin anlamadıklarını veya bilmediklerini oylama alışkanlığı var. -shrug-
Richard T

Bence Steve bu noktayı kaçırdı. Gevşek bağlantı her zaman aynı işyükünde bağımsız çalışan 2 aktör anlamına gelmez.
Rob
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.