Köprü modeli ve Adaptör modeli arasındaki fark


126

Köprü ve Adaptör modelleri arasındaki fark nedir?


Belki birini veya diğerini kullanmanız gerektiğine inandığınız tartışmaya rehberlik etmesi için bir açıklama düzenlemesi yapmayı düşünün.
Jeff Wilcox


Yanıtlar:


173

"Adaptör, tasarlandıktan sonra işlerin çalışmasını sağlar; Bridge, bunların daha önce çalışmasını sağlar. [GoF, p219]"

Etkili bir şekilde, Bağdaştırıcı modeli, üçüncü taraf veya şirket içi kodunuz olduğunda, ancak kontrolünüz dışında olduğunda veya ihtiyaç duyduğunuz arayüzü tam olarak karşılayacak şekilde değiştirilemediğinde kullanışlıdır. Örneğin, çok sayıda kıyamet günü cihazını kontrol edebilen bir SuperWeaponsArray ürünümüz var.

public class SuperWeaponsArray {
  /*...*/

  public void destroyWorld() {
    for (Weapon w : armedWeapons) {
      w.fire();
    }
  }
}

Harika. Cephaneliğimizde Silah arayüzüne dönüşümden büyük ölçüde önce gelen bir nükleer cihaz olduğunun farkında olmamız dışında. Ama burada çalışmasını gerçekten çok isteriz ... öyleyse ne yapacağız ... onu sıkıştıralım!

NukeWeaponsAdaptor - Nuke sınıfımıza dayanır, ancak Silah arayüzünü dışa aktarır. Tatlı, artık dünyayı kesinlikle yok edebiliriz. Biraz küfür gibi görünüyor, ancak işlerin yürümesini sağlıyor.


Köprü desen ön yukarı uygulamak şeydir - Eğer iki ortogonal hiyerarşileri var biliyorsanız, bu arayüz ve sınıfları bir deli numarası almak kalmamasıdır şekilde uygulanmasını ayrıştırmak için bir yol sağlar. Diyelim ki sahipsin:

MemoryMappedFile ve DirectReadFile dosya nesneleri türleri. Diyelim ki çeşitli kaynaklardan dosyaları okuyabilmek istiyorsunuz (Belki Linux'a karşı Windows uygulamaları, vb.). Bridge, aşağıdakilerle dolanmaktan kaçınmanıza yardımcı olur:

MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile


9
oy verildiyse, daha soyut bir kod listesi kullanabilir misiniz? örnek çok spesifik ve kafa karıştırıcı.

36
@omouse olumlu oy verildi, örnek kod gerçekten bu yanıtı noktaya getiren şey değil. Dikkatli okuyucu için yani sonuçta, desenleri ayırt başlamak için yeterli işaretçileri var - bu olduğunu iyi bir cevap.
Victor Farazdagi

15
Köprü modeli için gerçek bir kod örneği verebilir misiniz?
Jaime Hablutzel

2
Pek çok insanın bu soruya benim yaptığım gibi geldiğini hayal ediyorum - muhtemelen zaten iki model için koda bakıyorlardı, ancak bazı benzerlikleri fark ettiler ve iki modeli yan yana getirerek anlayışlarının daha da sağlamlaştırılabileceğini fark ettiler. Windows ve Linux'a özgü dosyalar ile dolanmaktan kaçınmanıza yardımcı olan köprü hakkındaki satır, en azından benim için, Bridge Pattern'in "Uygulayıcısı" nın ( dofactory.com/net/bridge-design-pattern ) bir "Adaptör".
Ürdün

3
"Adaptör, işlerin tasarlandıktan sonra çalışmasını sağlar; Bridge onları daha önce çalıştırır." Okuduğum kitapta hiç belirtilmedi, bu yüzden ikisini ayırt etmek zordu. Sanırım GOF okumak çabaya değer ...
Alexander Derck

15

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

Bağdaştırıcı kalıbı daha çok mevcut kodunuzun daha yeni bir sistem veya arayüzle çalışmasını sağlamakla ilgilidir.

Başka bir uygulamanın mevcut genişletilebilirlik arabirimine sunmak istediğiniz bir dizi şirket standardı web hizmeti API'niz varsa, bunu yapmak için bir dizi bağdaştırıcı yazmayı düşünebilirsiniz. Gri bir alan olduğunu ve cephe gibi diğer desenler benzer olduğu için bu daha çok deseni teknik olarak nasıl tanımladığınızla ilgilidir.

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

Köprü modeli, muhtemelen bir algoritma veya sistemin alternatif uygulamalarına sahip olmanıza izin verecektir.

Klasik bir Bridge modeli örneği olmasa da, birkaç veri deposu uygulamanız olduğunu hayal edin: biri uzayda verimli, diğeri ham performansta verimli ... ve hem uygulamanızda hem de çerçevede sunmak için bir iş durumunuz var .

Sorunuz açısından, "nerede hangi kalıbı kullanabilirim" cevabı, projeniz için neresi mantıklı olursa olsun! Belki birini veya diğerini kullanmanız gerektiğine inandığınız tartışmaya rehberlik etmesi için bir açıklama düzenlemesi yapmayı düşünün.


14

Adaptör:

  1. Yapısal bir modeldir
  2. İki uyumsuz arayüzle çalışmak faydalıdır

UML diyagramı: den dofactory makalesinde:

görüntü açıklamasını buraya girin

Hedef : Müşterinin kullandığı alana özgü arayüzü tanımlar.

Adaptör : Adaptee arayüzünü Hedef arayüze uyarlar.

Adaptee : uyarlanması gereken mevcut bir arayüzü tanımlar.

İstemci : Hedef arayüze uygun nesnelerle işbirliği yapar.

Misal:

Kare ve Dikdörtgen iki farklı şekildir ve her birinin alanını () almak farklı yöntemler gerektirir. Ancak yine de Square, bazı özelliklerin dönüştürülmesiyle Dikdörtgen arayüzünde çalışmaktadır.

public class AdapterDemo{
    public static void main(String args[]){
        SquareArea s = new SquareArea(4);
        System.out.println("Square area :"+s.getArea());
    }
}

class RectangleArea {
    public int getArea(int length, int width){
        return length * width;
    }
}

class SquareArea extends RectangleArea {

    int length;
    public SquareArea(int length){
        this.length = length;
    }
    public int getArea(){
        return getArea(length,length);
    }
}

Köprü:

  1. Yapısal model
  2. bir soyutlamayı uygulamasından ayırır ve her ikisi de bağımsız olarak değişebilir
  3. Mümkündür çünkü miras yerine kompozisyon kullanılmıştır

DÜZENLEME: (@quasoft önerisine göre)

Bu modelde dört bileşeniniz var.

  1. Soyutlama : Bir arayüz tanımlar

  2. RefinedAbstraction : Soyutlamayı uygular:

  3. Uygulayıcı : Uygulama için bir arayüz tanımlar

  4. ConcreteImplementor : Implementor arayüzünü uygular.

Kod pasajı:

Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();

gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();

İlgili gönderi:

Köprü Modelini ne zaman kullanıyorsunuz? Adaptör modelinden farkı nedir?

Temel farklılıklar: kaynak yapımı makalesinden

  1. Adaptör, tasarlandıktan sonra işlerin çalışmasını sağlar; Köprü onları kendilerinden önce çalıştırır.
  2. Bridge, soyutlamanın ve uygulamanın birbirinden bağımsız olarak değişmesine izin vermek için önden tasarlanmıştır. Bağdaştırıcı, ilgisiz sınıfların birlikte çalışması için güçlendirilmiştir.

Yanıta dokümanlardan araba / kamyon / dişli örneğini ekleyin. Harika bir örnek ve benzetme.
quasoft

8

Bu yazı bir süredir ortalıkta. Bununla birlikte, bir cephenin bir adaptöre biraz benzediğini anlamak önemlidir, ancak tamamen aynı şey değildir. Bir bağdaştırıcı, mevcut bir sınıfı genellikle uyumlu olmayan bir istemci sınıfına "uyarlar". Diyelim ki uygulamanızın istemci olarak kullandığı eski bir iş akışı sisteminiz var. Şirketiniz muhtemelen iş akışı sistemini yeni bir "uyumsuz" sistemle (arayüzler açısından) değiştirebilir. Çoğu durumda, bağdaştırıcı desenini kullanabilir ve yeni iş akışı motorunun arabirimlerini gerçekten çağıran kodu yazabilirsiniz. Bir köprü genellikle farklı bir şekilde kullanılır. Aslında farklı dosya sistemleriyle (örn. Yerel disk, NFS, vb.) Çalışması gereken bir sisteminiz varsa, tüm dosya sistemlerinizle çalışmak için köprü modelini kullanabilir ve bir soyutlama katmanı oluşturabilirsiniz. Bu, temelde köprü düzeni için basit bir kullanım durumu olacaktır. Cephe ve adaptör bazı özellikleri paylaşıyor ancakcepheler genellikle mevcut bir arayüzü / sınıfı basitleştirmek için kullanılır . EJB'lerin ilk günlerinde EJB'ler için yerel çağrı yoktu. Geliştiriciler her zaman saplamayı elde etti, daralttı ve onu "sözde uzaktan" olarak adlandırdı. Bu genellikle performans sorunlarına neden oluyordu (özellikle kablo üzerinden gerçekten çağrıldığında). Deneyimli geliştiriciler, müşteriye çok kaba bir arayüz sağlamak için cephe modelini kullanır. Bu cephe, daha sonra, farklı, daha ayrıntılı yöntemlere birden çok çağrı yapacaktı. Sonuç olarak, bu, gerekli yöntem çağrılarının sayısını büyük ölçüde azalttı ve performansı artırdı.


Yine de, görünüşte bu sorunun kapsamı dışında, Facade'e karşı Adapter & Bridge'in ağırlıklandırılması çok uygun olabilir.
Cody

1

Bridge, Adapter geliştirildi. Bridge, adaptör içerir ve buna ek esneklik katar. İşte Ravindra'nın desenler arasındaki yanıt haritasından öğeler:

      Adapter  |    Bridge
    -----------|---------------
    Target     | Abstraction
    -----------|---------------
               | RefinedAbstraction
               |
               |   This element is Bridge specific. If there is a group of 
               |   implementations that share the same logic, the logic can be placed here.
               |   For example, all cars split into two large groups: manual and auto. 
               |   So, there will be two RefinedAbstraction classes.
    -----------|--------------- 
    Adapter    | Implementor
    -----------|---------------
    Adaptee    | ConcreteImplementor

1

En üstteki yanıtta @James, GoF, sayfa 219'dan bir cümle alıntı yapıyor. Bence burada tam açıklamayı yeniden üretmeye değer.

Adaptör ve Köprü

Adaptör ve Köprü modellerinin bazı ortak özellikleri vardır. Her ikisi de başka bir nesneye bir dolaylılık düzeyi sağlayarak esnekliği artırır. Her ikisi de, bu nesneye kendi arabiriminden farklı bir arabirimden istekleri iletmeyi içerir.

Bu kalıplar arasındaki temel fark, amaçlarında yatmaktadır. Adaptör, mevcut iki arayüz arasındaki uyumsuzlukları çözmeye odaklanır. Bu arayüzlerin nasıl uygulandığına odaklanmıyor, bağımsız olarak nasıl gelişebileceklerini de düşünmüyor. Bu, birbirinden bağımsız olarak tasarlanmış iki sınıfın birini veya diğerini yeniden uygulamadan birlikte çalışmasını sağlamanın bir yoludur. Öte yandan Bridge, bir soyutlama ve onun (potansiyel olarak sayısız) uygulamalarını birbirine bağlar. Onu uygulayan sınıfları değiştirmenize izin verdiği için bile istemcilere kararlı bir arayüz sağlar. Ayrıca, sistem geliştikçe yeni uygulamaları da barındırır.

Bu farklılıkların bir sonucu olarak, Adapter ve Bridge genellikle yazılım yaşam döngüsünün farklı noktalarında kullanılır. Genellikle kodun çoğaltılmasını önlemek için iki uyumsuz sınıfın birlikte çalışması gerektiğini keşfettiğinizde bir bağdaştırıcı genellikle gerekli hale gelir. Kuplaj öngörülmemiş. Buna karşılık, bir köprünün kullanıcısı, bir soyutlamanın birkaç uygulamaya sahip olması gerektiğini ve her ikisinin de bağımsız olarak gelişebileceğini önceden anlar. Bağdaştırıcı deseni, tasarlandıktan sonra işlerin çalışmasını sağlar ; Köprü onları kendilerinden önce çalıştırır . Bu, Adapter'ın Bridge'den bir şekilde daha düşük olduğu anlamına gelmez; her model yalnızca farklı bir sorunu ele alır.


0

Bir (genel / soyutlanmış) çizim işlevine sahip soyut bir Shape sınıfınız ve Şekli uygulayan bir Çemberiniz olduğunu varsayalım. Köprü örüntüsü basitçe, uygulamayı (Circle'da çizim) ve genel / soyutlanmış işlevselliği (Shape sınıfında çizim) ayırmak için iki yönlü bir soyutlama yaklaşımıdır.

Gerçekten ne anlama geliyor? İlk bakışta, zaten yaptığınız bir şeye benziyor (bağımlılığı tersine çevirerek). Bu nedenle, daha az düzensiz veya daha modüler bir kod tabanına sahip olmak konusunda endişelenmenize gerek yok. Ama arkasında biraz daha derin bir felsefe var.

Benim anlayışıma göre, mevcut sistemle yakından ilişkili (RedCircle veya GreenCircle gibi) ve yalnızca tek bir işlevle (renk gibi) farklılık gösteren yeni sınıflar eklemem gerektiğinde kullanım modeli ihtiyacı ortaya çıkabilir. Ve özellikle mevcut sistem sınıfları (Daire veya Şekil) sık sık değiştirilecekse ve yeni eklenen sınıfların bu değişikliklerden etkilenmesini istemiyorsanız, Köprü modeline ihtiyacım olacak. Bu nedenle, genel çizim işlevselliği yeni bir arayüze aktarılır, böylece çizim davranışını Shape veya Circle'dan bağımsız olarak değiştirebilirsiniz.

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.