Proxy ve Dekoratör Kalıbı arasındaki farklar


136

Vekil ve Dekoratör arasındaki farkın ne olduğunu iyi bir açıklama yapabilir misiniz ?

Gördüğüm temel fark biz varsayıyorum zaman olacağı Vekil kullandığı kompozisyon ve Dekoratör kullandığı agregasyon da o birden (bir veya daha fazla) kullanarak o zaman net görünüyor dekoratörler oysa değiştirmek / örneği (Dekorasyonumu) önceden var işlevleri ekleyebilirsiniz vekil vekalet sınıf ve bazı ek özellikleri (vekil davranış) ekleyerek kendisine delegelerin kendi içsel örneği vardır.

Soru - mu Vekil toplama hala ile oluşturulan Vekil doğrusu ya Dekoratör ? Toplama ile Proxy oluşturmaya (GoF modellerinde tanım gereği) izin veriliyor mu?


2
Bazı bağlantılar: Vekil ve Dekoratör
Sotirios Delimanolis

5
Proxy'nin kompozisyon ve Dekoratör'ün toplamayı kullandığı fikrini nereden edindiniz?
CPerkins

1
@CPerkins, Rahul Tripathi cevabına ilişkin yorumuma bakın.
Łukasz Rzeszotarski

1
Ve ayrıca dekoratör ( patterns.cs.up.ac.za/examples/ch2/decorator-theory.cs ) - açıkça toplama, proxy ( patterns.cs.up.ac.za/examples/ch2/proxy-theory.cs ) - belli ki kompozisyon.
hyankov

Yanıtlar:


18

İşte GoF'den doğrudan alıntı (sayfa 216).

Dekoratörler vekil olarak benzer uygulamalara sahip olsalar da, dekoratörlerin farklı bir amacı vardır. Bir dekoratör, bir nesneye bir veya daha fazla sorumluluk ekler, oysa bir vekil bir nesneye erişimi kontrol eder.

Proxy'ler, bir dekoratör gibi uygulanma derecelerine göre değişir. Koruma vekili tam olarak bir dekoratör gibi uygulanabilir. Öte yandan, uzak bir proxy, gerçek konusuna doğrudan bir referans içermez, yalnızca "ana bilgisayar kimliği ve ana bilgisayardaki yerel adres" gibi dolaylı bir referans içerir. Bir sanal proxy, bir dosya adı gibi dolaylı bir referansla başlayacak, ancak sonunda doğrudan bir referans alacak ve kullanacaktır.

Popüler yanıtlar, bir Vekilin, temsilcisinin somut türünü bildiğini gösterir. Bu alıntıdan bunun her zaman doğru olmadığını görebiliriz.

GoF'ye göre Proxy ve Dekoratör arasındaki fark, Proxy'nin istemciyi kısıtlamasıdır . Dekoratör yapmaz. Vekil bir istemci neyi kısıtlayabilir yapar işlevselliğine erişim kontrol ederek; veya müşteri tarafından görünmeyen ve bilinmeyen eylemler gerçekleştirerek müşterinin bildiklerini kısıtlayabilir . Dekoratör tam tersini yapar: Temsilcinin yaptıklarını müşteriler tarafından görülebilecek şekilde geliştirir.

Proxy'nin kara kutu, Dekoratörün beyaz kutu olduğunu söyleyebiliriz.

Sarmalayıcı ve temsilci arasındaki kompozisyon ilişkisi, Proxy'yi Dekoratör ile karşılaştırırken odaklanılması gereken yanlış ilişkidir, çünkü kompozisyon bu iki modelin ortak özelliğidir. Sarmalayıcı ve müşteri arasındaki ilişki, bu iki modeli birbirinden ayıran şeydir.

  • Dekoratör müşterisini bilgilendirir ve güçlendirir.
  • Proxy, istemcisini kısıtlar ve yetkisini kaldırır.

114

Gerçek fark sahiplik (birleştirme ve birleştirme) değil, daha çok tür bilgisidir.

Bir Dekoratör her zaman temsilcisinden geçer. Bir Vekil olabilir Bunu bizzat yaratmak, ya da o olabilir o enjekte var.

Ancak bir Vekil her zaman (daha fazla) belirli temsilci türünü bilir. Başka bir deyişle, Vekil ve temsilcisi aynı temel türe sahip olacaktır, ancak Vekil türetilmiş bir türü işaret etmektedir. Bir Dekoratör , kendi temel türünü işaret eder. Bu nedenle, fark, temsilcinin türü hakkındaki derleme zamanı bilgilerindedir.

Dinamik bir dilde, delege enjekte edilirse ve aynı arayüze sahip olursa, o zaman bir fark yoktur.

Sorunuzun cevabı evet".


2
"Ancak bir Vekil her zaman (daha) belirli temsilci türünü bilir." Bunun doğru olduğunu sanmıyorum. Uzak vekil sunucu hayal edin. Proxy mekanizmasının uzak nesnenin herhangi bir özelliğini bilmesine gerek yoktur. Uzak sistem, nesneyi belirtilen arabirimle kaydeder. Ve yerel proxy aynı arayüzü ortaya çıkarır.
Alexey

3
Bu konuyla ilgili bir dersi Amazon'da, işini bilen bir misafir hocadan aldım. Bir "proxy" yürütülebilir dosyasının (örneğin bir web hizmetiyle) kullanımı ile Proxy Tasarım Modeli arasında bir fark vardır. Proxy modelinin ve Dekoratör modelinin UML'leri farklı olabilir. Ancak hiçbir şey bir Proxy'nin temsilcisiyle aynı API'ye sahip olmasını engellemez. Dekoratör, Proxy'nin katı bir alt kümesidir, ancak bir Dekoratör, temel API'nin aynı olmasının garanti edilip edilmediğine bağlı olarak yine bir Proxy olarak adlandırılabilir .
cdunn2001

85

Dekoratör Deseni, bir nesneye dinamik olarak işlevler eklemeye odaklanırken, Vekil Desen bir nesneye erişimi kontrol etmeye odaklanır.

DÜZENLE:-

Bir Proxy ile gerçek özne arasındaki ilişki tipik olarak derleme zamanında ayarlanır, Proxy bunu bir şekilde başlatır, oysa Dekoratör , yalnızca öznenin arayüzünü bilerek çalışma zamanında özneye atanır.


5
Yine de işlevsellik eklemek için bir Proxy kullanılabilir. AOP vekillerini düşünün.
Sotirios Delimanolis

5
Tamamen katılıyorum efendim. Başka bir deyişle, Proxy Pattern ile kastettiğim şeyi, proxy sınıfının bir nesnenin detay bilgilerini istemcisinden gizleyebileceğini dönüştürürdüm. Bu nedenle, Proxy Pattern'i kullanırken, genellikle proxy sınıfı içinde bir abject örneği oluştururuz. Ve Dekoratör Kalıbı kullanırken, genellikle orijinal nesneyi bir parametre olarak dekoratörün kurucusuna iletiriz.
Rahul Tripathi

Bu durumda, örnek proxy'de 'gizli' olduğunda, fark benim için açıktır (yazdığım gibi), ancak insanların genellikle yapıcı parametre olarak iletilen proxy nesnesini alan proxy sınıfları olarak çağırdığını düşünüyorum. Bu durumda yeni işlevsellik eklemenin veya kontrol etmenin farkı benim için (çok) zayıf.
Łukasz Rzeszotarski

5
Bir Proxy ile gerçek özne arasındaki ilişki tipik olarak derleme zamanında ayarlanır, Proxy bunu bir şekilde başlatır, oysa Dekoratör veya Bağdaştırıcı, yalnızca öznenin arayüzünü bilerek çalışma zamanında özneye atanır. Umarım bu mantıklıdır !!! :)
Rahul Tripathi

1
Cevabınıza bu satırı ekleyebilir misiniz?
Łukasz Rzeszotarski

49

Dekoratör , dekore edilmiş nesne için referans alır (genellikle kurucu aracılığıyla), vekil ise bunu kendi başına yapmaktan sorumludur.

Proxy , sarmalama nesnesini hiç başlatmayabilir (bunun gibi, nesne alanları / alıcılar kullanılmıyorsa DB'ye gereksiz erişimi önlemek için ORM'ler yapar), Dekoratör her zaman gerçek sarmalanmış örneğe bağlantıyı tutar.

Proxy genellikle çerçeveler tarafından güvenlik veya önbelleğe alma / tembellik eklemek için kullanılır ve çerçeve tarafından oluşturulur (normal geliştiricinin kendisi tarafından değil).

Dekoratör, genellikle geliştiricinin kendisi tarafından gerçek sınıf yerine arabirime dayalı olarak eski veya eski sınıflara yeni davranışlar eklemek için kullanılır (bu nedenle, çok çeşitli arabirim örneklerinde çalışır, Proxy somut sınıftır).


22

Temel farklılıklar:

  1. Proxy aynı arayüzü sağlar. Dekoratör , gelişmiş bir arayüz sağlar.
  2. Dekoratör ve Vekil farklı amaçlara sahiptir ancak benzer yapıları vardır. Her ikisi de başka bir nesneye bir dolaylılık düzeyinin nasıl sağlanacağını açıklar ve uygulamalar, istekleri ilettikleri nesneye bir referans tutar.
  3. Dekoratör , yalnızca tek bileşenli dejenere bir Kompozit olarak görülebilir. Ancak, bir Dekoratör ek sorumluluklar ekler - bu nesne birleştirme için tasarlanmamıştır.
  4. Dekoratör yinelemeli kompozisyonu destekler
  5. Dekoratörü sınıfı, bir ilan bileşim LCD (düşük sınıf paydası) arabirimine ilişkisi ve bu veri elemanı Oluşturucu başlatılır.
  6. Geç başlatma, nesneyi önbelleğe alarak ve istemciye / arayan kişiye erişimi kontrol ederek performans iyileştirme için Proxy kullanın

Kaynak oluşturma makalesi, benzerlikleri ve farklılıkları mükemmel bir şekilde aktarıyor.

İlgili SE soruları / bağlantıları:

Dekoratör Kalıbı Ne Zaman Kullanılır?

Bağdaştırıcı ve Proxy kalıpları arasındaki tam fark nedir?


3

Vekil ve Dekoratör amaç ve iç uygulamaya odaklandıkları yerde farklılık gösterir. Proxy, uzak, çapraz işlem veya ağlar arası bir nesneyi yerel bir nesne gibi kullanmak içindir. Dekoratör, orijinal arayüze yeni davranışlar eklemek içindir.

Her iki model de yapısal olarak benzer olsa da, Proxy'nin karmaşıklığının büyük kısmı, kaynak nesneyle doğru iletişimin sağlanmasında yatmaktadır. Dekoratör ise eklenen davranışın uygulanmasına odaklanır.


Zaten burada bulunan diğer 4 cevaptan farklı olan ne diyorsunuz?
Stephen Rauch

Hepsi orada mı bilmiyorum. Sadece önceki cevapları okuduktan sonra zil sesi gelme isteği hissettim.
James Lin

1

Anlamaya biraz zaman aldı bu cevabı ve gerçekten ne o anlamına gelir. Birkaç örnek bunu daha açık hale getirmelidir.

Proxy ilk:

public interface Authorization {
    String getToken();
} 

Ve :

// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
    @Override
    public String getToken() {
        return "DB-Token";
    }
}

Ve bunu arayan biri var, Authorizationoldukça aptal biri:

class Caller {
    void authenticatedUserAction(Authorization authorization) {
        System.out.println("doing some action with : " + authorization.getToken());
    }
}

Şimdiye kadar alışılmadık bir şey yok, değil mi? Belirli bir hizmetten jeton alın, bu jetonu kullanın. Şimdi resme bir gereksinim daha geliyor, günlük kaydı ekleyin: yani her seferinde jetonu günlüğe kaydedin. Bu durum için çok basit, sadece bir tane oluşturun Proxy:

public class LoggingDBAuthorization implements Authorization {

    private final DBAuthorization dbAuthorization = new DBAuthorization();

    @Override
    public String getToken() {
        String token = dbAuthorization.getToken();
        System.out.println("Got token : " + token);
        return token;
    }
}

Bunu nasıl kullanacağız?

public static void main(String[] args) {
    LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();

    Caller caller = new Caller();
    caller.authenticatedUserAction(loggingDBAuthorization);
}

Bir örneğini LoggingDBAuthorization tutan dikkat edin DBAuthorization. Hem LoggingDBAuthorizationve DBAuthorization uygulayın Authorization .

  • Bir proxy DBAuthorization, temel arayüzün ( Authorization) somut bir uygulamasını ( ) tutacaktır . Diğer bir deyişle, bir Vekil tam olarak neye vekalet edildiğini bilir .

Decorator:

Hemen hemen aynı Proxyarayüzle başlar:

public interface JobSeeker {
    int interviewScore();
}

ve bunun bir uygulaması:

class Newbie implements JobSeeker  {
    @Override
    public int interviewScore() {
        return 10;
    }
}

Ve şimdi daha tecrübeli bir aday eklemek istiyoruz, bu da mülakat puanının yanı sıra diğerinden birini ekliyor JobSeeker:

@RequiredArgsConstructor 
public class TwoYearsInTheIndustry implements JobSeeker {

    private final JobSeeker jobSeeker;

    @Override
    public int interviewScore() {
        return jobSeeker.interviewScore() + 20;
    } 
}

Buna ek olarak başka bir JobSeeker'dan gelen söylediğime dikkat edin , değil Newbie . Bir Decoratorbilmiyor tam olarak (bu bilmektedir o süslü örneğinin sadece sözleşme bilir, dekorasyon ne JobSeeker). Burada bunun a'dan farklı olduğuna dikkat edin Proxy; bunun aksine, tam olarak neyi süslediğini biliyor.

Bu durumda iki tasarım modeli arasında gerçekten bir fark olup olmadığını sorgulayabilirsiniz. DecoratorBir olarak yazmaya çalışırsak ne olur Proxy?

public class TwoYearsInTheIndustry implements JobSeeker {

    private final Newbie newbie = new Newbie();

    @Override
    public int interviewScore() {
        return newbie.interviewScore() + 20;
    }
}

Bu kesinlikle bir seçenektir ve bu modellerin ne kadar yakın olduğunu vurgular; diğer cevaplarda açıklandığı gibi hala farklı senaryolar için tasarlanmıştır.


1

Proxy , sarılmış nesneye aynı arabirimi sağlar , Dekoratör ona gelişmiş bir arabirim sağlar ve Proxy genellikle hizmet nesnesinin yaşam döngüsünü kendi başına yönetirken, Dekoratörlerin bileşimi her zaman müşteri tarafından kontrol edilir.

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.