[Design Patterns] Null Object

Null Object được sử dụng để thay thế cho phép kiểm tra một giá trị null có thể nhận xuất hiện. Một object Null được tạo ra để đại diện cho trường hợp vô nghĩa của một class thực thể và có thể được triển khai một số phương thức đáp ứng mặc định trong

Null Object được sử dụng để thay thế cho phép kiểm tra một giá trị null có thể nhận xuất hiện.
Một object Null được tạo ra để đại diện cho trường hợp vô nghĩa của một class thực thể
và có thể được triển khai một số phương thức đáp ứng mặc định trong trường hợp dữ liệu
truy vấn không khả dụng. Null Object được xếp vào nhóm các pattern Hành Vi.

Áp dụng triển khai

sơ đồ các class

Ở đây chúng ta có ví dụ mô tả về một đoạn xử lý yêu cầu đăng nhập từ người dùng.
Khi thông tin đăng nhập được gửi tới server, phần code main sẽ kết nối tới cơ sở dữ liệu
database để truy vấn tài khoản phù hợp. Nếu tập kết quả trả về sau khi truy vấn
bằng thông tin được cung cấp từ người dùng là một tập rỗng thì lệnh truy vấn sẽ trả
về một NullUser thay vì trả về giá trị null. Còn trong trường hợp có kết quả phù hợp
thì sẽ trả về một RealUser mô tả thực thể người dùng.

Bạn lưu ý là mặc dù NullUser cũng kế thừa từ AbstractUser giống như RealUser
nhưng không cần phải triển khai các phương thức với code đáp ứng tới giao diện người dùng
front-end. Phương thức quan trọng nhất là isNull() cần được chắc chắn triển khai
trên cả RealUserNullUser để sử dụng trong phép kiểm tra thay cho giá trị null
có khả năng xuất hiện. Các phương thức còn lại của NullUser có thể trả về null,
hoặcthrow Exception, hoặc in thông báo ra console để phục vụ debug và chạy thử.

Bước 1

Tạo AbstractUser để mô tả thực thể người dùng và tạo ràng buộc triển khai isNull()
cho các class kế thừa.

nullobject/AbstractUser.java

packagenullobject;publicabstractclassAbstractUser{protectedString username;protectedString password;publicabstractStringgetUsername();publicabstractvoidsetUsername(String username)throwsException;publicabstractStringgetPassword();publicabstractvoidsetPassword(String password)throwsException;publicabstractbooleanisNull();}

Bước 2

Tạo 2 class kế thừa AbstractUser:

  • RealUser để mô tả thực thể người dùng
  • NullUser để đại diện cho trường hợp kết quả truy vấn không khả dụng

nullobject/RealUser.java

packagenullobject;publicclassRealUserextendsAbstractUser{publicRealUser(String username,String password
   ){try{setUsername(username);setPassword(password);}catch(Exception e){
         e.printStackTrace();}}@OverridepublicStringgetUsername(){return username;}@OverridepublicvoidsetUsername(String username)throwsException{if(username ==null|| username.equalsIgnoreCase("")){thrownewException("Tên người dùng không hợp lệ");}else{this.username = username;}}@OverridepublicStringgetPassword(){return password;}@OverridepublicvoidsetPassword(String password)throwsException{if(password ==null|| password.equalsIgnoreCase("")){thrownewException("Mật khẩu không hợp lệ");}else{this.password = password;}}@OverridepublicbooleanisNull(){returnfalse;}}

nullobject/NullUser.java

packagenullobject;publicclassNullUserextendsAbstractUser{@OverridepublicStringgetUsername(){returnnull;}@OverridepublicvoidsetUsername(String username)throwsException{thrownewException("Phương thức chưa có code triển khai");}@OverridepublicStringgetPassword(){returnnull;}@OverridepublicvoidsetPassword(String password)throwsException{thrownewException("Phương thức chưa có code triển khai");}@OverridepublicbooleanisNull(){returntrue;}}

Bước 3

Viết code main để mô tả tiến trình xử lý yêu cầu đăng nhập.

PatternDemo.java

importnullobject.AbstractUser;importnullobject.NullUser;importnullobject.RealUser;importjava.util.ArrayList;importjava.util.List;publicclassPatternDemo{privatestaticList<AbstractUser> database =newArrayList<AbstractUser>();publicstaticvoidmain(String[] args){String inputUsername;String inputPassword;connectDatabase();//thử đăng nhập lần thứ nhấtSystem.out.println("==============");
      inputUsername ="someone";
      inputPassword ="qwerty123456789";userLogin(inputUsername, inputPassword);//thử đăng nhập lần thứ haiSystem.out.println("==============");
      inputUsername ="semiart";
      inputPassword ="123456789";userLogin(inputUsername, inputPassword);}privatestaticvoidconnectDatabase(){RealUser viblo =newRealUser("viblo","987654321");
      database.add(viblo);RealUser semiart =newRealUser("semiart","123456789");
      database.add(semiart);}privatestaticvoiduserLogin(String username,String password
   ){AbstractUser matched =queryUser(username, password);if(matched.isNull()){System.out.println("Thông tin đăng nhập không chính xác.");}else{System.out.println("Đăng nhập thành công!");System.out.println("Tên tài khoản: "+ matched.getUsername());}}privatestaticAbstractUserqueryUser(String username,String password
   ){List<AbstractUser> matchedUsers = database.stream()// filter lược bỏ những tài khoản không đúng với username// được cung cấp từ người dùng đang gửi yêu cầu đăng nhập.filter((user)-> user.getUsername().equals(username))// filter lược bỏ tiếp những tài khoản không đúng với password// được nhập vào bởi người dùng đang gửi yêu cầu đăng nhập.filter((user)-> user.getPassword().equals(password))// chuyển stream về lại giao diện List.toList();if(matchedUsers.isEmpty()){// nếu tập kết quả rỗng thì trả về một object NullreturnnewNullUser();}else{// nếu có kết quả phù hợp thì trả về phần tử duy nhấtreturn matchedUsers.get(0);}}}

Bước 4

Kiểm chứng lại kết quả được in ra ở console.

console

==============Thông tin đăng nhập không chính xác.==============
Đăng nhập thành công!Tên tài khoản: semiart

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ