Hậu quả khôn lường!

Đã bao nhiêu năm đi làm thì cũng là từng ấy năm phải đi tiếp nhận source code của người khác. Và thật khủng khiếp khi chúng ta nhận được yêu cầu của PM để cập nhật 1 tính năng đã có sẵn, và thế là cơn đau bắt đầu!

Trường hợp thực tế

Trong dự án #CRM nọ có 2 bạn dev không ưa nhau cho lắm, mỗi người làm việc của mình mà không ai bảo ai, 2 người làm 2 tính năng khác nhau: Bạn Dev A: làm tính năng đăng kí Bạn Dev B: làm tính năng login

Việc tranh cãi lựa chọn Spring hay JavaEE đã khiến cho dự án chậm deadline cả tuần và giờ đây các bạn vội vàng code như sau: Bạn Dev A:

public class RegisterController {
    public static final String USER_NAME_PATTERN = "[a-z]{36}";
    public void register(RegisterRequest request) {
        if(Pattern.compile(USER_NAME_PATTERN)
                  .matcher(request.getUsername()).matches()) {
            throw new IllegalArgumentException("invalid user");
        }
    }
}

Bạn Dev B:

public class LoginController {
    public static final String USER_NAME_PATTERN = "[a-z]{36}";
    public void login(LoginRequest request) {
        if(Pattern.compile(USER_NAME_PATTERN)
                  .matcher(request.getUsername()).matches()) {
            throw new IllegalArgumentException("invalid user");
        }
    }
}

Thương đau bắt đầu

Và rồi một ngày đẹp trời, cả 2 bạn Dev không chịu nổi nhau nữa và đồng loạt xin nghỉ việc, lúc này bạn C mới được tuyển vào và tiếp nhận source code của 2 bạn Dev A và B, sau 2 tháng thử việc thì PM quyết định giao cho bạn C update tính năng đăng kí, cho phép user đăng kí username cả chữ hoa và thường và số, và thảm họa bắt đầu. Với kinh nghiệm của mình bạn C nhanh chóng tìm ra lớp RegisterController để cập nhật như sau:

public class RegisterController {
    public static final String USER_NAME_PATTERN = "[a-zA-Z0-9]{36}";
    // register
}

Vì một lý do nào đó mà dự án không có QA, QC, nên bạn C đã test rất kỹ trên 2 môi trường BETA và RC và xin PM deploy lên PRO, mọi việc đều rất ổn, bạn C deploy lên PRO và thử đăng ký, PM cũng đăng ký thử thành công và có lời khen ngợi bạn C, nhưng ngay sau đó tất cả các khác hàng đăng kí mới không thể đăng nhập, cả công ty rối loạn, bạn C ngay lập tức phải rollback lại phiên bản cũ và đi tìm hiểu nguyên nhân, hóa ra bạn C chưa cập nhật lớp LoginController.

Thay đổi một chút

Chúng ta có thể code RegisterController và LoginController như sau:

public class UserValidator {
    public static final String USER_NAME_PATTERN = "[a-zA-Z0-9]{36}";
    public void validateUsername(String username) {
        if(Pattern.compile(USER_NAME_PATTERN).matcher(username).matches()) {
            throw new IllegalArgumentException("invalid user");
        }
    }
}
public class RegisterController {
    private UserValidator userValidator;
    public void register(RegisterRequest request) {
        userValidator.validateUsername(request.getUsername());
    }
}
public class LoginController {
    private UserValidator userValidator;
    public void login(LoginRequest request) {
        userValidator.validateUsername(request.getUsername());
    }
}

Tổng kết

Các bạn có thể thấy mặc dù chỉ là 1 dòng code nhưng nó ảnh hưởng đến cả 1 hệ thống, 1 công ty với bao nhiêu nhân viên và khách hàng, vậy nên đừng bao giờ duplicate source code nhé, hay luôn nâng cao năng lực để common được source code của mình nhé