Best Practice Properties oder Preferences ?

kaoZ

Top Contributor
Wie der title schon sagt stehe ich mal wieder von der Qual der Wahl,

ich befinde mich in folgender Sitation :

Ich habe eine Abstrakte Klasse angelegt welche ein Dokument Darstellt, diese Klasse erbt von JPanel, da es die Basisfunktionen / Attribute für zwei Subklassen bereitstellt.

nun ist mein Problem recht einfach zu beschreiben, meine Anwendung besitzt einen Zentralen Controller welcher die Gui initialisiert und anzeigt, dieser wiederum hält eine Referenz auf ein Preferences Objekt, welches (bis jetzt) lediglich die Informationen über den ExtendedState der Gui beinhaltet.

Nun möchte ich an folgender Stelle , das beim anlegen einer neuen Rechnung ( Spezialisierung eines Dokumentes ) , dementsprechend ein Counter inkrementiert wird ( welcher die bereits erstellten Rechnungen zählt ) und der (logischerweise) über den Anwendungszyklus hinaus persistent irgendwo gespeichert bleiben muss.

Hier hab ich natürlich mehrere Optionen, meine Frage ist nun , was ist der gängige Weg :

greife ich statisch auf das Preferences Objekt zu und hole mir die Werte ?

ungefähr so :
Java:
private void init(){
	id = ApplicationController.PREFS.getInt("invoiceID", 0);
	title = ApplicationController.PREFS.get("invoiceTitle", "default");			
	date = new Date();
	valueObject.add(title, date);
}

und halte dann ALLE Informationen zu meiner Anwendung in EINEM Preferences Objekt?
oder lege ich für die verschiedenen Dokument Typen eigene Preferences an ?

oder nutze ich Properties und erstelle einfach (irgendwo) eine Datei die dann die Daten für den jeweiligen Document typ hält und die ich dann bei jedem anlegen eines Dokumentes einlese, und ( z.B ) bei jedem Drucken oder speichern der Dokumentes überschreibe ?

Wie würdet ihr vorgehen ? Was ist da die gängige Praxis? Vielleicht ein doch völlig anderer Weg ?

EDIT :

oder sollte ich vielleicht eine Properties Datei anlegen welche alle informationen beim ersten Start in die Registry also in ein Preferences Objekt schreibt und dieses dann der gesamten Applikation zugänglich machen ?

das klingt zumindest schon ziemlich gut 😉


so müsste ich mich dann auch nicht immer um das parsing kümmern wenn man ein anderer Datentyp als String erwartet wird, da dies ja dann schon über das Preferences Objekt durch die verschiedenen getter erledigt wird.


oder prüfe ich vor Applikationsstart einfach ob z.B eine ersteinrichtung erfolgt ist , und wenn nicht schreibe ich die Werte direkt in das Preferences Objekt ? sollte ich diese Werte dann ggf. in einer Properties Datei halten anstatt hardcoded im Source Code zu halten ?

quasi solch ein ähnliches konstrukt:

Java:
public static void main(String[] args){
	if(!PREFS.getBoolean("setupFinished", false)) {
		PREFS.put("title", "Rechnungs Editor");
		PREFS.put("dev", "kaoZ");
		
		JOptionPane.showMessageDialog(null, "Sie müssen erst das Setup ausführen !");
	}
	else{
			
		new ApplicationController().startApplication();
        }

}

Erleuchtet mich :idea:
 
Zuletzt bearbeitet:
Zunächst müßte man mal wissen was du mit dem Counter eigentlich anstellen willst? Eine statische Klasse zu machen ist immer die letzte Wahl. Ich weiß ja nicht was Deine Software kann aber wenn sie zum Beispiel in der Lage ist mehrere Rechnungen gleichzeitig in verschiedenen Frames anzuzeigen, dann könnte es ja durchaus sein, dass mehrere Threads gleichzeitig an diesem Counter Änderungen machen. Das wäre bei einer statischen Klasse der SuperGAU.

Wenn man es streng nimmt, solllte es eigentlich einen Rechungen-Controller geben, der alle Rechnungen bearbeitet und die UI's dazu verwaltet. Dieser sollte dann als einziger auf den Counter zugreifen. Dann brauchst du die Daten nur beim Initialisieren dieses Controllers laden und bei belieben speichern.

Gruß

Claus
 
Der Counter zählt an und für sich nur die erstellten Dokumente, für jede Spezialisierung gibt es eine eigene ID sozusagen,

Sprich werden jetzt 4 Rechnungen geschrieben ist der Counter logischerweise bei 4, wird nun die Anwendung geschlossen , muss logischerweise der counter bei erneutesm Programmstart wieder bei 4 beginnen und nicht bei 0 , demnach muss ich ja diese Information irgendwo perisistent speichern,
wenn ich einen Conroller schreibe , welcher die UI's verwaltet, ist das schon eine guten idee, jedes Dokument hält aber eine Referenz auf ein Valueobjekt, welches als Modell dient, dort ist wiederum unter anderem auch die aktuelle ID hinterlegt,

normalerweise müsste ich ja nun , insofern ich z.B das Dokument speicher, oder drucke , diese gesamten Daten , inclusive des VO's ja persistent speichern, und gleichzeitig in meiner applikation ja irgendwo hinterlegen wieviel Dokumente bereits erstellt wurden, sprich entweder Preferences oder Properties , die beim erneutem start wieder eingelesen werde.

Dies betrifft ebenso die ganzen Grundlegenden Information, wie z.B kontaktdaten , Entwickler, Versionsnummer, die ich ja ebenfalls der Applikation irgendwie zur verfügung stellen muss

Da war halt meine Idee, eine Textdatei im BuildPath anzulegen , daraus eine Properties Objekt zu machen und aus diesem dann die Werte in das Preferences Objekt zu schreiben.

sprich :

Code:
title = "Editor"
dev = "kaoz"
version = 1.0a

daraus dann das Properties Objekt erstellen :

Java:
Properties props = new Properties();
try{
   props.load(getClass().getResourceAsStream("/properties/app.props");
}
catch(IOException e){
   e.printStackTrace();
}

und dann das ganze in ein Preferences Objekt screiben

Java:
static Preferences PREFS = Preferences.userNodeForPackage(ApplicationController.class);

PREFS.put("title", props.getProperty("title");

so muss ich nicht hardcoded im Source code hinterlegen.

ähnlich wollte ich es halt mit dem Counter für die Dokumente machen,
diese könnte ich ja ebenfalls einfach beim speichern oder schließen der Anwendung in die Preferences schreiben, und beim erneuten starten einfach wieder einlesen.
 
Zuletzt bearbeitet:
Ganz blöde Frage aber ist so ein Counter nicht redundant? Was passiert wenn der User einfach mal ein Dokument ausserhalb deiner App löscht? Dann stimmt die Anzahl Dokumente nicht mehr mit Deinem Counter überein. Wäre es nicht sinnvoller die Anzahl immer zu ermitteln wenn du sie brauchst indem Du die Dokumente zählst?

Gruß

Claus
 
Zuletzt bearbeitet:
Hmpf.....kein schlechter Ansatz..... sprich ich iterriere einfach über die im gesetzen Pfad befindlichen .dcu dateien. und initialisiere somit den counter..... Gute idee

Danke, ich schau erstmal was ich daraus machen kann .
 
Andere Frage , wenn ich der Anwendung Informationen zur Verfügung stellen will, z.b Entwickler, versionsnummer, releasedate usw.
schreibe ich diese am besten einfach beim starten der Anwendung in die Preferences ? weiß nicht ob es sinnvoll ist Sowas in einer Textdatei zu halten aus der die Daten dann der Anwendung zur Verfügung gestellt werden ?

oder halte ich diese Daten auch z.B einfach in der Anwendung selbst ? z.B in einer Map ? oder doch in Properties :lol:
 
Zuletzt bearbeitet:
Also ich finde es nicht sinnvoll unveränderliche Daten in eine Textdatei zu schreiben. Gerade Sachen wie Entwickler und Versionsnummer kann man sonst ja total einfach ändern, was ja eigentlich nur der Entwickler können sollte. Ausserdem was für einen Vorteil bringt es die Daten in einer Textdatei zu haben gegenüber sie fest im Code zu verankern?

Gruß

Claus
 
weiß nicht ob es sinnvoll ist Sowas in einer Textdatei zu halten aus der die Daten dann der Anwendung zur Verfügung gestellt werden ?

Deswegen auch mein Zweifel, ich weiß das zum Zweck der Internationalisierung oftmals String literale in Properties Dateien oder ähnlichem gehalten werden um je nach locale dann einfach den text / die Übersetzung zu liefern.

Aber du hast natürlich recht, es wäre dann einfach änderbar, was selbstverständlich nicht das Ziel ist.
 
Bei mir sind die Versionsnummer fest im code aber die Anzeige um User hin findet natürlich über eine property statt. Sprich es gibt einen property string

xy.Version=Version v{0}

Und der parameter wird dann durch den Hard codierten Versionsstring ersetzt. Somit ist auch die Versionsnummer ausgabe internationalisiert. Beim Entwickler etc verhält es sich genauso so.

Gruss

Claus
 
Ich sehe keinen guten Grund die Version im Quellcode zu schreiben.

Die MANIFEST.MF stellt extra Variablen für die Version bereit: Setting Package Version Information (The Java™ Tutorials > Deployment > Packaging Programs in JAR Files)
Auslesen kann man die Version mit:
Java:
public final static String CURRENT_VERSION =  <Klasse>.class.getPackage().getImplementationVersion();

Es wird auch gerne eine version.properties genommen, da dies oft von den gewählten Tools abhängt.
 
Was die Version angeht ok , aber was ist mit den Ganzen anderen Informationen, wie z.B developer, email, meiner Addresse ?
Ich habe unter anderem einen Menüpunkt "Über..." im Hilfemenü der Informationen zu verschiedenen dingen anzeigt, wie Version,
Entwickler, Firma, usw. usw., diese dinge sind zzt alle Hardcoded im Source Code verankert, in Form von Konstanten.

Ich dachte halt es gibt einen schöneren weg , der Mit der Lösung mit der Manifest Datei wäre es ja wie mit properties Dateien , man könnte diese Informationen alle zwar leicht austauschen , aber sie sind auch leicht zu manipulieren ..... 🙂

Ich kommen wie gesagt nicht aus der Branche und dies ist mein erstes größeres Projekt, und bisher musste ich mich mit solchen Feinheiten nie rumschlagen 🙂

Deshalb suche ich halt die Best Practice
 
Ich finde derartige Dinge wie developer, email, Addresse oder Versionsnummer auch ganz richtig im Programm aufgehoben.

Daher ist dies auch mehr eine Frage des Konfigurationsmanagement WIE diese Infos in das Programm integriert werden können. Oft wird in der Versionsnummer die Repositorynummer des Source-Control-Systems (Subversion, Git,...) integriert. Das möchte man ja kaum manuell pflegen.

Daher habe ich in Eclipse oft einen ANT-Buildstep, der diese Informationen pflegt (Stichwort Buildnumber-Task). In Profi-Projekten findet der Build üblicherweise über CI statt (Jenkins, Hudson, Gradle) und daher ist es eine Frage der Einrichtung des Build-Prozesses.

Damit werden bei einem Build automatisch die korrekten Werte geholt und in einer Datei abgelegt. Es ist dann eine Frage des Aufwands, ob die Datei schon reicht oder eine Java-Datei geschrieben wird, die im Programm kompiliert wird.
 
Ich finde derartige Dinge wie developer, email, Addresse oder Versionsnummer auch ganz richtig im Programm aufgehoben.

also könnte man zur Not auch ( der Einfachheit halber ) einfach eine Konstantensammlung, oder ein Enum anbieten was eben Zentral die gewünschten Werte verwaltet und der Applikation zur Verfügung stellt?!

Da wäre dann aber die Frage was schicker ist :
Java:
frame = new JFrame(AppInfo.APPLICATION_TITLE.value() + " " + AppInfo.VERSION.value());

oder doch solch ein Konstrukt :
Java:
frame = new JFrame(Info.APPLICATION_TITLE + " " + Info.VERSION);

Das mit dem ANT-Buildstep müsste ich mir genauer anschauen, wenn ich mit Einer Versionsverwaltung arbeite dann mit Git, da müsste ich mir aber auch erst anschauen wie sich das mit der Versionsnummer verhält und wie ich diese automatisch meiner Applikation zugänglich machen könnte.
 
Zuletzt bearbeitet:
Schaue ich mir gleich mal an , danke 🙂

EDIT : ich habe zzt. für alle Informationen die der Anwendung vorliegen sollen eine Konstantensammlung angelegt, da ich es schöner fand als ein Enum anzulegen

Konstrukte wie :
Java:
JFrame frame = new JFrame(App.TITLE + " " + App.VERSION);

find ich zumindest zum jetzigen Zeitpunkt doch recht angenehm 🙂
 
Zuletzt bearbeitet:
Jo schau ich mir an , wie das mit normalen Properties Objekten geht hab ich mir auch schon angeschaut, grade im bezug auf i8n, insofern ich das später mal implementiere, die Anwendung läuft sowieso erstmal nur als Stand-alone Version auf den Rechnern der Firma meines Vaters, ich konnte einfach nicht mit ansehen wie er sich da mit der Exel-Tabelle rumschlagen muss die ich ihm mal angelegt habe ^^
 

Neue Themen


Zurück
Oben