-
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!
- 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
Né tránh lỗi tỉ đô
Null
là một giá trị đặc biệt trong lập trình, và mỗi ngôn ngữ lập trình lại có những cách đối xử khác nhau, với C/C++ có thể là crash luôn chương trình, với Java thì có thể ném ra NullPointerException
với javascript thì có thể là undefined
. Tuy là một giá trị đơn giản nhưng lại gây ra rất nhiều lỗi trên các sản phẩm của chúng ta mà có khi phải rất lâu mới bắt gặp và khi bắt gặp thì toàn gây thiệt hại rất lớn, nhẹ thì 1 chức năng không sử dụng được, nặng thì có thể làm tê liệt cả 1 dịch vụ. Vậy cần phải có 1 cách nào đó để chúng ta né tránh hoặc giảm thiểu được rủi ro đối với giá trị Null
này, đó là chính là lúc Null Object Design Pattern ra đời.
Bài toán thực tế
Có lẽ bài toán phổ biến nhất mà chúng ta vẫn thường làm đó là truy xuất data từ cơ sở dữ liệu kiểu thế này:
public User getUserById(long userId) {}
Vậy đối với trrường hợp chúng ta không tìm thấy dữ liệu thì phải làm thế nào? Trả về null và viết docs cho hàm đó, hay chúng ta sẽ làm gì để cho những người sử dụng hàm này không được phép quên xử lý trường hợp không tìm thấy dữ liệu?
Mục tiêu ra đời
Để trả lời những câu hỏi đó thì Null Object Design Pattern đã ra đời với mục tiêu:
- Đóng gói lại giá trị null, từ đó cố gắng gây sự chú ý cho các lập trình viên để xử lý các trường hợp không tìm thấy dữ liệu.
- Tạo ra các xử lý mặc định trong trường hợp dữ liệu bị null, như trả về giá trị mặc định hay nén ra exception.
Mô hình tiêu chuẩn
Là design pattern đơn giản nhất trong số các pattern nên mô hình tiêu chuẩn của null object cũng chẳng có gì đặc biệt.
- CompositeOperation: chứa các opration để xử lý dữ liệu trong trường hợp null và không null
- RealOperation: xử lý dữ liệu trong trường hợp không null
- NullOperation: xử lý dữ liệu trong trường hợp null
Ví dụ
Để giải quyết bài toán đã nói ở trên, chúng ta sẽ sử dụng đối tượng Optional
có sẵn kể từ java 8. Tuy nhiên hãy thiết kế sơ đồ lớp một chút cho dễ nhìn nhé.
Sơ đò lớp
Trong sơ đồ này thì:
- Optional sẽ đóng vai trò là 1 lớp wrapper, bao bọc lại kết quả, xử lý if else và gọi đến các opration tương ứng
- ToJsonOperation: biến đối tượng thành json string
- ToEmptyStringOperation: trong trường hợp dữ liệu bị null, sẽ trả về một chuỗi rỗng.
- UserFetcher: đóng vai trò là lớp sử dụng null object design pattern, nó sẽ lấy dữ liệu từ cơ sở dữ liệu và chuyển thành json và trả về cho người dùng.
Cài đặt
Trước tiên chúng ta sẽ cài đặt 2 lớp xử lý:
public class ToJsonOperation implements Function<User, String> {
@Override
public String apply(User t) {
return t.toJson();
}
}
public class ToEmptyStringOperation implements Supplier<String> {
@Override
public String get() {
return "";
}
}
Tiếp theo, việc sử dụng sẽ chỉ đơn giản thế này thôi:
String user1stJson = userFetcher
.getUserById(1L)
.map(new ToJsonOperation())
.orElseGet(new ToEmptyStringOperation());
System.out.println(user1stJson);
String user3rdJson = userFetcher
.getUserById(3L)
.map(new ToJsonOperation())
.get();
System.out.println(user3rdJson);
Source code đầy đủ, bạn có thể tham khảo tại Github của mình nhé.
Tổng kết
Về cơ bản thì null object design pattern là một cách thay thế cho việc if (null) then else
truyền thống. Tuy nhiên lợi ích to lớn của nó là khiến cho lập trình viên chú ý hơn đến việc xử lý trong trường hợp dữ liệu bị null này, hoặc nếu họ quên không xử lý thì sẽ có hành động mặc định được đưa ra để dễ dàng debug hơn trong quá trình chạy thực tế ví dụ như ném ra 1 exception với 1 message dễ hiểu chẳng hạn.
-
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!
- 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