Gần đây tôi đã đọc rất nhiều về TDD và mã sạch nên tôi bắt đầu làm việc với một dự án đơn giản để sử dụng và tôi đã nghĩ ra điều gì đó mà tôi thực sự không biết cách tiếp cận tốt nhất là gì.Người gọi có nên kiểm tra tính hợp lệ của các đối số trước khi gọi hàm tạo không?
Tôi có một lớp có đối tượng Java File
làm tham số, mong đợi là đối tượng File
này phải là một thư mục và phải bắt đầu bằng một tiền tố nhất định. Lần đầu tiên tôi thực hiện việc kiểm tra đối tượng File
trước khi gọi hàm tạo, nghĩa là kiểm tra xem đó có phải là thư mục và kiểm tra xem tên có hợp lệ không. Nhưng tôi không thích rằng đó là người gọi đó là xác định những gì làm cho nó hợp lệ và đặc biệt là những gì tiền tố hợp lệ là, tôi nghĩ rằng logic này nên được đặt trong lớp chính nó.
Tôi có thể thực hiện việc kiểm tra này trong hàm khởi tạo và ném ngoại lệ nếu nó không hợp lệ, nhưng do bản chất của vấn đề, nếu tôi lặp qua danh sách File
s thì hoàn toàn mong đợi rằng một số người trong số họ đã thắng 't là' hợp lệ '(tức là chúng sẽ là các tập tin chứ không phải là thư mục) do đó, việc ném một số thực hiện bảo hành có thực sự là Exception
không?
public MyObject(File directory) {
if (!directory.isDirectory()) {
throw new IllegalArgumentException("Must be a directory");
}
if (!directory.getName().startsWith("Prefix")) {
throw new IllegalArgumentException("Must start with Prefix");
}
....
}
Tôi đã nghĩ về việc thêm phương thức Factory để tạo đối tượng và trả về null nếu File
không hợp lệ.
public static MyObject createMyObject(File directory) {
if (!directory.isDirectory() || !directory.getName().startsWith("Prefix")) {
return null;
}
return new MyObject(directory);
}
Ngoài ra tôi nghĩ về việc thêm một phương pháp tĩnh để các lớp đó xác nhận File cho người gọi trước khi gọi các nhà xây dựng.
public static boolean isValid(File directory) {
return directory.isDirectory() && directory.getName().startsWith("Prefix");
}
if (MyObject.isValid(directory)) {
MyObject object = new MyObject(directory);
}
Vì vậy, về mã sạch và tất cả nguyên tắc OOP (như trách nhiệm duy nhất, khớp nối, v.v.) sẽ là cách ưa thích để thực hiện việc này?
UPDATE:
Sau khi đọc một số câu trả lời đã được đăng lên đã Tôi bắt đầu suy nghĩ về một khả năng đó sẽ là chỉ áp dụng cho tình hình hiện tại của tôi chứ không phải quát như câu hỏi của tôi đã thực sự về.
Là một phần của mã gọi điện thoại, tôi có một đường dẫn từ hệ thống tệp và tôi liệt kê tất cả các tệp trong thư mục đó và đó là mỗi tệp mà tôi đang chuyển đến hàm tạo MyObject cho dù đó là hợp lệ hay không. Tôi có thể chuyển một FileFilter
đến phương thức listFiles
để đảm bảo rằng listFiles chỉ trả về các thư mục hợp lệ. Các FileFilter
có thể được công bố trong vòng MyObject:
public static FileFilter getFilter() {
return new FileFilter() {
public boolean accept(File path) {
return path.isDirectory() && path.getName().startsWith("Prefix");
}
};
}
Nếu constructor của tôi đã ném một ngoại lệ sau đó nó thực sự sẽ là một trường hợp ngoại lệ vì kỳ vọng là nó chỉ được thông qua danh bạ hợp lệ. Làm điều này có nghĩa là tôi có thể loại bỏ sự cần thiết cho một ngoại lệ được kiểm tra từ nhà xây dựng/nhà máy vì bất kỳ ngoại lệ nào sẽ chỉ ra lỗi ở đâu đó thay vì hành vi mong đợi. Nhưng nó vẫn để lại câu hỏi liệu có nên đặt nó trong một nhà xây dựng hay một phương pháp nhà máy.
Đối với tôi, thứ ba sẽ thích hợp hơn. Ngắn hơn và bạn có thể sử dụng nó với một số tệp. Ngoài ra, bạn không cần phải trả về một đối tượng mới từ phương thức isValid và bạn chỉ tạo đối tượng nếu isValid trả về true từ một phần khác của mã của bạn. Điều này là tốt vì nó tách các chức năng. –
@AliAlamiri Trong điều khoản của mã sạch đó là sở thích của tôi bởi vì đọc nó làm cho ý nghĩa nhất, nghĩa là nó là rõ ràng cho người đọc những gì đang xảy ra.Tôi chỉ không thể quyết định nếu tôi thích thực tế là người gọi phải biết rằng anh ấy nên gọi isValid trước. – DaveJohnston
Tại sao không truyền tệp cho hàm tạo và kiểm tra ở đó nếu tệp làValid. Điều này ẩn các kiểm tra từ người gọi khi bạn xây dựng các đối tượng và có các nhà xây dựng kiểm tra các tập tin được thông qua? –