Perbedaan antara Proxy dan Pola Dekorator

136

Bisakah Anda memberikan penjelasan yang baik apa perbedaan antara Proxy dan Dekorator ?

Perbedaan utama yang saya lihat adalah bahwa ketika kita mengasumsikan bahwa Proxy menggunakan komposisi dan Dekorator menggunakan agregasi maka tampaknya menjadi jelas bahwa dengan menggunakan beberapa Dekorator, Anda dapat memodifikasi / menambahkan fungsionalitas ke instance yang sudah ada sebelumnya (menghias), sedangkan Proxy memiliki instance turunan dari kelas proksi dan mendelegasikannya menambahkan beberapa fitur tambahan (perilaku proxy).

Pertanyaannya adalah - Apakah Proxy yang dibuat dengan agregasi masih Proxy atau tepatnya Penghias ? Apakah diizinkan (menurut definisi dalam pola GoF) untuk membuat Proxy dengan agregasi?

Łukasz Rzeszotarski
sumber
2
Beberapa tautan: Proksi dan Dekorator
Sotirios Delimanolis
5
Dari mana Anda mendapatkan gagasan bahwa Proxy menggunakan komposisi dan Dekorator menggunakan agregasi?
CPerkins
1
@CPerkins lihat komentar saya untuk jawaban Rahul Tripathi.
Łukasz Rzeszotarski
1
Dan juga dekorator ( patterns.cs.up.ac.za/examples/ch2/decorator-theory.cs ) - jelas agregasi, proxy ( patterns.cs.up.ac.ac.za/examples/ch2/proxy-theory.cs ) - komposisi jelas.
hyankov

Jawaban:

17

Ini adalah kutipan langsung dari GoF (halaman 216).

Meskipun dekorator dapat memiliki implementasi yang sama dengan proxy, dekorator memiliki tujuan yang berbeda. Dekorator menambahkan satu atau lebih tanggung jawab ke suatu objek, sedangkan proxy mengontrol akses ke objek.

Proxy bervariasi dalam tingkat di mana mereka diimplementasikan seperti dekorator. Proxy perlindungan mungkin diterapkan persis seperti dekorator. Di sisi lain, proxy jarak jauh tidak akan berisi referensi langsung ke subjek sebenarnya tetapi hanya referensi tidak langsung, seperti "ID host dan alamat lokal pada host." Proxy virtual akan memulai dengan referensi tidak langsung seperti nama file tetapi pada akhirnya akan mendapatkan dan menggunakan referensi langsung.

Jawaban populer menunjukkan bahwa Proksi tahu tipe konkret dari delegasinya. Dari kutipan ini kita dapat melihat bahwa itu tidak selalu benar.

Perbedaan antara Proxy dan Dekorator menurut GoF adalah bahwa Proxy membatasi klien. Penghias tidak. Proksi dapat membatasi apa yang dilakukan klien dengan mengontrol akses ke fungsionalitas; atau mungkin membatasi apa yang diketahui klien dengan melakukan tindakan yang tidak terlihat dan tidak dikenal oleh klien. Penghias melakukan yang sebaliknya: meningkatkan apa yang dilakukan oleh delegasinya dengan cara yang terlihat oleh klien.

Kita dapat mengatakan bahwa Proxy adalah kotak hitam sedangkan Dekorator adalah kotak putih.

Hubungan komposisi antara wrapper dan delegate adalah hubungan yang salah untuk difokuskan ketika membandingkan Proxy dengan Dekorator, karena komposisi adalah fitur yang sama-sama dimiliki kedua pola ini. Hubungan antara pembungkus dan klien adalah yang membedakan kedua pola ini.

  • Dekorator menginformasikan dan memberdayakan kliennya.
  • Proxy membatasi dan melemahkan kliennya.
jaco0646
sumber
114

Perbedaan sesungguhnya bukanlah kepemilikan (komposisi versus agregasi), melainkan tipe-informasi.

Sebuah dekorator yang selalu melewati delegatee nya. Sebuah Proxy mungkin menciptakannya sendiri, atau dia mungkin memilikinya disuntikkan.

Tapi Proxy selalu tahu (lebih) jenis delegasi tertentu. Dengan kata lain, Proxy dan delegatee-nya akan memiliki tipe basis yang sama, tetapi Proxy menunjuk ke beberapa tipe turunan. Sebuah Decorator menunjuk ke tipe dasar sendiri. Dengan demikian, perbedaannya adalah dalam informasi waktu kompilasi tentang jenis delegasi.

Dalam bahasa yang dinamis, jika delegate disuntikkan dan kebetulan memiliki antarmuka yang sama, maka tidak ada perbedaan.

Jawaban atas pertanyaan Anda adalah ya".

cdunn2001
sumber
2
"Tapi Proxy selalu tahu jenis delegasi yang spesifik (lebih)." Saya tidak berpikir itu benar. Bayangkan proksi jarak jauh. Mekanisme proxy tidak perlu mengetahui secara spesifik objek jarak jauh. Sistem jarak jauh mendaftarkan objek dengan antarmuka yang ditentukan. Dan proxy lokal memperlihatkan antarmuka yang sama.
Alexey
3
Saya mengikuti kelas ini di Amazon dari dosen tamu yang mengetahui barang-barangnya. Ada perbedaan antara penggunaan "proxy" yang dapat dieksekusi (mis. Dengan layanan web) dan Pola Desain Proxy. UML dari pola Proxy dan pola Decorator dapat berbeda. Tetapi tidak ada yang mencegah Proksi memiliki API yang sama dengan delegasinya. Dekorator adalah bagian ketat dari Proksi, tetapi Dekorator mungkin masih disebut Proksi tergantung pada apakah API yang mendasarinya dijamin sama.
cdunn2001
85

Pola Dekorator berfokus pada penambahan fungsi secara dinamis ke suatu objek, sementara Pola Proxy berfokus pada pengontrolan akses ke suatu objek.

EDIT: -

Hubungan antara Proxy dan subjek nyata biasanya diatur pada waktu kompilasi, Proxy membuat contoh dalam beberapa cara, sedangkan Dekorator ditugaskan ke subjek saat runtime, hanya mengetahui antarmuka subjek.

Rahul Tripathi
sumber
5
Proxy masih dapat digunakan untuk menambah fungsionalitas. Pikirkan proxy AOP.
Sotirios Delimanolis
5
Sepenuhnya setuju Pak. Saya akan mengonversi itu dengan kata lain apa yang saya maksudkan dengan Pola Proxy, kelas proxy dapat menyembunyikan informasi detail suatu objek dari kliennya. Karena itu, ketika menggunakan Pola Proxy, kami biasanya membuat instance dari abject di dalam kelas proxy. Dan ketika menggunakan Pola Dekorator, kami biasanya meneruskan objek asli sebagai parameter ke konstruktor dekorator.
Rahul Tripathi
Dalam hal ini ketika instance 'disembunyikan' dalam proksi, perbedaannya jelas bagi saya (seperti yang saya tulis) namun saya berpikir bahwa sering orang memanggil sebagai kelas proksi yang mengambil objek proksi yang dilewatkan sebagai parameter konstruktor. Dalam hal ini perbedaan menambahkan fungsionalitas baru atau mengendalikan (sangat) tipis bagi saya.
Łukasz Rzeszotarski
5
Hubungan antara Proxy dan subjek nyata biasanya diatur pada waktu kompilasi, Proxy membuat instance dalam beberapa cara, sedangkan Dekorator atau Adaptor ditugaskan ke subjek saat runtime, hanya mengetahui antarmuka subjek. Harapan itu masuk akal !!! :)
Rahul Tripathi
1
Anda dapat menambahkan baris ini ke jawaban Anda.
Łukasz Rzeszotarski
49

Dekorator mendapatkan referensi untuk objek yang didekorasi (biasanya melalui konstruktor) sementara Proxy bertanggung jawab untuk melakukannya sendiri.

Proksi sama sekali tidak dapat membuat instance objek pembungkus (seperti ini lakukan ORM untuk mencegah akses yang tidak perlu ke DB jika bidang objek / pengambil tidak digunakan) sementara Dekorator selalu memegang tautan ke instance pembungkus aktual.

Proxy biasanya digunakan oleh frameworks untuk menambah keamanan atau caching / lazing dan dibangun oleh framework (bukan oleh developer reguler itu sendiri).

Dekorator biasanya digunakan untuk menambahkan perilaku baru ke kelas lama atau lama oleh pengembang itu sendiri berdasarkan antarmuka daripada kelas yang sebenarnya (sehingga bekerja pada berbagai contoh antarmuka, Proxy ada di sekitar kelas beton).

gavenkoa
sumber
22

Perbedaan utama:

  1. Proxy menyediakan antarmuka yang sama. Dekorator menyediakan antarmuka yang ditingkatkan.
  2. Dekorator dan Proksi memiliki tujuan yang berbeda tetapi struktur yang serupa. Keduanya menggambarkan bagaimana memberikan tingkat tipuan ke objek lain, dan implementasinya tetap mengacu pada objek yang mereka ajukan permintaan.
  3. Dekorator dapat dilihat sebagai Komposit degenerasi dengan hanya satu komponen. Namun, Dekorator menambahkan tanggung jawab tambahan - tidak dimaksudkan untuk agregasi objek.
  4. Dekorator mendukung komposisi rekursif
  5. Kelas Dekorator menyatakan hubungan komposisi dengan antarmuka LCD (Penyingkat Kelas Terendah), dan anggota data ini diinisialisasi dalam konstruktornya.
  6. Gunakan Proxy untuk inisialisasi malas, peningkatan kinerja dengan caching objek dan mengontrol akses ke klien / pemanggil

Sourcemaking artikel mengutip persamaan dan perbedaan dalam cara yang sangat baik.

Pertanyaan / tautan SE terkait:

Kapan Menggunakan Pola Penghias?

Apa perbedaan yang tepat antara pola Adaptor dan Proksi?

Ravindra babu
sumber
3

Proxy dan Dekorator berbeda dalam tujuan dan di mana mereka fokus pada implementasi internal. Proxy adalah untuk menggunakan objek jarak jauh, lintas proses, atau lintas jaringan seolah-olah itu adalah objek lokal. Dekorator adalah untuk menambahkan perilaku baru ke antarmuka asli.

Sementara kedua pola memiliki struktur yang sama, sebagian besar kompleksitas Proxy terletak dalam memastikan komunikasi yang tepat dengan objek sumber. Penghias, di sisi lain, berfokus pada penerapan perilaku yang ditambahkan.

James Lin
sumber
Apa yang Anda katakan berbeda dari 4 jawaban lainnya yang sudah ada di sini?
Stephen Rauch
Saya tidak tahu apakah semua ada di sana. Saya hanya merasakan keinginan untuk berbunyi setelah membaca jawaban sebelumnya.
James Lin
1

Butuh beberapa saat untuk mencari tahu jawaban ini dan apa artinya sebenarnya. Beberapa contoh harus membuatnya lebih jelas.

Proxy pertama:

public interface Authorization {
    String getToken();
} 

Dan:

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

Dan ada penelepon ini Authorization, yang sangat bodoh:

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

Sejauh ini tidak ada yang tidak biasa, bukan? Dapatkan token dari layanan tertentu, gunakan token itu. Sekarang hadir satu persyaratan lagi untuk gambar, tambahkan logging: arti log token setiap kali. Sederhana untuk kasus ini, cukup buat 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;
    }
}

Bagaimana kita menggunakannya?

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

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

Perhatikan bahwa LoggingDBAuthorization memegang instance dari DBAuthorization. Keduanya LoggingDBAuthorizationdan DBAuthorization implementasikan Authorization .

  • Proxy akan mengadakan implementasi konkret ( DBAuthorization) antarmuka dasar ( Authorization). Dengan kata lain Proksi tahu persis apa yang sedang diproksi.

Decorator:

Dimulai hampir sama dengan Proxy, dengan antarmuka:

public interface JobSeeker {
    int interviewScore();
}

dan implementasi dari itu:

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

Dan sekarang kami ingin menambahkan kandidat yang lebih berpengalaman, yang menambahkan skor wawancara ditambah satu dari yang lain JobSeeker:

@RequiredArgsConstructor 
public class TwoYearsInTheIndustry implements JobSeeker {

    private final JobSeeker jobSeeker;

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

Perhatikan bagaimana saya mengatakan itu ditambah satu dari JobSeeker lain , bukan Newbie . A Decoratortidak tahu persis apa itu dekorasi, ia tahu hanya kontrak contoh yang dihiasi (ia tahu tentang JobSeeker). Perhatikan di sini bahwa ini tidak seperti Proxy; sebaliknya, tahu persis apa itu dekorasi.

Anda mungkin mempertanyakan apakah sebenarnya ada perbedaan antara dua pola desain dalam kasus ini? Bagaimana jika kami mencoba menulis Decoratorsebagai Proxy?

public class TwoYearsInTheIndustry implements JobSeeker {

    private final Newbie newbie = new Newbie();

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

Ini jelas merupakan pilihan dan menyoroti seberapa dekat pola-pola ini; mereka masih ditujukan untuk skenario yang berbeda seperti yang dijelaskan dalam jawaban lain.

Eugene
sumber
1

Proxy menyediakan antarmuka yang sama ke objek yang dibungkus, Penghias menyediakannya dengan antarmuka yang ditingkatkan, dan Proxy biasanya mengelola siklus hidup objek layanannya sendiri, sedangkan komposisi Dekorator selalu dikontrol oleh klien.

Ali Bayat
sumber