Saya melihat Proxy Pattern, dan bagi saya sepertinya banyak sekali pola dekorator, Adapter, dan Bridge. Apakah saya salah mengerti sesuatu? Apa bedanya? Mengapa saya menggunakan pola Proksi dibandingkan yang lain? Bagaimana Anda menggunakannya di masa lalu dalam proyek dunia nyata?
design-patterns
decorator
bridge
proxy-pattern
Charles Graham
sumber
sumber
Jawaban:
Proxy, Dekorator, Adaptor, dan Jembatan adalah semua variasi pada "pembungkus" suatu kelas. Tetapi penggunaannya berbeda.
Proxy dapat digunakan ketika Anda ingin malas-instantiate objek, atau menyembunyikan fakta bahwa Anda memanggil layanan jarak jauh, atau mengontrol akses ke objek.
Dekorator juga disebut "Proksi Cerdas." Ini digunakan ketika Anda ingin menambahkan fungsionalitas ke objek, tetapi tidak dengan memperluas tipe objek itu. Ini memungkinkan Anda melakukannya saat runtime.
Adaptor digunakan ketika Anda memiliki antarmuka abstrak, dan Anda ingin memetakan antarmuka itu ke objek lain yang memiliki peran fungsional serupa, tetapi antarmuka yang berbeda.
Bridge sangat mirip dengan Adapter, tetapi kami menyebutnya Bridge ketika Anda mendefinisikan antarmuka abstrak dan implementasi yang mendasarinya. Yaitu Anda tidak beradaptasi dengan beberapa kode warisan atau pihak ketiga, Anda adalah perancang semua kode tetapi Anda harus dapat menukar implementasi yang berbeda.
Facade adalah antarmuka tingkat tinggi (baca: sederhana) ke subsistem dari satu atau lebih kelas. Misalkan Anda memiliki konsep kompleks yang membutuhkan banyak objek untuk diwakili. Membuat perubahan pada kumpulan objek itu membingungkan, karena Anda tidak selalu tahu objek mana yang memiliki metode yang perlu Anda panggil. Itulah waktu untuk menulis Fasad yang menyediakan metode tingkat tinggi untuk semua operasi kompleks yang dapat Anda lakukan untuk pengumpulan objek. Contoh: Model Domain untuk bagian sekolah, dengan metode seperti
countStudents()
,reportAttendance()
,assignSubstituteTeacher()
, dan sebagainya.sumber
Seperti jawaban Bill mengatakan, kasus penggunaannya berbeda .
Begitu juga struktur mereka.
Proxy dan Dekorator keduanya memiliki antarmuka yang sama dengan tipe yang dibungkus, tetapi proksi membuat instance di bawah tenda, sedangkan dekorator mengambil instance dalam konstruktor.
Adaptor dan Fasad keduanya memiliki antarmuka yang berbeda dari yang mereka bungkus. Tetapi adaptor berasal dari antarmuka yang ada, sedangkan fasad menciptakan antarmuka baru.
Bridge dan Adapter keduanya menunjuk pada tipe yang ada. Tetapi jembatan akan menunjuk ke jenis abstrak, dan adaptor mungkin menunjuk ke jenis beton. Bridge akan memungkinkan Anda untuk memasangkan implementasi saat runtime, sedangkan adaptor biasanya tidak.
sumber
Pandangan saya tentang masalah ini.
Keempat pola memiliki banyak kesamaan, keempatnya kadang-kadang secara informal disebut pembungkus, atau pola pembungkus. Semua menggunakan komposisi, membungkus subjek dan mendelegasikan eksekusi ke subjek di beberapa titik, lakukan pemetaan satu pemanggilan metode ke yang lain. Mereka menghindarkan klien dari keharusan membangun objek yang berbeda dan menyalin semua data yang relevan. Jika digunakan dengan bijak, mereka menghemat memori dan prosesor.
Dengan mempromosikan kopling longgar, mereka membuat kode stabil sekali kurang terekspos terhadap perubahan yang tak terhindarkan dan lebih mudah dibaca oleh sesama pengembang.
Adaptor
Adaptor menyesuaikan subjek (adaptee) ke antarmuka yang berbeda. Dengan cara ini kita dapat menambahkan objek yang ditempatkan pada kumpulan jenis yang berbeda secara nominal.
Adaptor hanya mengekspos metode yang relevan untuk klien, dapat membatasi semua yang lain, mengungkapkan maksud penggunaan untuk konteks tertentu, seperti mengadaptasi perpustakaan eksternal, membuatnya tampak kurang umum dan lebih fokus pada kebutuhan aplikasi kami. Adaptor meningkatkan keterbacaan dan deskripsi diri dari kode kami.
Adaptor melindungi satu tim dari kode volatil dari tim lain; alat penyelamat saat berurusan dengan tim lepas pantai ;-)
Tujuan yang kurang disebutkan adalah untuk mencegah kelas subjek dari anotasi berlebih. Dengan begitu banyak kerangka kerja berdasarkan anotasi, ini menjadi penggunaan yang lebih penting dari sebelumnya.
Adaptor membantu untuk mengatasi keterbatasan Jawa hanya satu warisan. Itu dapat menggabungkan beberapa adaptee di bawah satu amplop memberikan kesan pewarisan berganda.
Dari segi kode, Adaptor “tipis”. Seharusnya tidak menambahkan banyak kode ke kelas adaptee, selain hanya memanggil metode adaptee dan sesekali konversi data yang diperlukan untuk melakukan panggilan seperti itu.
Tidak ada banyak contoh adaptor yang baik di JDK atau perpustakaan dasar. Pengembang aplikasi membuat Adapters, untuk mengadaptasi perpustakaan ke antarmuka spesifik aplikasi.
Penghias
Penghias tidak hanya mendelegasikan, tidak hanya memetakan satu metode ke metode lain, mereka melakukan lebih banyak, mereka memodifikasi perilaku beberapa metode subjek, dapat memutuskan untuk tidak memanggil metode subjek sama sekali, mendelegasikan ke objek yang berbeda, objek pembantu.
Dekorator biasanya menambahkan fungsionalitas (secara transparan) ke objek yang dibungkus seperti pencatatan, enkripsi, pemformatan, atau kompresi pada subjek. Fungsionalitas baru ini dapat membawa banyak kode baru. Karenanya, dekorator biasanya jauh lebih "gemuk" dari pada Adaptor.
Dekorator haruslah sub-kelas antarmuka subjek. Mereka dapat digunakan secara transparan, bukan pada subjeknya. Lihat BufferedOutputStream, itu masih OutputStream dan dapat digunakan seperti itu. Itu adalah perbedaan teknis utama dari Adapters.
Contoh buku teks seluruh keluarga dekorator tersedia di JDK - Java IO. Semua kelas seperti BufferedOutputStream , FilterOutputStream dan ObjectOutputStream adalah dekorator OutputStream . Mereka dapat berlapis bawang, di mana satu dekorator dihiasi lagi, menambahkan lebih banyak fungsi.
Proksi
Proxy bukan pembungkus khas. Objek yang dibungkus, subjek proxy, mungkin belum ada pada saat pembuatan proxy. Proxy sering membuatnya secara internal. Ini mungkin objek berat yang dibuat atas permintaan, atau objek jarak jauh di JVM yang berbeda atau node jaringan yang berbeda dan bahkan objek non-Jawa, komponen dalam kode asli. Tidak perlu membungkus atau mendelegasikan ke objek lain sama sekali.
Contoh paling umum adalah proksi jarak jauh, penginisialisasi objek berat, dan proksi akses.
Remote Proxy - subjek berada di server jarak jauh, JVM yang berbeda atau bahkan sistem non Java. Proxy menerjemahkan panggilan metode ke panggilan RMI / REST / SOAP atau apa pun yang diperlukan, melindungi klien dari paparan teknologi yang mendasarinya.
Lazy Load Proxy - sepenuhnya menginisialisasi objek hanya penggunaan pertama atau penggunaan intensif pertama.
Access Proxy - mengontrol akses ke subjek.
Tatapan
Fasad terkait erat dengan desain Principle of Least Knowledge (Law of Demeter). Fasad sangat mirip dengan Adaptor. Mereka berdua membungkus, mereka berdua memetakan satu objek ke yang lain, tetapi mereka berbeda dalam niat. Fasad meratakan struktur kompleks subjek, grafik objek kompleks, menyederhanakan akses ke struktur kompleks.
Fasad membungkus struktur yang kompleks, menyediakan antarmuka datar untuknya. Ini mencegah objek klien dari terkena hubungan dalam struktur subjek sehingga mempromosikan kopling longgar.
Jembatan
Varian yang lebih kompleks dari pola Adaptor di mana implementasi tidak hanya bervariasi tetapi juga abstraksi. Itu menambah satu lagi tipuan ke delegasi. Delegasi tambahan adalah jembatan. Ini memisahkan Adapter bahkan dari mengadaptasi antarmuka. Ini meningkatkan kompleksitas lebih dari yang lain dari pola pembungkus lainnya, jadi terapkan dengan hati-hati.
Perbedaan konstruktor
Perbedaan pola juga jelas ketika melihat konstruktor mereka.
Proxy tidak membungkus objek yang ada. Tidak ada subjek dalam konstruktor.
Dekorator dan Adaptor tidak membungkus objek yang sudah ada, dan biasanya
disediakan di konstruktor.
Konstruktor fasad mengambil elemen root dari keseluruhan grafik objek, jika tidak maka akan tampak sama dengan Adapter.
Contoh kehidupan nyata - JAXB Marshalling Adapter . Tujuan dari adaptor ini adalah pemetaan kelas datar sederhana ke struktur yang lebih kompleks yang diperlukan secara eksternal dan untuk mencegah "mencemari" kelas subjek dengan anotasi yang berlebihan.
sumber
Ada banyak tumpang tindih di banyak pola GoF. Mereka semua dibangun di atas kekuatan polimorfisme dan kadang-kadang hanya berbeda niat. (strategi vs. negara)
Pemahaman saya tentang pola meningkat 100 kali lipat setelah membaca Pola Desain Kepala Pertama .
Saya sangat merekomendasikannya!
sumber
Semua jawaban yang baik dari para ahli telah menjelaskan apa arti setiap pola.
Saya akan menghias poin-poin penting.
Penghias:
misalnya (dengan rantai):
java.io
kelas paket yang terkait denganInputStream
&OutputStream
antarmukaProksi:
mis:
java.rmi
kelas paket.Adaptor:
mis.
java.io.InputStreamReader
(InputStream
mengembalikan aReader
)Jembatan:
mis. Kelas koleksi di
java.util
.List
diimplementasikan olehArrayList
.Catatan kunci:
Lihat pertanyaan SE / artikel bagus tentang contoh berbagai pola desain
Kapan Menggunakan Pola Penghias?
Kapan Anda menggunakan Pola Jembatan? Apa bedanya dengan pola Adaptor?
Perbedaan antara Proxy dan Pola Dekorator
sumber
Mereka sangat mirip, dan garis-garis di antara mereka cukup abu-abu. Saya sarankan Anda membaca entri Pola Proxy dan Pola Penghias di wiki c2.
Entri dan diskusi di sana cukup luas, dan mereka juga menghubungkan ke artikel lain yang relevan. Ngomong-ngomong, wiki c2 sangat bagus ketika bertanya-tanya tentang nuansa antara pola yang berbeda.
Untuk meringkas entri c2, saya akan mengatakan dekorator menambah / mengubah perilaku, tetapi proxy lebih berkaitan dengan kontrol akses (malas instantiation, akses jarak jauh, keamanan dll). Tapi seperti yang saya katakan, garis-garis di antara mereka berwarna abu-abu, dan saya melihat referensi ke proxy yang dapat dengan mudah dilihat sebagai dekorator dan sebaliknya.
sumber
Keempat pola melibatkan membungkus objek / kelas batin dengan yang luar, sehingga mereka sangat mirip secara struktural. Saya akan menguraikan perbedaan dengan tujuan:
Dan dengan variasi antarmuka antara objek dalam dan luar:
sumber
Ini adalah kutipan dari Pola Desain Kepala Pertama
Definisi adalah milik buku. Contohnya milik saya.
Dekorator - Tidak mengubah antarmuka, tetapi menambah tanggung jawab. Asumsikan Anda memiliki antarmuka mobil, ketika Anda menerapkan ini untuk model mobil yang berbeda (s, sv, sl) Anda mungkin perlu menambahkan lebih banyak tanggung jawab untuk beberapa model. Seperti memiliki sunroof, airbag dll.
Adaptor - Mengubah satu antarmuka ke antarmuka lainnya. Anda memiliki antarmuka mobil dan Anda ingin bertindak seperti jip. Jadi Anda mengambil mobil, memodifikasinya dan berubah menjadi jip. Karena itu bukan jip asli. Tapi bertindak seperti jip.
Fasad - Membuat antarmuka lebih sederhana. Asumsikan Anda memiliki antarmuka mobil, pesawat, dan kapal. Sebenarnya yang Anda butuhkan adalah kelas yang mengirim orang dari satu lokasi ke lokasi lain. Anda ingin fasad memutuskan kendaraan apa yang akan digunakan. Kemudian Anda mengumpulkan semua referensi antarmuka di bawah 1 payung dan membiarkannya memutuskan / mendelegasikan untuk membuatnya sederhana.
Head First: "Fasad tidak hanya menyederhanakan antarmuka, tetapi juga memisahkan klien dari subsistem komponen. Fasad dan adaptor dapat membungkus beberapa kelas, tetapi maksud fasad adalah untuk menyederhanakan, sedangkan adaptor adalah untuk mengubah antarmuka menjadi sesuatu yang berbeda. "
sumber
Saya sering menggunakannya ketika mengkonsumsi layanan web. Pola Proxy mungkin harus diubah namanya menjadi sesuatu yang lebih pragmatis, seperti 'Pola Pembungkus ". Saya juga memiliki perpustakaan yang merupakan Proxy ke MS Excel. Ini membuatnya sangat mudah untuk mengotomatisasi Excel, tanpa harus khawatir tentang detail latar belakang seperti apa versi diinstal (jika ada).
sumber
Berbicara implementasi detail, saya menemukan perbedaan antara Proxy dan Dekorator, Adaptor, Fasad ... Dalam penerapan umum dari pola-pola ini ada objek target yang dibungkus oleh objek tertutup. Klien menggunakan objek terlampir sebagai ganti objek target. Dan objek target sebenarnya memainkan peran penting dalam beberapa metode melampirkan objek.
Namun, dalam kasus Proksi, melampirkan objek dapat memainkan beberapa metode dengan sendirinya, itu hanya menginisialisasi objek target ketika klien memanggil beberapa metode yang diperlukan objek target untuk mengambil bagian. Ini inisialisasi malas. Dalam hal pola lain, melampirkan objek sebenarnya didasarkan pada objek target. Jadi objek target selalu diinisialisasi bersama dengan melampirkan objek dalam konstruktor / setter.
Hal lain, proxy melakukan apa yang target lakukan sedangkan pola lainnya menambahkan lebih banyak fungsionalitas ke target.
sumber
Saya ingin menambahkan contoh untuk jawaban Bill Karwing (yang bagus btw.) Saya juga menambahkan beberapa perbedaan utama implementasi, yang saya rasa hilang
Bagian yang dikutip berasal dari jawaban [ https://stackoverflow.com/a/350471/1984346] (Bill Karwing)
ProxyClass dan ObjectClass yang diproksi, harus mengimplementasikan antarmuka yang sama, sehingga mereka dapat dipertukarkan
Contoh - proksi objek mahal
DecoratorClass harus (dapat) mengimplementasikan antarmuka ObjectClass yang diperluas. Jadi ObjectClass bisa diganti oleh DecoratorClass, tetapi tidak sebaliknya.
Contoh - menambahkan fungsionalitas penambahan
Perbedaan Implikasi Proksi, Dekorator, Adaptor
Adaptor menyediakan antarmuka yang berbeda untuk subjeknya. Proxy menyediakan antarmuka yang sama. Dekorator menyediakan antarmuka yang ditingkatkan.
Sebagian besar informasi dalam jawaban ini adalah dari https://sourcemaking.com/design_patterns , yang saya rekomendasikan sebagai sumber yang bagus untuk pola desain.
sumber
Saya percaya kode akan memberikan ide yang jelas (untuk melengkapi jawaban orang lain juga). Silakan lihat di bawah, (Fokuskan jenis yang diterapkan dan dibungkus kelas)
sumber
Pola desain bukan matematika, itu kombinasi seni dan rekayasa perangkat lunak. Tidak ada yang seperti untuk persyaratan ini Anda harus menggunakan proxy, menjembatani dll. Pola desain dibuat untuk menyelesaikan masalah. Jika Anda mengantisipasi masalah desain, maka gunakan. Berdasarkan pengalaman, Anda akan mengetahui untuk masalah tertentu, pola mana yang digunakan. Jika Anda bagus dalam prinsip-prinsip desain yang solid, Anda akan menerapkan pola desain tanpa menyadarinya. Contoh umum adalah pola statergy dan pabrik
Oleh karena itu lebih berkonsentrasi pada prinsip-prinsip desighn solid, prinsip-prinsip pengkodean bersih dan ttd
sumber