-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Kinh nghiệm phát triển dự án phức tạp, nhiều người - Tuân thủ
- Kinh nghiệm phát triển dự án phức tạp, nhiều người - Lựa chọn người đi cùng
- Ngành công nghiệp phần mềm tại Việt Nam - Mới chỉ là bắt đầu.
- Ngành công nghiệp phần mềm tại Việt Nam - Dây chuyền sản xuất.
- Ngành công nghiệp phần mềm tại Việt Nam - Thị trường
- Ngành công nghiệp phần mềm tại Việt Nam - Công ăn việc làm
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local
- Tham gia phát triển open source!
- Buôn có bạn, bán có phường
- Đam mê đi đâu rồi?
- Giữa lửa đam mê!
- Tương lai nào cho tester? Thay đổi để dẫn đầu xu thế!
- Tương lai nào cho tester? - Khi thế sự đổi thay!
- Tương lai nào cho lập trình viên? Khi không có hệ quy chiếu!
- Tương lai nào cho lập trình viên - Làm đến bao nhiêu tuổi?
- Tương lai nào cho lập trình viên? Có làm giàu được không?
- Tương lai nào cho lập trình viên? Có cân bằng cuộc sống được không?
- Tương lai nào cho lập trình viên - Nhảy việc đến khi nào?
- Tương lai nào cho lập trình viên - Con đường sự nghiệp (Career path)!
- Tương lai nào cho lập trình viên - Tổng kết lại!
- Con đường sự nghiệp cho lập trình viên - Giai đoạn sơ cấp (Junior)!
- Con đường sự nghiệp cho lập trình viên - Giai đoạn trung cấp (Intermediate)!
- Con đường sự nghiệp cho lập trình viên - Giai đoạn lành nghề (Senior)!
- Giai đoạn lành nghề (Senior) - Giữa những hoang mang!
- Giai đoạn lành nghề (Senior) - Phân hoá trong doanh nghiệp!
- Con đường sự nghiệp cho lập trình viên - Trở thành chuyên gia (Expert)!
- Con đường sự nghiệp cho lập trình viên - Trở thành người ảnh hưởng (Influencer)!
- Các giai đoạn phát triển của lập trình viên - Tổng kết lại!
- Metaverse - Câu chuyện 10 nghìn CCU (Người tham gia đồng thời)
- Metaverse có khả thi ở Việt Nam?
- Lựa chọn nghề nghiệp - DevOps!
- Lựa chọn nghề nghiệp - Project Manager (PM)!
- Lựa chọn nghề nghiệp - Data Engineer!
- Lựa chọn nghề nghiệp - BackEnd Engineer!
- “Talk is cheap. Show me the code” ― Linus Torvalds
- Lựa chọn nghề nghiệp - Web Front-End Engineer!
- Lựa chọn nghề nghiệp - Mobile Engineer!
- Lựa chọn nghề nghiệp - Game Engineer!
- Lựa chọn nghề nghiệp - Product Owner!
- Tuổi trẻ cần đột phá!
- Tuổi trẻ cần sự đồng cảm!
- Tuổi trẻ - điều đáng sợ đầu tiên là gì?
- Tuổi trẻ - Điều đáng sợ thứ 2 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 3 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 4 là gì?
- Nếu tận dụng hết năng lực thì sẽ thế nào?
- Tuổi trẻ - Điều đáng sợ thứ 5 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 6 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 7 là gì?
- Tuổi trẻ - ham học hỏi là như thế nào?
- Đầu tư cho bản thân là gì?
- Học chủ động!
- Có nên quay lại công ty cũ?
- Làm cho startup (công ty nhỏ) hay làm cho công ty lớn? (Phần 1)
- Làm cho startup (công ty nhỏ) hay làm cho công ty lớn? (Phần 2)
- Làm cho startup (công ty nhỏ) hay làm cho công ty lớn? (Phần 3)
- Tự học
- Học tập tại doanh nghiệp
- Học tại trung tâm
- Cách đọc sách kỹ thuật hiệu quả
- Học trong một tổ chức mã nguồn mở.
- Câu chuyện lập trình viên - Công việc đầu tiên
- Câu chuyện lập trình viên - Mức lương đầu tiên
- Câu chuyện lập trình viên - 2018
- Định hướng là gì?
- Wordpress nguy hiểm thế nào?
- Danh sách 10 trung tâm đào tạo trình uy tín, chất lượng ở Hà Nội
Thăm quan có mục đích
Cũng có chức năng giống với iterator design pattern, dùng để duyệt qua tất cả các phần tử của một đối tượng hay một collection, tuy nhiên visitor cung cấp cho chúng ta nhiều lựa chọn hơn để quyết định sẽ làm gì với những dữ liệu sẽ được duyệt qua. Ví dụ chúng ta sẽ in thông tin của đối tượng duyệt qua hoặc lưu thông tin các đối tượng vào file một cách dễ dàng.
Bài toán thực tế
Visitor được dùng khá nhiều trong các cấu trúc dữ liệu phức tạp như dạng cây (cây thực mục, BTree, TreeMap, ..) hay dạng dữ liệu đồ thị. Trong phạm vi bài viết này, chúng ta sẽ nói đến dạng dữ liệu đồ thị (Graph) nhé.
Đồ thị được cấu tạo bởi các đỉnh, các đỉnh này có mối liên hệ với nhau, nghĩa là từ một đỉnh ta có thể thăm quan được tất cả các đỉnh có liên hệ với nó.
Chúng ta không thể nào sử dụng vòng for
kiểu này:
for(Vertex vertex : graph.getVertexts()) {
// làm gì đó với vertex
}
Vì mỗi đỉnh lại có mối liên hệ với nào đó với các đỉnh còn lại, nếu dùng vòng for
kiểu này chúng ta sẽ bị lặp qua các đỉnh đã được duyệt rồi.
Mục tiêu ra đời
- Visitor ra đời nhằm giải quyết các hạn chế của iterator, nó giúp chúng ta không cần quan tâm đến điểm bắt đầu và điều kiện kết thúc, từ đó chúng ta sẽ chỉ cần tập trung vào xử lý nghiệp vụ mà thôi. Ví dụ với đồ thị, chúng ta có thể bắt đầu từ bất cứ điểm nào và tham quan cho đến khi nào hết các đỉnh có mối quan hệ thì thôi.
- Chúng ta cũng có thể tạo ra nhiều lớp visitor khác nhau và sử dụng chúng mà không làm thay đổi bất kì thông tin hay cấu trúc của lớp chứa dữ liệu. Ví dụ chúng ta có thể tạo ra các lớp visitor khác nhau để tham quan các đỉnh của đồ thị nhưng lớp đồ thị sẽ chẳng cần thay đổi gì cả.
Mô hình tiêu chuẩn
Mô hình tiêu chuẩn của một visitor design pattern bao gồm:
- Visitor: là interface cơ sở chưa hàm visit để thăm quan các phần tử.
- ConcreteVisitor: là các lớp cài đặt cụ thể tương ứng từng nghiệp vụ mà chúng ta muốn xử lý phần tử được thăm quan.
- ObjectStructure: là lớp chứa các phần tử cần được thăm quan.
- Element: là các phần tử được thăm quan
- Client: là lớp khởi tạo visitor và cung cấp cho lớp
ObjectStructure
Ví dụ
Quay trở lại với vi dụ đồ thị, chúng ta sẽ sử dụng visitor để thăm quan tấn cả các đỉnh, bắt đầu từ một đỉnh bất kì nhé. Trước hết, hãy thiết kế lớp một chút.
Sơ đồ lớp
Sơ đồ lớp bao gồm:
- Visitor: chức năng giống như trong mô hình tiêu chuẩn
- PrintVisistor: in ra các phần tử được thăm quan
- CacheVisitor: lưu lại thông tin các phần tử được thăm quan vào cache
- Graph: là lớp đại diện cho đồ thị
- Vertext: là lớp đại diện cho mỗi đỉnh của đồ thị
Cài đặt
Để bài viết không bị dài và nhàm chán, mình sẽ chỉ đưa một ít code vào đây, ví dụ đầy đủ, các bạn có thể tham khảo tại đây nhé.
Đầu tiên là visitor interface:
public interface Visitor<E> {
void visit(E element);
}
Sau đó là 2 lớp PrintVisitor
và CacheVisitor
:
public class PrintVisitor<K, V> implements Visitor<Vertex<K, V>> {
@Override
public void visit(Vertex<K, V> element) {
System.out.print(element + " => ");
}
}
public class CacheVisitor<K, V> implements Visitor<Vertex<K, V>> {
private final List<Vertex<K, V>> buffer = new LinkedList<>();
@Override
public void visit(Vertex<K, V> element) {
buffer.add(element);
}
}
Tiếp theo là lớp Graph
và hàm thăm quan tất cả các đỉnh của nó:
public class Graph<K, V> {
private final Map<K, Vertex<K, V>> vertexByKey;
// Các đỉnh và các mỗi liên kết
private final Map<Vertex<K, V>, List<Vertex<K, V>>> adjVertices;
public void depthFirstTraversal(K rootKey, Visitor<Vertex<K, V>> visitor) {
Stack<Vertex<K, V>> stack = new Stack<>();
Vertex<K, V> root = getRootByKey(rootKey);
if(root != null)
stack.add(root);
Set<K> visited = new HashSet<>();
while(stack.size() > 0) {
Vertex<K, V> vertex = stack.pop();
if(!visited.contains(vertex.key)) {
visited.add(vertex.key);
vertex.accept(visitor);
for(Vertex<K, V> v : adjVertices.get(vertex)) {
stack.push(v);
}
}
}
}
}
Cuối cùng, việc sử dụng sẽ chỉ đơn giản thế này:
Graph<String, Integer> graph = new Graph<>();
graph.addVertex("Bob", 1);
graph.addVertex("Alice", 2);
graph.addVertex("Mark", 3);
graph.addVertex("Rob", 4);
graph.addVertex("Maria", 5);
graph.addEdge("Bob", "Alice");
graph.addEdge("Bob", "Rob");
graph.addEdge("Alice", "Mark");
graph.addEdge("Rob", "Mark");
graph.addEdge("Alice", "Maria");
graph.addEdge("Rob", "Maria");
System.out.println(graph);
Visitor<Vertex<String, Integer>> printVisitor = new PrintVisitor<>();
graph.breadthFirstTraversal(printVisitor);
System.out.println();
Visitor<Vertex<String, Integer>> cacheVisitor = new CacheVisitor<>();
graph.depthFirstTraversal(cacheVisitor);
System.out.println(((CacheVisitor)cacheVisitor).getBuffer());
Tổng kết
Visitor là một trong những design pattern tương đối quan trọng để xử lý các cấu trúc dữ liệu phức tạp. Vòng for
nên phù hợp với những tập dữ liệu nhỏ và có điều kiện kết thúc cụ thể. Nhưng với visitor, chúng ta sẽ có khả năng xử lý được những tập dữ liệu lớn hơn rất nhiều như các database vẫn đang làm cho chúng ta. Hãy sử dụng nó khi bạn không muốn dùng hoặc không yêu thích vòng for
nhé.
-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Kinh nghiệm phát triển dự án phức tạp, nhiều người - Tuân thủ
- Kinh nghiệm phát triển dự án phức tạp, nhiều người - Lựa chọn người đi cùng
- Ngành công nghiệp phần mềm tại Việt Nam - Mới chỉ là bắt đầu.
- Ngành công nghiệp phần mềm tại Việt Nam - Dây chuyền sản xuất.
- Ngành công nghiệp phần mềm tại Việt Nam - Thị trường
- Ngành công nghiệp phần mềm tại Việt Nam - Công ăn việc làm
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local
- Tham gia phát triển open source!
- Buôn có bạn, bán có phường
- Đam mê đi đâu rồi?
- Giữa lửa đam mê!
- Tương lai nào cho tester? Thay đổi để dẫn đầu xu thế!
- Tương lai nào cho tester? - Khi thế sự đổi thay!
- Tương lai nào cho lập trình viên? Khi không có hệ quy chiếu!
- Tương lai nào cho lập trình viên - Làm đến bao nhiêu tuổi?
- Tương lai nào cho lập trình viên? Có làm giàu được không?
- Tương lai nào cho lập trình viên? Có cân bằng cuộc sống được không?
- Tương lai nào cho lập trình viên - Nhảy việc đến khi nào?
- Tương lai nào cho lập trình viên - Con đường sự nghiệp (Career path)!
- Tương lai nào cho lập trình viên - Tổng kết lại!
- Con đường sự nghiệp cho lập trình viên - Giai đoạn sơ cấp (Junior)!
- Con đường sự nghiệp cho lập trình viên - Giai đoạn trung cấp (Intermediate)!
- Con đường sự nghiệp cho lập trình viên - Giai đoạn lành nghề (Senior)!
- Giai đoạn lành nghề (Senior) - Giữa những hoang mang!
- Giai đoạn lành nghề (Senior) - Phân hoá trong doanh nghiệp!
- Con đường sự nghiệp cho lập trình viên - Trở thành chuyên gia (Expert)!
- Con đường sự nghiệp cho lập trình viên - Trở thành người ảnh hưởng (Influencer)!
- Các giai đoạn phát triển của lập trình viên - Tổng kết lại!
- Metaverse - Câu chuyện 10 nghìn CCU (Người tham gia đồng thời)
- Metaverse có khả thi ở Việt Nam?
- Lựa chọn nghề nghiệp - DevOps!
- Lựa chọn nghề nghiệp - Project Manager (PM)!
- Lựa chọn nghề nghiệp - Data Engineer!
- Lựa chọn nghề nghiệp - BackEnd Engineer!
- “Talk is cheap. Show me the code” ― Linus Torvalds
- Lựa chọn nghề nghiệp - Web Front-End Engineer!
- Lựa chọn nghề nghiệp - Mobile Engineer!
- Lựa chọn nghề nghiệp - Game Engineer!
- Lựa chọn nghề nghiệp - Product Owner!
- Tuổi trẻ cần đột phá!
- Tuổi trẻ cần sự đồng cảm!
- Tuổi trẻ - điều đáng sợ đầu tiên là gì?
- Tuổi trẻ - Điều đáng sợ thứ 2 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 3 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 4 là gì?
- Nếu tận dụng hết năng lực thì sẽ thế nào?
- Tuổi trẻ - Điều đáng sợ thứ 5 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 6 là gì?
- Tuổi trẻ - Điều đáng sợ thứ 7 là gì?
- Tuổi trẻ - ham học hỏi là như thế nào?
- Đầu tư cho bản thân là gì?
- Học chủ động!
- Có nên quay lại công ty cũ?
- Làm cho startup (công ty nhỏ) hay làm cho công ty lớn? (Phần 1)
- Làm cho startup (công ty nhỏ) hay làm cho công ty lớn? (Phần 2)
- Làm cho startup (công ty nhỏ) hay làm cho công ty lớn? (Phần 3)
- Tự học
- Học tập tại doanh nghiệp
- Học tại trung tâm
- Cách đọc sách kỹ thuật hiệu quả
- Học trong một tổ chức mã nguồn mở.
- Câu chuyện lập trình viên - Công việc đầu tiên
- Câu chuyện lập trình viên - Mức lương đầu tiên
- Câu chuyện lập trình viên - 2018
- Định hướng là gì?
- Wordpress nguy hiểm thế nào?
- Danh sách 10 trung tâm đào tạo trình uy tín, chất lượng ở Hà Nội