Definisi: merangkum operasi tertentu yang bertindak pada setiap elemen dalam struktur data tertentu. Ini dapat mendefinisikan operasi baru yang bertindak pada elemen -elemen ini tanpa mengubah struktur data.
Jenis: Pola perilaku
Diagram kelas:
contoh:
Misalnya, pikirkan tentang menambahkan berbagai jenis barang ke keranjang, dan saat mengklik checkout, ia menghitung biaya yang harus dibayar untuk semua barang yang berbeda. Sekarang, logika perhitungan adalah untuk menghitung harga berbagai jenis barang ini. Atau dengan kata lain, kami mentransfer logika ini ke kelas lain melalui mode pengunjung. Mari kita terapkan contoh pola pengunjung ini.
Untuk mengimplementasikan pola pengunjung, hal pertama yang harus dilakukan adalah membuat kelas yang dapat ditambahkan ke keranjang belanja untuk mewakili berbagai jenis item (ItemElements).
ItemElement.javapackage com.journaldev.design.visitor; antarmuka publik itemElement {public int accept (pengunjung ShoppingCartVisitor);}Perhatikan bahwa metode menerima menerima pengunjung sebagai parameter. Tentu saja, ada cara lain untuk menentukan produk terperinci di sini, tetapi untuk kesederhanaan, tidak perlu mempertimbangkan terlalu banyak detail di sini, hanya berfokus pada mode pengunjung.
Sekarang buat beberapa kelas entitas untuk berbagai produk.
Book.java
paket com.journaldev.design.visitor; buku kelas publik mengimplementasikan itemElement {private int price; string pribadi isbnnumber; buku publik (biaya int, string ISBN) {this.price = biaya; this.isbnnumber = isbn; } public int getPrice () {harga kembali; } public string getisbnnumber () {return isBnnumber; } @Override public int accept (ShoppingCartVisitor Visitor) {return visitor.visit (this); }}Buah.java
paket com.journaldev.design.visitor; kelas publik mengimplementasikan itemElement {private int pricePerkg; berat int pribadi; nama string pribadi; buah publik (int pricekg, int wt, string nm) {this.priceperkggg = pricekg; this.weight = wt; this.name = nm; } public int getPricePerkg () {return pricePerkg; } public int getWeight () {return weight; } public string getName () {return this.name; } @Override public int accept (ShoppingCartVisitor Visitor) {return visitor.visit (this); }} Perhatikan bahwa implementasi metode penerimaan () ada di kelas entitas, yang memanggil metode pengunjung kunjungan () untuk meneruskan objek kelas saat ini sebagai parameternya sendiri.
Di sini, metode kunjungan () yang digunakan untuk berbagai jenis barang akan diterapkan di kelas entitas antarmuka pengunjung.
ShoppingCartVisitor.java
paket com.journaldev.design.visitor; antarmuka publik ShoppingCartVisitor {int visit (buku buku); int kunjungan (buah buah);}Antarmuka pengunjung sekarang akan diimplementasikan dan logika menghitung pengeluarannya sendiri untuk setiap produk.
ShoppingCartVisitorImpl.java
Paket com.journaldev.design.visitor; Public Class ShoppingCartVisitorImpl mengimplementasikan ShoppingCartVisitor {@Override Public Int Visit (buku buku) {int cost = 0; // Terapkan 5 $ diskon jika harga buku lebih besar dari 50 if (book.getPrice ()> 50) {cost = book.getPrice ()-5; } else cost = book.getPrice (); System.out.println ("BUKU ISBN ::"+Book.GetisBnNumber ()+"cost ="+cost); biaya pengembalian; } @Override Public int Visit (buah buah) {int cost = fruit.getpriceperkg ()*fruit.getweight (); System.out.println (Fruit.getName () + "cost =" + cost); biaya pengembalian; }}Sekarang mari kita lihat cara menggunakannya dalam program.
ShoppingCartClient.java
Paket com.journaldev.design.visitor; kelas publik shoppingCartClient {public static void main (string [] args) {itemElement [] item = new itemElement [] {Buku baru (20, "1234"), buku baru (100, "5678"), Buah Baru (10, 2, "Banana"), baru (100, "5678"), Buah (10, 2, 2, "Banana"), "5678"), Buff (10, 2, 2, "Banana"), "5678"), BUKU (10, 2, 2, 2, 2, "BURANA"), "BUKAAN"), BUKU BURAT (10, 2, 2, "BURAN"), BUKA (100, "BURAN" BUKAAN (100, "BUKA, APPLE (100," BUKA, " int total = CalculatePrice (item); System.out.println ("Total biaya ="+total); } private static int calculatePrice (itemElement [] item) {ShoppingCartVisitor pengunjung = ShoppingCartVisitorImpl (); int sum = 0; untuk (item itemElement: item) {sum = sum + item.accept (pengunjung); } return sum; }}Saat menjalankan program di atas, kami mendapatkan output berikut.
BUKU ISBN :: 1234 Biaya = 20book ISBN :: 5678 Biaya = 95Banana Biaya = 20 biaya Apple = 25 biaya total = 160
Harap dicatat bahwa implementasinya di sini tampaknya sama dengan metode ACCECT () untuk semua produk, tetapi juga bisa berbeda. Misalnya, jika produk kosong, ia dapat melakukan pemeriksaan logis dan tidak lagi memanggil metode kunjungan ().
Keuntungan dari Mode Pengunjung:
Mematuhi prinsip tanggung jawab tunggal: dalam skenario apa pun di mana mode pengunjung berlaku, operasi yang perlu dienkapsulasi dalam pengunjung di kelas elemen harus berupa operasi yang tidak ada hubungannya dengan kelas elemen itu sendiri dan mudah berubah. Di satu sisi, penggunaan mode pengunjung sesuai dengan prinsip tanggung jawab tunggal, dan di sisi lain, karena operasi yang dienkapsulasi biasanya tidak stabil, ketika perubahan terjadi, perluasan bagian yang berubah dapat dicapai tanpa mengubah kelas elemen itu sendiri.
Skalabilitas yang baik: Kelas elemen dapat memperluas operasi yang berbeda dengan menerima pengunjung yang berbeda.
Skenario yang berlaku untuk mode pengunjung:
Jika ada beberapa operasi dalam suatu objek yang tidak terkait dengan objek (atau terkait lemah) dan untuk menghindari operasi ini yang mencemari objek, Anda dapat menggunakan mode pengunjung untuk merangkum operasi ini ke dalam pengunjung.
Jika ada operasi serupa dalam sekelompok objek, untuk menghindari sejumlah besar kode duplikat, operasi duplikat ini juga dapat dienkapsulasi ke dalam pengunjung.
Namun, mode pengunjung tidak begitu sempurna, dan juga memiliki kelemahan fatal: menambahkan kelas elemen baru lebih sulit. Melalui kode pola pengunjung, kita dapat melihat bahwa di kelas pengunjung, setiap kelas elemen memiliki metode pemrosesan yang sesuai. Dengan kata lain, setiap kelas elemen perlu ditambahkan untuk memodifikasi kelas pengunjung (juga termasuk kelas subkelas atau implementasi kelas pengunjung), yang cukup merepotkan untuk dimodifikasi. Dengan kata lain, ketika jumlah kelas elemen tidak pasti, mode pengunjung harus digunakan dengan hati -hati. Oleh karena itu, mode pengunjung lebih cocok untuk refactoring fungsi yang ada. Misalnya, jika fungsi dasar suatu proyek telah ditentukan, data kelas elemen pada dasarnya telah ditentukan dan tidak akan berubah. Semua yang akan berubah adalah operasi yang relevan dalam elemen -elemen ini. Pada saat ini, kita dapat menggunakan mode pengunjung untuk refactor kode asli, sehingga fungsi asli dapat dimodifikasi tanpa memodifikasi setiap kelas elemen.
Meringkaskan:
Sebagai GOF, penulis pola desain, menjelaskan mode pengunjung: Dalam kebanyakan kasus, Anda perlu menggunakan mode pengunjung, tetapi begitu Anda membutuhkannya, Anda benar -benar membutuhkannya. Tentu saja ini hanya untuk orang -orang besar yang sebenarnya. Pada kenyataannya (setidaknya di lingkungan tempat saya berada), banyak orang sering kecanduan pola desain. Saat menggunakan pola desain, mereka tidak pernah secara serius mempertimbangkan apakah pola yang mereka gunakan cocok untuk skenario ini, tetapi seringkali hanya ingin menunjukkan kemampuan mereka untuk mengontrol desain yang berorientasi objek. Jika Anda memiliki mentalitas ini saat pemrograman, Anda sering menyalahgunakan pola desain. Oleh karena itu, ketika belajar pola desain, Anda harus memahami penerapan pola. Penting untuk menggunakan suatu pola karena Anda memahami kelebihannya, bukan untuk menggunakan suatu pola karena Anda memahami kerugiannya; Daripada menggunakan pola karena Anda tidak memahami kerugiannya, bukan untuk menggunakan pola karena Anda tidak memahami kelebihannya.