Hm…
Trong TH cậu cần cài đặt i18n, cậu nên dùng 1 component riêng để switch giữa các message lỗi giữa các ngôn ngữ.
Nó có thể trông thế này khi cậu throw ra lỗi:
// Error message in English: "You got busted!"
throw new WrongEmailException(i18n.getMessage("error.wrong_email", currentLanguage);
Ở file properties nào đó:
# language-en.properties file
error.wrong_email=You got busted!
# language-jp.properties file
error.wrong_email=ごめんね!
Hoặc thậm chí, cậu có thể convert message ở thời điểm catch exception, chẳng hạn:
throw new WrongEmailException("error.wrong-email");
// in a exception handler class, quite popular in spring
@ExceptionHandler(WrongEmaiException.class)
// return HTTP 400
public Response handleWrongEmail(WrongEmailException ex) {
Response response = new Response();
response.setMessage(i18n.getMessage(ex.getMessage(), currentLanguage);
return response;
}
Dù cách này cũng không hẳn là flexible, vì có lúc cậu không muốn logic chuyển đổi message được thực hiện.
Load từ database cũng là một cách để cài đặt, nếu như cậu có quá nhiều message và ngôn ngữ.
Hay là mình dùng cách này:
- Tạo nhiều class custom cho từng loại exception.
- Hàm
checkLogin
sẽ throw ra một trong những class exception đó.
- Hàm nào thực thi lời gọi hàm đến
checkLogin
sẽ instanceof
để phân loại lỗi ra.
Dùng instanceof
trong TH của cậu không phải là cách tốt khi cậu code OOP đâu.
Về cơ bản, nếu cậu phải dùng instanceof để phân loại hành vi và đưa ra action phù hợp với từng class, cậu hoàn toàn có thể dùng đa hình để làm việc đó nếu cậu sử dụng OOP.
Cậu cũng hoàn toàn có thể catch từng loại exception và thực thi hành động phù hợp. Tuy nhiên, trong TH i18n, cậu có thể thấy các hành động này đều giống nhau (chỉ là hiển thị message phụ thuộc vào ngôn ngữ thôi).
Trong code mà cậu đưa ra, có 1 vài vấn đề:
- Exception không nên chứa logic và dữ liệu. Cậu có logic load dữ liệu vào exception từ DB, và toàn bộ dữ liệu liên quan tới message dưới các ngôn ngữ khác nhau ở constructor. Điều này không nên vì:
- Exception không nên quan tâm tới việc chuyển đổi ngôn ngữ diễn ra như thế nào.
- Exception không nên quan tâm tới việc lấy dữ liệu ngôn ngữ như thế nào.
- Cậu sẽ không thể thay nội dung của message ở từng nơi khác nhau một cách flexible. Hay nói cách khác, exception của cậu bị coupling với message mất rồi.
Có thể, tại 1 logic, cậu chỉ cần thông báo email định dạng sai, nhưng ở 1 logic khác, cậu cần mắng người dùng (ví dụ thôi nha, đừng làm thế trên production).
- Load dữ liệu ở constructor đồng nghĩa với việc mỗi lần khởi tạo object, cậu lại gọi tới DB => thao tác này đắt đỏ và không cần thiết mọi lúc, nhất là khi cậu không thường xuyên thay đổi thông điệp lỗi.
Dữ liệu này nên được cache lại ở app của cậu.
- Tớ đoán cậu có thể catch loại exception thay vì dùng instanceof để check chứ?
Như tớ đề cập ở trên, cậu nên có 1 component i18n riêng để xử lý.
Hope it helps!