- vừa được xem lúc

[Design Patterns] Null Object

0 0 9

Người đăng: Thịnh Trần

Theo Viblo Asia

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

package nullobject; public abstract class AbstractUser { protected String username; protected String password; public abstract String getUsername(); public abstract void setUsername(String username) throws Exception; public abstract String getPassword(); public abstract void setPassword(String password) throws Exception; public abstract boolean isNull();
}

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

package nullobject; public class RealUser
extends AbstractUser { public RealUser( String username, String password ) { try { setUsername(username); setPassword(password); } catch (Exception e) { e.printStackTrace(); } } @Override public String getUsername() { return username; } @Override public void setUsername(String username) throws Exception { if (username == null || username.equalsIgnoreCase("")) { throw new Exception("Tên người dùng không hợp lệ"); } else { this.username = username; } } @Override public String getPassword() { return password; } @Override public void setPassword(String password) throws Exception { if (password == null || password.equalsIgnoreCase("")) { throw new Exception("Mật khẩu không hợp lệ"); } else { this.password = password; } } @Override public boolean isNull() { return false; }
}

nullobject/NullUser.java

package nullobject; public class NullUser
extends AbstractUser { @Override public String getUsername() { return null; } @Override public void setUsername(String username) throws Exception { throw new Exception("Phương thức chưa có code triển khai"); } @Override public String getPassword() { return null; } @Override public void setPassword(String password) throws Exception { throw new Exception("Phương thức chưa có code triển khai"); } @Override public boolean isNull() { return true; }
}

Bước 3

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

PatternDemo.java

import nullobject.AbstractUser;
import nullobject.NullUser;
import nullobject.RealUser; import java.util.ArrayList;
import java.util.List; public class PatternDemo { private static List<AbstractUser> database = new ArrayList<AbstractUser>(); public static void main(String[] args) { String inputUsername; String inputPassword; connectDatabase(); //thử đăng nhập lần thứ nhất System.out.println("=============="); inputUsername = "someone"; inputPassword = "qwerty123456789"; userLogin(inputUsername, inputPassword); //thử đăng nhập lần thứ hai System.out.println("=============="); inputUsername = "semiart"; inputPassword = "123456789"; userLogin(inputUsername, inputPassword); } private static void connectDatabase() { RealUser viblo = new RealUser("viblo", "987654321"); database.add(viblo); RealUser semiart = new RealUser("semiart", "123456789"); database.add(semiart); } private static void userLogin( 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()); } } private static AbstractUser queryUser( 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 Null return new NullUser(); } else { // nếu có kết quả phù hợp thì trả về phần tử duy nhất return 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

Bình luận

Bài viết tương tự

- vừa được xem lúc

Closure trong Javascript - Phần 2: Định nghĩa và cách dùng

Các bạn có thể đọc qua phần 1 ở đây. Để mọi người không quên, mình xin tóm tắt gọn lại khái niệm lexical environment:.

0 0 51

- vừa được xem lúc

Var vs let vs const? Các cách khai báo biến và hằng trong Javascript

Dạo này mình tập tành học Javascript, thấy có 2 cách khai báo biến khác nhau nên đã tìm tòi sự khác biệt. Nay xin đăng lên đây để mọi người đọc xong hy vọng phân biệt được giữa let và var, và sau đó là khai báo hằng bằng const.

0 0 31

- vừa được xem lúc

VueJS: Tính năng Mixins

Chào mọi người, hôm nay mình sẽ viết về Mixins và 1 số vấn đề trong sử dụng Mixins hay ho mà mình gặp trong dự án thực. Trích dẫn từ trang chủ của VueJS:.

0 0 27

- vừa được xem lúc

Asset Pipeline là cái chi chi?

Asset Pipeline. Asset pipeline là cái chi chi. . Giải thích:.

0 0 47

- vừa được xem lúc

Tạo data table web app lấy dữ liệu từ Google Sheets sử dụng Apps Script

Google Sheets là công cụ tuyệt vời để lưu trữ bảng tính trực tuyến, bạn có thể truy cập bảng tính bất kỳ lúc nào ở bất kỳ đâu và luôn sẵn sàng để chia sẻ với người khác. Bài này gồm 2 phần.

0 0 266

- vừa được xem lúc

Học Deep Learning trên Coursera miễn phí

Bạn muốn bắt đầu với Deep Learning nhưng không biết bắt đầu từ đâu? Bạn muốn có một công việc ở mức fresher về Deep Learning? Bạn muốn khoe bạn bè về kiến thức Deep Learning của mình. Bắt đầu từ đâu.

0 0 35