YAGNI, DRY là gì? (Nguyên tắc YAGNI, DRY trong Java)
Cũng giống như KISS, YAGNI và DRY là 2 nguyên tắc quan trọng để lập trình.
1. DRY
DRY: “Don’t Repeat Yourself” – Đừng bao giờ lặp lại code.
Bạn cũng có thể đã nghe về sự so sánh: DRY cod vs WET code (Don’t Repeat Yourself and Write Everything Twice)
Bạn đã bao giờ viết các đoạn code giống nhau nằm ở các phần, module khác nhau của project? bạn đã bao giờ có 2 màn hình giống nhau nhưng lại dùng tới 2 đoạn code để hiển thị 2 màn hình đó?
OK, Nguyên tắc DRY chính là đang nói về vấn đề này.
Đừng lặp lại code ở đây là không lặp lại các đoạn code giống nhau, các method thực hiện chức năng như nhau, cố gắng gom chúng lại 1 cách gọn gàng và có thể dùng lại khi cần.
Ví dụ 1
Ta có 2 method
public void print(User user) { System.out.println("first name: "+user.getFirstName()); System.out.println("last name: "+user.getLastName()); System.out.println("age: "+user.getAge()); System.out.println("email: "+user.getEmail()); System.out.println("address: "+user.getAddress()); System.out.println("gender: "+user.getGender()); System.out.println("exprience: "+user.getExperience()); // do something: print user info } public void preview(User user) { System.out.println("first name: "+user.getFirstName()); System.out.println("last name: "+user.getLastName()); System.out.println("age: "+user.getAge()); System.out.println("email: "+user.getEmail()); System.out.println("address: "+user.getAddress()); System.out.println("gender: "+user.getGender()); System.out.println("exprience: "+user.getExperience()); // do something: review user }
2 method trên thực hiện 2 chức năng khác nhau nhưng có rất nhiều code bị lặp lại, đây là case bị lặp code cơ bản ít người mắc phải. Ta có thể tránh lặp code trường hợp này bằng cách tách phần in thông tin user ra thành 1 method và gọi tới nó:
public void showUser(User user) { System.out.println("first name: "+user.getFirstName()); System.out.println("last name: "+user.getLastName()); System.out.println("age: "+user.getAge()); System.out.println("email: "+user.getEmail()); System.out.println("address: "+user.getAddress()); System.out.println("gender: "+user.getGender()); System.out.println("exprience: "+user.getExperience()); } public void print(User user) { showUser(user); // do something: print user info } public void preview(User user) { showUser(user); // do something: review user }
Sau khi tách ra method showUser thì ta có thể dùng lại nó hoặc nếu cần chỉnh sửa, lỗi trong việc in ra thông tin user thì ta chỉ cần sửa method showUser là được.
Ví dụ 2
Dưới đây là 1 đoạn code thực hiện tìm kiếm đối tượng User theo name, email, theo cả name và email
public List<User> findByName(String name) { if (name == null) { return null; } String sql = "SELECT u FROM User u WHERE u.name like %"+name+"% "; // do something } public List<User> findByEmail(String email) { if (email == null) { return null; } String sql = "SELECT u FROM User u WHERE u.email like %"+email+"% "; // do something } public List<User> findByNameAndEmail(String name, String email) { if (name == null || email == null) { return null; } String sql = "SELECT u FROM User u WHERE u.name like %"+name+"% AND u.email like %"+email+"%"; // do something }
Cái gì thế này? có vẻ như cả 3 method này đều thực hiện một việc khá giống nhau.
Sao không chuyển thành hàm dưới dây:
public List<User> find(String name, String email) { if (name == null && email == null) { return null; } String sql = "SELECT u FROM User u WHERE u.name like %"+name+"% AND u.email like %"+email+"%"; if (name != null && email == null) { sql = "SELECT u FROM User u WHERE u.name like %"+name+"% "; } if (name == null && email != null) { sql = "SELECT u FROM User u WHERE u.email like %"+email+"% "; } // do something }
Ngắn gọn hơn đúng không, lại vừa có thể search theo name, theo email và theo cả 2.
Vậy là việc suy tính trước method của mình sẽ làm gì sẽ giúp bạn trành việc lặp code, phải viết thêm method mới.
(Chú ý, giả sử bạn có method findByName, bây giờ cần thêm method search theo email thì phải giữ nguyên method findByName và viết mới method find chứ không được xóa method cũ đi nếu không nó sẽ vi phạm nguyên tắc “open for extension but closed for modification” tức là ưu tiên thêm mới và hạn chế sửa đổi).
2. YAGNI
YAGNI: “You Aren’t Gonna Need It”: Bạn không cần nó.
Đôi khi bạn nghĩ rằng cần phải thêm 1 số chức năng mới, bạn nghĩ nó cần thiết, có thể sẽ dùng trong tương lai và bạn làm nó. Stop, hãy dừng lại, như thế là bạn đang phạm phải sai lầm.
Bạn không nên lãng phí thời gian vì hành động đó, cái chức năng mà bạn thêm mới đó có thể không làm ưng ý khách hàng hoặc cấp trên, thậm chí không bao giờ được dùng tới. Hãy confirm nó trước khi làm, và tập trung vào các task hiện tại thay vì đi làm 1 cái mới mà chưa chắc đã dùng tới rồi lại phải mất thêm công test nó.
YAGNI, DRY là gì? (Nguyên tắc YAGNI, DRY trong Java) stackjava.com
Okay, Done!
References: https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it