Programm-Models in Static-Objekten speichern

Status
Nicht offen für weitere Antworten.

m@nu

Bekanntes Mitglied
hi zusammen

für meine applikation habe ich folgende klasse geschrieben, welche meine models bereithält, lädt & speichert:
Code:
/*
 * Created on 19.05.2005
 */
package net.msites.drivesync.data.core.models;

import java.io.File;
import java.util.ArrayList;

import net.msites.drivesync.data.core.io.TaskIconXMLReader;
import net.msites.drivesync.data.core.io.plugindefinition.PluginDefinitionReader;
import net.msites.drivesync.data.core.io.setting.SettingReader;
import net.msites.drivesync.data.core.io.setting.SettingWriter;
import net.msites.drivesync.data.core.io.task.TaskReader;
import net.msites.drivesync.data.core.io.task.TaskWriter;
import net.msites.drivesync.data.core.models.plugindefinition.PluginDefinitionHolder;
import net.msites.drivesync.data.core.models.settings.SettingHolder;
import net.msites.drivesync.data.core.models.settings.SettingProperty;
import net.msites.drivesync.data.core.models.task.Group;
import net.msites.drivesync.data.core.models.task.TaskHolder;
import net.msites.drivesync.data.reusable.io.BasicXMLStructureReader;


/**
 * Diese Klasse stellt statische Methoden zur Verfügung, welche den Zugriff
 * auf die Haupt-Datenstrukturen erlauben.
 * 
 * @author Manuel Alabor
 * @version 1.0
 */
public class ApplicationDataHolder {

    /* Eigenschaften: */
    private static SettingHolder settingHolder = null;
    private static TaskHolder taskHolder = null;
    private static PluginDefinitionHolder pluginDefinitionHolder = null;
    private static ArrayList quickAddHolder = null;
    private static ArrayList taskIconHolder = null;
    
    /* Konstanten: */
    private static final String settingXML = "settings.xml";
    private static final String taskXML = "tasks.xml";
    private static final String pluginDefinitionXML = "plugins/plugins.xml";
    private static final String quickAddXML = "quickadd.xml";
    private static final String taskIconXML = "taskicons/icons.xml";
    
    
    
    // Getter-Methoden ---------------------------------------------------------
    /**
     * Liefert die Datenstruktur <code>settingHolder</code> mit allen aktuell
     * geladenen/verfügbaren Einstellungen für DriveSync.

     * Wurde die Datenstruktur noch nicht initialisiert/geladen, wird dies
     * automatisch nachgeholt.
     * 
     * @return
     */
    public static SettingHolder getSettingHolder() {
        if(settingHolder == null) {
            loadSettingXML();
        }
        
        return settingHolder;
    }
    
    /**
     * Liefert die Datenstruktur <code>taskHolder</code> mit allen aktuell
     * geladenen/verfügbaren Aufgaben.

     * Wurde die Datenstruktur noch nicht initialisiert/geladen, wird dies
     * automatisch nachgeholt.
     * 
     * @return
     */
    public static TaskHolder getTaskHolder() {
        if(taskHolder == null) {
            loadTaskXML();
        }
        
        return taskHolder;
    }
    
    /**
     * Liefert die Datenstruktur <code>pluginHolder</code> mit allen aktuell
     * geladenen Plugins.

     * Wurde die Datenstruktur noch nicht initialisiert/geladen, wird dies
     * automatisch nachgeholt.
     * 
     * @return
     */
    public static PluginDefinitionHolder getPluginDefinitionHolder() {
        if(pluginDefinitionHolder == null) {
            loadPluginDefinitionXML();
        }
        
        return pluginDefinitionHolder;
    }
    
    /**
     * Liefert die Datenstruktur <code>quickAddHolder</code> mit allen aktuell
     * geladenen QuickAdd-Einträgen für das erstellen von Namenausschlüssen.

     * Wurde die Datenstruktur noch nicht initialisiert/geladen, wird dies
     * automatisch nachgeholt.
     * 
     * @return
     */
    public static ArrayList getQuickAddHolder() {
        if(quickAddHolder == null) {
            loadQuickAddXML();
        }
        
        return quickAddHolder;
    }
    
    /**
     * Liefert die Datenstruktur <code>taskIconHolder</code> mit allen aktuell
     * geladenen Aufgaben-Symbolen.

     * Wurde die Datenstruktur noch nicht initialisiert/geladen, wird dies
     * automatisch nachgeholt.
     * 
     * @return
     */
    public static ArrayList getTaskIconHolder() {
        if(taskIconHolder == null) {
            loadTaskIconXML();
        }
        
        return taskIconHolder;
    }
    
    
    // Laden -------------------------------------------------------------------
    /**
     * Lädt alle Einstellungen aus der Settings.xml in einen
     * <code>SettingHolder</code>.
     */    
    private static void loadSettingXML() {
        /* Prüfen ob Setting-XML existiert: */
        File checker = new File(settingXML);
        
        if(!checker.exists() || !checker.isFile()) {
            // Wenn die Setting-XML-Datei nicht existiert, wird ein SettingHolder
            // mit Standart-Einstellungen erstellt.
            // Sobald gespeichert wird, wird der neue Standart-SettingHolder dann
            // in die XML-Datei geschrieben.
            settingHolder = createDefaultSettingHolder();
        
        } else {
            // Existiert die XML-Datei, wird diese eingelesen.
            try {
                // Einstellungen holen:
                SettingReader settingReader = new SettingReader();
                settingHolder = settingReader.readXML(settingXML);
            } catch (Exception e) {
                e.printStackTrace();
            }        
        }
    }
    
    /**
     * Lädt die Aufgaben in der XML-Datei "tasks.xml" im Applikationsordner
     * in die Datenstruktur <code>taskHolder</code>.
     */
    private static void loadTaskXML() {
        /* Prüfen ob Task-XML existiert: */
        File checker = new File(taskXML);
        
        if(!checker.exists() || !checker.isFile()) {
            // Wenn die Task-XML-Datei nicht existiert, wird ein TaskHolder mit
            // Standart-Daten erstellt.
            // Sobald gespeichert wird, wird der neue Standart-TaskHolder dann
            // in die XML-Datei geschrieben.
            taskHolder = createDefaultTaskHolder();
        
        } else {
            // Existiert die XML-Datei, wird diese eingelesen.
            try {
                // Aufgaben holen:
                TaskReader taskReader = new TaskReader();
                taskHolder = taskReader.readXML(taskXML);
            } catch (Exception e) {
                e.printStackTrace();
            }            
        }
    }
    
    /**
     * Lädt alle installierten Plugins in die Datenstruktur 
     * <code>pluginHolder</code>.
     */    
    private static void loadPluginDefinitionXML() {
        try {
            // Plugins holen:
            PluginDefinitionReader pluginReader = new PluginDefinitionReader();
            pluginDefinitionHolder = pluginReader.readXML(pluginDefinitionXML);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * Lädt die XML mit allen QuickAdd-Items, welche für das erstellen von neuen
     * Namenausschlüssen verwendet werden können.
     */
    private static void loadQuickAddXML() {
        BasicXMLStructureReader reader = new BasicXMLStructureReader("item");
        quickAddHolder = reader.readXML(quickAddXML);
    }

    /**
     * Lädt die XML mit allen verfügbaren Aufgabensymbolen, welche zur verfügung
     * stehen.
     */
    private static void loadTaskIconXML() {
        TaskIconXMLReader reader = new TaskIconXMLReader();
        taskIconHolder = reader.readXML(taskIconXML);
    }
    
    
    // Speichern ---------------------------------------------------------------
    /**
     * Speichert die Daten im <code>settingHolder</code> in die entsprechende
     * XML-Datei.
     */
    public static void saveSettingHolder() {
        try {
            // Einstellungen speichern:
            SettingWriter writer = new SettingWriter();
            writer.writeXML(settingXML, settingHolder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * Speichert die Daten im <code>taskHolder</code> in die entsprechende
     * XML-Datei.
     */
    public static void saveTaskHolder() {
        try {
            // Aufgaben speichern:
            TaskWriter writer = new TaskWriter();
            writer.writeXML(taskXML, taskHolder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    // Default-Strukturen ------------------------------------------------------
    // Folgende Methoden liefern den jeweiligen Data-Holder mit den Standart-
    // Inhalten. Somit kann eine Datei frisch erstellt werden, falls diese nicht
    // vorhanden sein sollte.
    /**
     * Erstellt einen <code>SettingHolder</code> welcher lediglich die Standart-
     * Einstellungen enthält.
     * 
     * @return
     */
    private static SettingHolder createDefaultSettingHolder() {
        /* SettingHolder erstellen: */
        SettingHolder settingHolder = new SettingHolder();
        
        /* Standart-Einstellungen erstellen: */
        SettingProperty concurrentThreads = 
            new SettingProperty("concurrentThreads", new Integer(1));
        SettingProperty saveTasksBeforeSync = 
            new SettingProperty("saveTasksBeforeSync", new Boolean(true));
        
        /* Einstellungen zum Holder hinzufügen: */
        settingHolder.addProperty(concurrentThreads);
        settingHolder.addProperty(saveTasksBeforeSync);
        
        /* Rückgabe: */
        return settingHolder;
    }
    
    /**
     * Erstellt einen leeren <code>TaskHolder</code>, welcher lediglich die
     * Standart-Gruppe "< keine >" (id = 0) enthält.
     * 
     * @return
     */
    private static TaskHolder createDefaultTaskHolder() {
        /* TaskHolder erstellen: */
        TaskHolder taskHolder = new TaskHolder();
        
        /* Standartgruppe erstellen & zum Holder hinzufügen: */
        Group defaultGroup = new Group("0", "< keine >");
        taskHolder.addGroup(defaultGroup);
        
        /* Rückgabe: */
        return taskHolder;
    }
    
}

ist es sinnvoll diese aufgabe auf diese weise zu lösen?
gibt es bessere ansätze? ich bin mir eben wegen den statischen objekten & methoden nicht so ganz sicher... aber auf die andere seite ist es so am praktischsten, um von überall her zugriff auf die daten zu haben...

vielen dank für anregungen! :)
gruss
m@nu
 

Sky

Top Contributor
Also, ich bin kein Fan von nur statischen Objekten & Methoden. Ich würde es eher als Singleton realisieren... aber ob das was an der Perfermance ändert kann ich nicht sagen, ich denke aber eher nicht.
 

m@nu

Bekanntes Mitglied
hab mal singletons gegoogelt...
scheint mir irgendwie "sauberer" zu sein ... vorallem das "synchronized" keyword scheint grossen sinn zu machen.

danke für den tipp!

ps. hab gemerkt ich hab sowas schonmal programmiert... hab aber nicht gewusst dass man das singleton nennt ;)
 

Karl

Aktives Mitglied
Hallo m@nu,

Dein ApplicationDataHolder ähnelt dem SingletonRegistry-Pattern. Eine Reihe von Services (oder Objekte) -
bei Dir SettingHolder, TaskHolder, QuickAddHolder, etc. werden bei Bedarf lazy nur ein einziges Mal (Singleton-Pattern) initialisiert und zurückgegeben.
Allerdings finde ich wie sky80, dass Du die Registry selbst auch als Singleton implementieren solltest. Die vielen statics sind unschön (aber kein Performance-Hindernis). Eine andere Sache ist, dass Deine Klasse Gefahr läuft zu einer Gott-Klasse zu werden (sehr groß und für zuvieles zuständig), wenn noch mehr Sachen hinzukommen. Andererseits nehme ich an, dass die späte Initialisierung Dir wichtig ist, also ein Füttern des ApplicationDataHolders bei Programmstart nicht in Frage kommt. Du könntest als Alternative das eigentliche Erzeugen (also für SettingHolder, etc.) in Factory-Klassen auslagern, die bei Bedarf angesprochen werden.
Wenn Du die späte Initialisierung gar nicht brauchst, verzichte darauf und initialisiere zu Beginn.

Das Speichern von TaskHolder und SettingHolder würde ich woanders hin packen. Möglicherweise können die Klassen selbst eine save-Methode bekommen (die dann ggf. auch delegieren können).

Konstantenbenutzung ist löblich, diese werden in Java aber immer in Großbuchstaben geschrieben, solltest Du anpassen (Bsp.: pluginDefinitionXML --> PLUGIN_DEF_XML). Außerdem sollten sie plublic sein, damit sie im JavaDoc gelistet werden. Eine Wiederholung des Werts im JavaDoc der Konstante kann hier auch nicht schaden. Dann muss man nicht bei der Konfiguration der Anwendung in den Source gucken, wie denn gleich die xml-Datei heißen muss.

Deine Implementierung ist nicht Thread-sicher. Das kann völlig richtig sein, allerdings gerade bei Registries, die zentrale Aufgaben wahrnehmen, wird das schnell unangenehm, falls doch jemand einen Thread zu etwas nutzt.
Wenn dann zwei SettingHolder existieren, wird das zwar erstmal nichts schaden, aber herauszufinden, warum die Settings manchmal gespeichert werden und manchmal nicht, wird recht interessant :wink:
Einfach mal checken, ob die Gefahr überhaupt besteht.

Das ExceptionHandling beim xml-Zugriff ist inakzeptabel. :noe:

Der Code ist gut dokumentiert :D

Ich hoffe, das war nicht zuviel genörgelt, aber Du wolltest es ja so :bae:

Gruß,
Karl

EDIT: Sorry, zwischenzeitlichen Post übersehen: richtig: synchronized ist das Mittel für die Threadsicherheit.
 

m@nu

Bekanntes Mitglied
hi Karl,

wow! vielen dank für dein ausführliches code-review!

denke ich werde das grundlegende design der klasse nochmal überarbeiten. (inkl. thread sicherheit)
hehe, die namenskonvetionen für konstanten hab ich wohl übersehen im eifer des gefechts ggg

jop, das exception-handling is ein grosses "No No" ... die klasse is aber auch noch nicht "vollendet" :)

dokumentierter code ist mir etwas vom wichtigsten. als ich letztes jahr begonnen hab an einem projekt in meinem neuen job zu arbeiten, durfte ich viele "insert description here"'s lesen... damals hab ich mir geschworen: so programmierst du NIE! ;)

grüsse
m@nu
 

Bleiglanz

Gesperrter Benutzer
du hast ganz schön viele Magic-Strings da drin, ab in ein Property-File damit :)

du wiederholst zigmal das "Muster"
Code:
        FOOFAAReader reader = new FOOFAAXMLReader();
        FOOFAAHolder = reader.readXML(foofaafile);
mach mal lieber ein Interface für FOOFAA und behandle alle gleich, das richt doch stark nach dupliziertem Code...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Jose05 Umgang mit Exceptions in einen Programm Allgemeine Java-Themen 2
E Output Fehler (Java-Programm Kuchen) Allgemeine Java-Themen 11
S Java Programm lässt sich vom USB-Stick starten, aber nicht von HDD Allgemeine Java-Themen 16
R Programm führt Methoden gleichzeitig aus Allgemeine Java-Themen 2
T Der Aufruf von CMD-Programm Allgemeine Java-Themen 30
A Java Programm erstellen hilfe Allgemeine Java-Themen 10
Mike80 Processing Programm fiert ohne Arduino ein Allgemeine Java-Themen 2
B Mysteriöse Ergebnisse beim Baccarat Programm? Allgemeine Java-Themen 13
districon Programm zum Durchsuchen von (Ebay-)Artikeln Allgemeine Java-Themen 1
T Addons im eigenen Programm Allgemeine Java-Themen 1
Calli11 Was muss ich hier in die Main schreiben, damit das Programm ausgeführt wird? Allgemeine Java-Themen 4
S .exe Datei/Programm auslesen? Allgemeine Java-Themen 2
S Formel für Sonnenwinkel in ein Programm überführen Allgemeine Java-Themen 11
Alex_99 Programm stürzt beim Aufruf der Funktion ab? Text ausgeben Allgemeine Java-Themen 45
B Java Programm auf virutellem Desktop laufen lassen? Allgemeine Java-Themen 1
L Java überprüfen lassen, ob sich ein gegebener Pfad / das Programm an sich auf einer CD oder Festplatte befindet Allgemeine Java-Themen 14
Tiago1234 Warum hängt sich mein Programm auf? Allgemeine Java-Themen 22
D Programm designen Allgemeine Java-Themen 1
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
J c Programm läuft nicht in compilierter Version des Java Projektes Allgemeine Java-Themen 7
O 2D-Grafik BioFarben-Programm soll auf Vollbild schalten Allgemeine Java-Themen 1
S Nachrichten Filter Programm Allgemeine Java-Themen 14
S Programm schreiben, das mir aufgrund von Schlagwörtern, die ich im Internet suche, relevante Themen sofort anzeigt. Allgemeine Java-Themen 1
T Hilfe bei Programm. IDE: Eclipse mit EV3-Plugin, lejos Allgemeine Java-Themen 8
Lukas2904 Swing Anzeigen lassen das das Programm geschlossen wurde Allgemeine Java-Themen 3
TechnikTVcode Mail Programm Allgemeine Java-Themen 2
S Programm entwickeln, welches ein Dreieckspuzzle lösen kann Allgemeine Java-Themen 5
R Lesen von Interfaces (Programm Vervollständigen) Allgemeine Java-Themen 10
Dann07 Java-Programm findet DLLs nicht! Allgemeine Java-Themen 20
OSchriever Linux-Programm öffnen Allgemeine Java-Themen 6
P USER Management in SQL übergreifend auf JAVA Programm Allgemeine Java-Themen 41
L Eclipse Konsole im exportierten Programm Allgemeine Java-Themen 2
OSchriever Programm über Linux-Kommandozeile ausführen Allgemeine Java-Themen 20
D Verkauf von einem Programm welches ich in Java geschrieben habe Allgemeine Java-Themen 4
M Programm erkennt String aus .txt Datei nicht Allgemeine Java-Themen 3
P Erstelltes Programm ist doppelt so groß Allgemeine Java-Themen 11
N Programm nach Abschluss neustarten lassen Allgemeine Java-Themen 6
S Einfaches Programm programmieren Allgemeine Java-Themen 5
M kleines KI Programm Idee Allgemeine Java-Themen 7
D Boolean von ein anderem Java Programm während der Laufzeit ändern Allgemeine Java-Themen 23
L Excel Datei löscht sich selbst im Programm - Java Allgemeine Java-Themen 3
I File ausführen und mein Programm bearbeiten lassen Allgemeine Java-Themen 11
ralfb1105 Starten Java App(s) (.jar) aus einem Java Programm Allgemeine Java-Themen 18
temi Java Programm aus einer DB laden und starten Allgemeine Java-Themen 2
N Programm startet nicht, nur per cmd Allgemeine Java-Themen 5
J Programm zum Suchen eines Wortes im Dateisystem Allgemeine Java-Themen 4
E Java Programm mit Clients erweitern - Möglichkeiten? Allgemeine Java-Themen 2
Joker4632 Methoden Befehl an bereits extern geöffnete Programm-spezifische Konsole senden Allgemeine Java-Themen 1
M Dieses Programm schneller machen? Allgemeine Java-Themen 2
R Programm zur Rekursion Allgemeine Java-Themen 5
N Quicksort Programm hängt sich auf Allgemeine Java-Themen 6
S Compiler-Fehler Programm verhält sich in Eclipse anders Allgemeine Java-Themen 1
B Input/Output Programm zum Auslesen/Beschreiben von Textdateien, wie Geschwindigkeit erhöhen? Allgemeine Java-Themen 18
dereki2000 Programm veröffentlichen Allgemeine Java-Themen 14
mrbig2017 Threads Chat Programm mit Threads? Allgemeine Java-Themen 2
M Suche aktuelle Apache Poi Bibliothek zum Einbinden in mein Programm Allgemeine Java-Themen 2
J Java "Bank Programm" Brauche eure Hilfe Allgemeine Java-Themen 3
S Java Programm (Spiel mit den Boxen) Allgemeine Java-Themen 1
kodela Programm hängt in der Ereigniswarteschlange Allgemeine Java-Themen 13
A Java Programm verbessern/vereinfachen Allgemeine Java-Themen 20
P Programm darf nicht mehrfach startbar sein Allgemeine Java-Themen 16
S Programm hängt sich manchmal (selten) auf Allgemeine Java-Themen 9
JavaNewbie2.0 Programm nicht im Taskmanager schliesen können Allgemeine Java-Themen 15
J XML Datei mit installiertem Programm öffnen Allgemeine Java-Themen 7
Arif Input/Output Dateien im Jar-Programm speichern Allgemeine Java-Themen 12
H Java FX 2 Fragen um Programm in mehrere sprachen zu übersetzen in Gluon Framwork Allgemeine Java-Themen 3
JavaNewbie2.0 Programm bleibt "stehen" Allgemeine Java-Themen 2
JavaNewbie2.0 Start eines Anderen Programm erkennen Allgemeine Java-Themen 6
E Mit Java ein Python Programm starten Allgemeine Java-Themen 20
Q-bert Daten von Java Programm speichern Allgemeine Java-Themen 4
Aruetiise Methoden .jar mit Programm öffnen Allgemeine Java-Themen 2
C anderes Programm schließen! Allgemeine Java-Themen 5
C Webseiten Programm problem Allgemeine Java-Themen 5
E Programm auf Installation prüfen Allgemeine Java-Themen 1
J Programm zum Download von CSV-Dateien Allgemeine Java-Themen 4
E Programm ohne Windowsrand(Vollbild) ? Allgemeine Java-Themen 5
G Programm, das nach abgearbeiteter main Methode weiterläuft Allgemeine Java-Themen 72
P Schnittstelle java Programm zu Webserver / Browser Allgemeine Java-Themen 2
J Schutz Programm Jar Exe Allgemeine Java-Themen 7
R javax.comm --> Programm funktioniert nach Export nicht mehr Allgemeine Java-Themen 0
Blender3D Java Swing Programm Windows 10 Autostart Problem Allgemeine Java-Themen 2
U Input/Output Warum wirft mir das Programm diesen Fehler? Allgemeine Java-Themen 6
X jvm exception abfangen und an externes Programm schicken Allgemeine Java-Themen 4
B Programm updaten mit FXLauncher Allgemeine Java-Themen 1
D Nicht quelloffenes Programm Allgemeine Java-Themen 5
F Java-Programm lizensieren Allgemeine Java-Themen 21
I Programm im Hintergrund bei Windows zur Steuerung der Tastatur nutzen Allgemeine Java-Themen 2
X Aus Programm "Installationsprogramm" machen Allgemeine Java-Themen 6
T Java Programm in Internetseite? Allgemeine Java-Themen 4
T Java Programm frisst RAM Allgemeine Java-Themen 6
H Alter Java-Programm läuft nicht mehr. Laut strace fehlt libpthread.so.0 Allgemeine Java-Themen 3
H Runtime reagiert erst wenn Programm abbricht Allgemeine Java-Themen 1
E Exceptions abfangen und dann Programm stoppen - aber wie? Allgemeine Java-Themen 2
Neumi5694 Offenes Programm nutzen Allgemeine Java-Themen 4
L Java-Programm Zahlenkombinationen ausgeben Allgemeine Java-Themen 10
KaffeeFan Methoden Suche Methode um Programm kurz warten zu lassen Allgemeine Java-Themen 22
J Programm meldet "Keine Rückmeldung" nach Verbindung zum Server Allgemeine Java-Themen 4
T Java Programm sauber beenden (Mac OS) Allgemeine Java-Themen 7
O Programm wird einfach "gekillt" Allgemeine Java-Themen 3
L TV Programm API/Web Service o.ä. Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben