Fine-grain refactoring deep dive (5) – Implement constants.

1. Issue Thông thường trong quá trình phát triển phần mềm, một trong những việc gần như luôn phải có đó chính là implement constants để có thể dùng được ở nhiều nơi khác nhau khắp hệ thống đơn cử như đoạn code sau: public interface FieldConst { String ID = "_id"; String NAME =

1. Issue

Thông thường trong quá trình phát triển phần mềm, một trong những việc gần như luôn phải có đó chính là implement constants để có thể dùng được ở nhiều nơi khác nhau khắp hệ thống đơn cử như đoạn code sau:

public interface FieldConst {
	String ID = "_id";
	String NAME = "name";
}

Việc implement constants thì sẽ có nhiều cách làm, ở đây chúng ta sẽ không cố gắng để tìm BEST PRATICE mà chỉ tìm GOOD PRACTICE mà thôi. Và trước khi đến với GOOD PRACTICE thì chúng ta phải hiểu tại sao đoạn code trên tại là BAD PRACTICE.
Ở dòng đầu tiên định nghĩa một interface dành cho việc khai báo constants, việc này có lợi thế là khi khai báo thì code trở nên gọn gàng khi không phải viết public static final ở trước data type bởi vì interface không thể khởi tạo instance được. Nghe có vẻ khá ổn, tuy nhiên hãy cùng xem lại định nghĩa thế nào là một interface và nó dùng để giải quyết vấn đề gì:

An interface in the Java programming language is an abstract type that is used to specify a behavior that classes must implement. [1]https://en.wikipedia.org/wiki/Interface_(Java)

Interface trong ngôn ngữ lập trình Java là một kiểu trừu tượng dùng để chỉ định một(?) hành vi mà các class phải thực hiện.

Bạn có thể thấy, đoạn code trên là sự lạm dụng interface cho một mục đích sai lệch hoàn toàn với ý nghĩa ban đầu của nó. Mặc dù vẫn hoạt động ổn, nhưng cách thiết kế như vậy là không tốt, nên tránh.

2. Solution

Ngoài sử dụng interface chúng ta có hai hướng tiếp cận chính:

  1. Standalone enum
  2. Standalone class

Vì enum sinh ra để giải quyết bài toán necessary of a fixed set of constants nên có thể nói là lựa chọn hàng đầu để implement constants (bạn có thể xem thêm về cách thiết kế enum ở bài trước) tuy nhiên khi truy cập thuộc tính của enum lại hơi rườm rà thông qua getter/setter nên mình sẽ giới thiệu với các bạn cách tiếp cận thứ hai thông qua standalone class.
Trước khi đi vào thiết kế thì chúng ta cùng điểm qua các requirement cần phải đạt trước đã:

  1. Class must be read-only.
  2. Class must be accessible anywhere.
  3. Class must not allow extend.

Và cuối cùng chúng ta có một final class với private constructor như sau:

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class FieldConst {
	public static final String ID = "_id";
    public static final String NAME = "name";
}

Cảm ơn mọi người đã đọc bài. Happy coding! 😍😆

References:

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 đầ