2 Stimmen

Statische vs. Instanzmethode für gemeinsame Verwendung

Hier ist, was ich zu bestimmen versuche...

Ich habe eine Hilfsklasse zum Anhängen von Zeilen an eine Textdatei. Dies muss von einer Anzahl anderer Klassen verwendet werden, wie einer gemeinsamen Protokolldatei.

In meiner ersten Implementierung hatten alle Klassen, die es verwenden wollten, eine referenzlose Instanz erstellt, z. B.

new Logger(logline,logname);

Der Konstruktor erstellt einen PrintWriter, hängt die Zeile an und schließt die Datei.

Dies schien verschwenderisch zu sein, da bei jedem angehängten eine neue Instanz erstellt wird.

Die Alternative war die Verwendung einer statischen Methode namens "writeln" in dieser gemeinsamen Klasse, da ich verstanden hatte, dass statische Methoden und Daten den gleichen Speicher immer wieder verwenden... aber

Diese statische Methode erstellt eine Instanz von PrintWriter, um ihre Aufgabe zu erfüllen, bedeutet das also nicht, dass eine neue Instanz von PrintWriter für jede Zeile erstellt wird, wie bei #1?

Wie auch immer, (ich bin relativ neu in Java), gibt es einen bekannten, genehmigten Weg, dies zu tun, oder sollen wir einfach erstellen und den Garbage-Collector nach uns aufräumen lassen?

Danke

5voto

Chris Jester-Young Punkte 212385

Die vernünftige Antwort lautet, dass Sie ein "ernsthaftes" Logging-Paket verwenden sollten, wie zum Beispiel Commons Logging.

Um jedoch Ihre Frage zu beantworten, sollten Sie in diesem Fall eine statische Methode verwenden (es sei denn, Sie möchten Logging-Klasseninstanzen in Ihrem Code beibehalten, in welchem Fall Sie den anderen Antworten in diesem Thread folgen sollten). Darüber hinaus sollten Sie ein statisches Feld haben, das z. B. auf ein Map initialisiert ist. (Sie müssen nicht String als Schlüssel verwenden: Wenn Sie eine endliche Anzahl von Logging-Zieltypen wünschen, verwenden Sie ein enum.)

Dann, wenn Ihre Methode einen Schlüssel sieht, der noch nicht im map existiert, würde sie den PrintWriter auf der Stelle erstellen und ihn in die map einfügen. Sie möchten wahrscheinlich ConcurrentHashMap als den zugrunde liegenden Map-Typ verwenden, damit er threadsicher ist.

Sie müssen auch eine Möglichkeit bereitstellen, ein Logging-Ziel zu schließen (was auch den zugehörigen Eintrag aus der Map löscht).

Viel Glück!

3voto

Chad Grant Punkte 41992

Sie sollten keine Arbeit in Ihrem Konstruktor ausführen.

Konstruktoren dienen der Objekteinrichtung.

Sie sollten eine Log() Methode erstellen, um das eigentliche Protokollieren durchzuführen.

Logger l = new Logger();
l.Log(logline,logname);
l.Log(logline,logname);

oder Sie können das Logger-Objekt als Singleton einrichten.

Logger.getInstance().Log(logline,logname);

Singelton-Pattern in Java: http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html

2voto

Dan Breslau Punkte 11294

Es gibt mehrere Arten von Zuständen, die dieses Objekt möglicherweise halten möchte, insbesondere den PrintWriter. Wenn Ihre Logger-Klasse diese als Instanzdaten speichern würde, müsste die Methode zum Protokollieren eine Instanzmethode und keine statische Methode sein. Daher müssen Sie das Protokollieren von der Konstruktion trennen:

// Geben Sie nur den PrintWriter in den Konstruktor ein, nicht die Zeile, die protokolliert werden soll.
Logger myLogger = new Logger(dateiname);

...

// Protokollieren Sie eine Nachricht
myLogger.log("Dies ist eine Nachricht, die protokolliert werden soll.");

// Protokollieren Sie eine weitere Nachricht, einfach nur zum Spaß.
myLogger.log("das zeigt, dass myLogger wiederholt verwendet werden kann.");

Ich habe keine der Implementierungsdetails gezeigt, aber ich hoffe, dies reicht aus, um Ihnen den Einstieg zu erleichtern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X