2013-04-15 24 views
7

Tôi muốn hợp nhất các thông báo lỗi và nội dung của mình thành một tệp và làm cho mã của tôi dễ đọc hơn nếu có thể.Sử dụng liệt kê để đại diện cho các thông báo lỗi một cách hợp pháp - đó có phải là thực hành tốt không?

Dưới đây là một ví dụ về những gì tôi có trong tập tin enum của tôi:

public enum ZipErrorType { 

// START: define exception messages (alphabetical order) 
EMPTY_FILE_NAME_IN_LIST { 
    public String toString() { 
     return "One or more null/empty filename(s) found"; 
    } 
}, 

FILE_DOESNT_EXIST { 
    public String who(String sThisFile) { 
     return "[" + sThisFile + "] does not exist"; 
    } 
}, 

FILE_LIST_IS_NULL { 
    public String toString() { 
     return "File list is null/empty"; 
    } 
}, 

FILENAME_NOT_ABSOLUTE { 
    public String who(String sThisFile) { 
     return "[" + sThisFile + "] is not absolute"; 
    } 
}, 

MUST_BE_DIR { 
    public String who(String sThisFile) { 
     return "[" + sThisFile + "] must be a directory"; 
    } 
}, 

MUST_BE_FILE { 
    public String who(String sThisFile) { 
     return "[" + sThisFile + "] must be a file"; 
    } 
}, 

NULL_OR_EMPTY { 
    public String who(String sThisFile) { 
     return "[" + sThisFile + "] is null/empty"; 
    } 
}, 

OUTPUT_FILE_ALREADY_EXISTS { 
    public String who(String sThisFile) { 
     return "[" + sThisFile + "] already exists"; 
    } 
}, 

OUTPUT_FILENAME_EMPTY { 
    public String toString() { 
     return "Output filename is null/empty"; 
    } 
}, 

OUTPUT_PATH_EMPTY { 
    public String toString() { 
     return "Output path is null/empty"; 
    } 
}, 
// END: define exception messages 

NONE {}; 

public String who(String sThisFile) { return ""; } 
} 

Sau đó, trong chương trình của tôi, tôi có mã như:

private static ZipErrorType getFileErrorsIfAny(String sFilename, boolean shouldBeFile) { 

    // check if given filename is absolute 
    File file = new File(sFilename); 
    if (!file.isAbsolute()) { 
     return ZipErrorType.FILENAME_NOT_ABSOLUTE; 
    } 

    // check if file exists 
    if (!file.exists()) { 
     return ZipErrorType.FILE_DOESNT_EXIST; 
    } 

    // check if corresponding file is a file when it shouldn't be... 
    if (file.isFile() && !shouldBeFile) { 
     return ZipErrorType.MUST_BE_DIR; 
    } 
    // ...or a directory when it should be a file 
    else if (file.isDirectory() && shouldBeFile) { 
     return ZipErrorType.MUST_BE_FILE; 
    } 

    return ZipErrorType.NONE; 
} 

... và một ví dụ về làm thế nào tôi sử dụng của enum của tôi:

// check input files 
    for (String sFile : files) { 
     if (sFile == null || sFile.trim().length() == 0) { 
      throw new NullPointerException("One or more filename is null/empty"); 
     } 

     errorIfAny = getFileErrorsIfAny(sFile.trim(), true); 
     if (!errorIfAny.equals(ZipErrorType.NONE)) { 
      throw new ZipInputException(errorIfAny.who(sFile.trim())); 
     } 
    } 

Bây giờ tôi biết rất khó để đánh giá chỉ bằng những đoạn mã này một mình, nhưng điều này có ổn không, từ một địa lý quan điểm neral? Là những gì tôi đang làm không có giá trị rắc rối, và có cách nào để cải thiện điều này?

+0

Cân nhắc đăng câu hỏi này lên http://codereview.stackexchange.com/. Có vẻ như bạn không có bất kỳ vấn đề hoặc câu hỏi nào, nhưng chỉ cần xem xét ngang hàng. – mthmulders

+0

Tôi không chắc liệu nó có tốt hơn hay không, nhưng trong dự án hiện tại của chúng tôi, chúng tôi đang sử dụng enums theo cùng một cách ... nhưng Chuỗi được trả về bởi mỗi một chỉ là một mã định danh được sử dụng cho i18n –

Trả lời

4

Tôi khuyên bạn nên sử dụng các mẫu chuỗi đơn giản thay vì enums để tạo thông báo lỗi. Something như thế này:

String EMPTY_FILE_NAME_IN_LIST_TEMPLATE = "One or more null/empty filename(s) found"; 
String FILE_DOESNT_EXIST_TEMPLATE = "[ %s ] does not exist"; 
String FILE_LIST_IS_NULL_TEMPLATE = "File list is null/empty"; 
String FILENAME_NOT_ABSOLUTE_TEMPLATE = "[ %s ] is not absolute"; 
String MUST_BE_DIR_TEMPLATE = "[ %s ] must be a directory"; 
String MUST_BE_FILE_TEMPLATE = "[ %s ] must be a file"; 
String NULL_OR_EMPTY_TEMPLATE = "[ %s ] is null/empty"; 
String OUTPUT_FILE_ALREADY_EXISTS_TEMPLATE = "[ %s ] already exists"; 
String OUTPUT_FILENAME_EMPTY_TEMPLATE = "Output filename is null/empty"; 
String OUTPUT_PATH_EMPTY_TEMPLATE = "Output path is null/empty"; 

Và sau đó, sử dụng String.format(template, sFilename) cho việc xây dựng thông điệp thực tế.

Bạn cũng có thể xem xét ném một ngoại lệ ngay trên getFileErrorsIfAny() phương pháp:

File file = new File(sFilename); 
if (!file.isAbsolute()) { 
    throw new ZipInputException(String.format(FILENAME_NOT_ABSOLUTE_TEMPLATE, sFilename)); 
} 

Trông sạch hơn và nhỏ gọn hơn với tôi.

+0

Câu trả lời hay nhất, +1. Giữ nó lên! Bất cứ thứ gì sạch hơn là 'enum' ... –

1

Điều này dường như có khả năng dẫn đến nhiều số lượng lớn enum s rải rác xung quanh mã.

Đây không phải là lần đầu tiên một người nào đó muốn tách thông điệp tường trình khỏi bản ghi nhật ký.

Thực tế, java.util.logging đã có framework for this được thiết kế để bản địa hóa.

Sử dụng tệp .properties chứa thư.
Bạn nhận được các logger với đường dẫn đến tập tin trong classpath: -

Logger logger = Logger.getLogger("com.example", "path/to/messages.properties"); 

báo cáo Logging này sau đó được thực hiện bằng cách sử dụng phím sở hữu

logger.log(level, "messageKey"); 

Và bạn có thể parameterise logging vì nó sử dụng MessageFormat cú pháp

zip.fileDoesNotExist={0} does not exist 

logger.log(level, "zip.fileDoesNotExist", file); 

Các thông số này cực kỳ linh hoạt như bạn có thể chỉ định thông tin định dạng trong và thậm chí sử dụng ChoiceFormat nếu cần.

Ưu điểm chính của tất cả điều này là thư của bạn nằm trong một tệp riêng biệt, chứ không phải là class. bạn có thể bật và tắt ghi nhật ký theo ý muốn với tệp logging.properties. Bạn thậm chí có thể bật và tắt đăng nhập cho các lớp đơn lẻ. bạn có thể đăng nhập vào nhiều tệp, vào bảng điều khiển, bạn có thể gửi email về lỗi, v.v.

Vì vậy, kết luận. Sử dụng khung ghi nhật ký hiện có. Đừng cuộn của riêng bạn.

Tuyên bố từ chối trách nhiệm: Tôi chỉ nói về JUL vì sau đó được tích hợp vào Java - bạn không cần bất kỳ thư viện nào của bên thứ ba, có rất nhiều khung công tác khác.