Visitor pattern

Trong thiết kế hướng đối tượng, Visitor là mẫu thiết kế (Design Patterns) cho phép định nghĩa các thao tác (operations) trên một tập hợp các đối tượng (objects) không đồng nhất (về kiểu) mà không làm thay đổi định nghĩa về lớp (classes) của các đối tượng đó. Để đạt được điều này, trong mẫu thiết kế visitor ta định nghĩa các thao tác trên các lớp tách biệt gọi các lớp visitors, các lớp này cho phép tách rời các thao tác với các đối tượng mà nó tác động đến. Với mỗi thao tác được thêm vào, một lớp visitor tương ứng được tạo ra.

Thiết kế

[sửa | sửa mã nguồn]

Thiết kế của mẫu visitor gồm 3 phần:

Các lớp visitor

[sửa | sửa mã nguồn]

Các lớp visitor định nghĩa các thao tác tương tác trên các đối tượng. Các lớp này là cài đặt của một giao diện chung là VisitorInterface trong đó định nghĩa các phương thức dạng visit(ObjectType object),với mỗi kiểu (lớp) của các đối tượng ta có một phương thức visit với tham số truyền vào là một thực thể của kiểu đó. Mỗi phương thức như thế có nhiệm vụ xử lý trên các thực thể của lớp tương ứng. Ví dụ ta có tập hợp các đối tượng là các thực thể của hai kiểu(lớp) ClassA và ClassB thì VisitorInterface sẽ bao gồm hai phương thức:

visit(ClassA obj)
visit(ClassB obj)

Các lớp của các đối tượng trong tập hợp các đối tượng

[sửa | sửa mã nguồn]

Để các thao tác định nghĩa trong các lớp visitor có thể thực hiện được, các lớp của các đối tượng trong tập hợp các đối tượng cần cài đặt giao diện Visitable trong đó có một phương thức accept(VisitorInterface visitor). Trong cài đặt của phương thức này ta gọi hàm visit của visitor với tham số truyền vào chính là đối tượng gọi:

public void accept(VisitorInterface visitor){
 visitor.visit(this);
}

Các client muốn thực thi thao tác của visitor trên tập hợp các đối tượng cần phải tạo ra một thực thể của lớp vistor tương ứng với thao tác đó, và sau đó gọi phương thức accept của từng đối tượng trong tập hợp các đối tượng với tham số là thực thể visitor vừa tạo ra. (Xem ví dụ để hiểu rõ hơn)

Sau đây là một ví dụ đơn giản minh họa áp dụng của mẫu thiết kế trên và cũng để hiểu rõ thêm về cài đặt của nó.

Sơ đồ lớp của ví dụ bằng UML

[sửa | sửa mã nguồn]

Tập tin:Wiki visitor.png

Cài đặt bằng Java

[sửa | sửa mã nguồn]

Sau đây là cài đặt của ví dụ trên bằng ngôn ngữ Java

interface Visitor {
 public void visit(Wheel wheel);
 public void visit(Engine engine);
 public void visit(Body body);
 public void visit(Car car);
}

//differing from above displayed UML: Additional use of an interface 'Element'
interface Element {
 public void accept(Visitor visitor);
}

/* Concrete element */
class Wheel implements Element {
 private String name;
 Wheel(String name) {
 this.name = name;
 }
 String getName() {
 return this.name;
 }
 public void accept(Visitor visitor) {
 visitor.visit(this);
 }
}

/* Concrete element */
class Engine implements Element{
 public void accept(Visitor visitor) {
 visitor.visit(this);
 }
}

/* Concrete element */
class Body implements Element{
 public void accept(Visitor visitor) {
 visitor.visit(this);
 }
}

/* Concrete element */
class Car implements Element {
 private Engine engine = new Engine();
 private Body body = new Body();
 private Wheel[] wheels 
 = { new Wheel("front left"), new Wheel("front right"),
 new Wheel("back left"), new Wheel("back right") };
 public void accept(Visitor visitor) {
 visitor.visit(this);
 engine.accept(visitor);
 body.accept(visitor);
 for(int i=0; i<wheels.length; ++i)
 wheels[i].accept(visitor);
 }
}

/* Concrete visitor */
class PrintVisitor implements Visitor {
 public void visit(Wheel wheel) {
 System.out.println("Visiting "+wheel.getName()
  +" wheel");
 }
 public void visit(Engine engine) {
 System.out.println("Visiting engine");
 }
 public void visit(Body body) {
 System.out.println("Visiting body");
 }
 public void visit(Car car) {
 System.out.println("Visiting car");
 }
}

public class VisitorDemo {
 public static void main(String[] args){
 Car car = new Car();
 Visitor visitor = new PrintVisitor();
 car.accept(visitor);
 }
}

Tham khảo

[sửa | sửa mã nguồn]
Chúng tôi bán
Bài viết liên quan
[Next Comer - Limited Banner - Awakening AG] Factor Nio/ Awaken Nio - The Puppet Emperor
[Next Comer - Limited Banner - Awakening AG] Factor Nio/ Awaken Nio - The Puppet Emperor
Nio từ chối tử thần, xoá bỏ mọi buff và debuff tồn tại trên bản thân trước đó, đồng thời hồi phục 100% HP
Một vài thông tin về Joy Boy  - One Piece
Một vài thông tin về Joy Boy - One Piece
Ông chính là người đã để lại một báu vật tại hòn đảo cuối cùng của Grand Line, sau này báu vật ấy được gọi là One Piece, và hòn đảo đó được Roger đặt tên Laugh Tale
SPAC là gì và vì sao Vinfast lựa chọn SPAC để niêm yết trên sàn chứng khoán Nasdaq?
SPAC là gì và vì sao Vinfast lựa chọn SPAC để niêm yết trên sàn chứng khoán Nasdaq?
Trong niềm tự hào vì 1 công ty Việt Nam có thể niêm yết trên 1 trong những sàn giao dịch chứng khoán nổi tiếng nhất thế giới là Nasdaq của Mỹ
Chàng Trai Khắc Kỷ Sẽ Sống Như Thế Nào?
Chàng Trai Khắc Kỷ Sẽ Sống Như Thế Nào?
Trước khi bắt đầu mình muốn bạn đọc nhập tâm là người lắng nghe thằng homie kể về người thứ 3