2013-04-15 5 views
7

Ich möchte meine Fehlermeldungen und Zeug in einer Datei zusammenführen, und meinen Code wenn möglich lesbarer machen.Verwenden der Aufzählung, um Fehlermeldungen lesbar darzustellen - ist es eine gute Übung?

Hier ist ein Beispiel dessen, was ich in meiner Enum-Datei:

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 ""; } 
} 

Dann in meinem Programm habe ich Code wie:

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; 
} 

... und ein Beispiel dafür, wie ich Gebrauch machen meine enum:

// 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())); 
     } 
    } 

Jetzt weiß ich, es ist schwer, allein nur durch diesen Code-Schnipsel zu beurteilen, aber das ist in Ordnung, aus einem ge Nerale Perspektive? Ist das, was ich tue, nicht die Mühe wert, und gibt es einen Weg, dies zu verbessern?

+0

Stellen Sie diese Frage unter http://codereview.stackexchange.com/. Es scheint, dass Sie keine Probleme oder Fragen haben, aber nur Peer-Review benötigen. – mthmulders

+0

Ich bin nicht sicher, ob es besser ist oder nicht, aber in meinem aktuellen Projekt verwenden wir Enums auf die gleiche Weise ... aber die von jedem zurückgegebene Zeichenfolge ist nur eine Kennung für i18n –

Antwort

4

Ich würde vorschlagen, einfaches Zeichenketten-Templates statt Aufzählungen für den Aufbau von Fehlermeldungen verwendet wird. Etwas wie folgt aus:

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"; 

Und dann verwenden String.format(template, sFilename) für die eigentliche Nachricht zu bauen.

Sie können sie auch eine Ausnahme direkt aus getFileErrorsIfAny() Methode zu werfen:

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

Sehen saubere und kompakter zu mir.

+0

Schöne erste Antwort, +1. Mach weiter! Alles ist sauberer als ein 'enum' ... –

1

Dies scheint das Potenzial zu haben, in vielen, vielen massiven enum s um den Code punktiert zu führen.

Dies ist nicht das erste Mal, wenn jemand trennen von der Log-Nachricht aus der Log-Anweisung gewünscht hat.

Tatsächlich hat java.util.logging bereits eine framework for this, die für die Lokalisierung konzipiert ist.

Es verwendet eine .properties Datei, die die Nachrichten enthält.
Sie erhalten den Logger mit dem Pfad zur Datei im Classpath: -

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

Logging-Anweisungen

logger.log(level, "messageKey"); 

die Eigenschaftsschlüssel dann geschieht mit Hilfe Und Sie können die Protokollierung parametrisieren, weil es MessageFormat verwendet Syntax

zip.fileDoesNotExist={0} does not exist 

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

Diese Parameter sind sehr flexibel, da Sie Formatierungsinformationen angeben können sie und sogar ChoiceFormat verwenden, wenn nötig.

Der Hauptvorteil von all dem ist, dass Ihre Nachrichten in einer separaten Datei sind, sondern als ein class. Und können Sie mit der Datei logging.properties einloggen und abschalten. Sie können das An- und Abmelden sogar für einzelne Klassen aktivieren. Und können Sie auf mehrere Dateien, auf der Konsole, können Sie E-Mails bei Fehlern usw. usw.

Also abschließend. Verwenden Sie ein vorhandenes Protokollierungsframework. Rollen Sie nicht Ihre eigenen.

Haftungsausschluss: Ich habe nur über Juli sprechen, weil dann in Java gebaut - Sie brauchen keine 3rd-Party-Libs, gibt es viele, aus vielen anderen Frameworks gibt.

Verwandte Themen