Soll mich darauf, dass in einer Klasse Darstellung einer XML-Einstellungsdatei gibt das Gesetz des demeter verletzt?

StackOverflow https://stackoverflow.com/questions/3689118

Frage

Ich bin mit einem Werkzeug, um automatisch eine Klasse Darstellung einer hierarchisch organisierten XML-Datei zu generieren. Die XML-Datei ist eine Einstellungs meine App Notwendigkeit, den Zugang zu können Datei (read-only).

Wenn ich pass in dem Top-Level-Knoten (zum Beispiel AppSettings) zu einer Klasse, die Bedürfnisse für den Zugriff eines oder mehr Einstellungen, ich leicht mit dem Code kann am Ende das sieht etwa so aus:

var windowSize = AppSettings.Views.Windows.Dashboard.Size;

Dies scheint eine schwere Verletzung des Gesetzes von Demeter zu sein, aber ich frage mich, ob ich kümmern soll. Ich konnte zu großer Mühe geben, nur in den genauen Einstellungen geht ich für jede Klasse brauchen, aber ich habe Probleme seeing mit, wie diese mehrere Punkte mich in diesem Fall verletzt werden.

Ist Kopplung fest meinen Code in meinem XML-Dateiformat wahrscheinlich Wartungsprobleme oder andere Probleme in der Zukunft zu schaffen, oder ist dies ein Beispiel, wo es Sinn macht, nicht religiös einen OOP Bauprinzip folgen?

War es hilfreich?

Lösung

Ja, Sie sollten darauf, für einen sehr pragmatischen Grund!

Die Klassen, in denen Sie Ihre Einstellungen verwenden, unbedingt brauchen nicht auf die Art und Weise abhängig zu sein, diese Einstellungen gespeichert werden.

Stellen Sie sich vor in der Zukunft mehrere Themen für Ihre Anwendung unterstützen wollen. Sie werden nicht nur mit einem, sondern viele Möglichkeiten für Armaturenbrett Größe, zum Beispiel am Ende:

AppSettings.Views.ThemeA.Windows.Dashboard.Size;
AppSettings.Views.ThemeB.Windows.Dashboard.Size;

Ihre UI-Klasse noch braucht nur eine Sache, einen Wert für die variable Fenstergröße, ist es nicht wissen müssen, welches Thema zur Zeit verwendet wird.

Es ist wahr, egal wo Sie eine XML-Schnittstelle haben, wollen Sie nicht überall in Ihrem Code auf dem Schema abhängig sein, sondern nur an einer zentralen Stelle.

Zum Beispiel können Sie die Einstellungen in einer Map setzen könnten intern verwendet werden, wie folgt:

public class SettingsReader {

    public static final String VIEW_WINDOW_DASHBOARD_SIZE = "Views.Windows.Dashboard.Size";

    private Map settings = new Hashmap();

    public SettingsReader(AppSettings appSettings) {
        settings.put(VIEW_WINDOW_DASHBOARD_SIZE, appSettings.Views.Windows.Dashboard.Size);
    }

    public String getSettingValue(String key) {
        return settings.get(key);
    }
}

Dann haben Sie nur einen Ort zum Umgestalten eines Themas zu unterstützen, wie folgt aus:

public class SettingsReader {

    public static final String VIEW_WINDOW_DASHBOARD_SIZE = "Views.Windows.Dashboard.Size";

    private Map settings = new Hashmap();

    public SettingsReader(AppSettings appSettings, String theme) {
        settings.put(VIEW_WINDOW_DASHBOARD_SIZE, appSettings.Views + theme + Windows.Dashboard.Size);
    }

    public String getSettingValue(String key) {
        return settings.get(key);
    }
}

Eine letzte Bemerkung, nur weil meine Mischung aus Pseudo-Code und Java-Code Leute verwechseln kann, vor allem die appSettings.Views + theme + Windows.Dashboard.Size: wenn sie mit einer XML-Schnittstelle arbeiten, ist xPath in der Regel sehr nützlich, auch wenn mit Objekten dank der schönen Bibliothek arbeiten JXPath (für Java, ich weiß nicht, für andere Sprachen).

Andere Tipps

Wenn Sie spuckt stummen Daten dann gibt es wirklich keine bessere Möglichkeit, es zu tun.

Ich würde dazu neigen, an der Arbeit zu einer Lösung zu versuchen, wo Sie schieben und Kontexte Pop könnten, though.

PushContext(AppSettings)
  // do child contexts
  PushContext(Views)
    // more child contexts
    PushContext(Windows)
    // etc.
    PopContext()
  PopContext()
PopContext()

Normalerweise werden die verschiedenen Schiebt würden in verschiedenen Funktionen oder Dateien sein, sind aber hier aus Gründen der Darstellung gezeigt. Unabhängig davon, ob Sie die Ansichten Kontext einschieben dann analysieren Sie genau das, als ob man an der Wurzel des Objekts ist.

Wenn diese DumbData ist aber, könnte man auch passieren nur die Art der Sache, die ‚Ansichten‘ darstellt, um den Code, dass Parsen es. Top-Level, Ihr Code würde wie folgt aussehen:

views.ParseSettings(AppSettings.Views);
locale.ParseSettings(AppSettings.Locale);
network.ParseSettings(AppSettings.Network);

Dies wäre sicherlich „saubere“ von einem LOD POV, aber es kann nicht wert für die Anzahl der Einstellungen sein, dass Sie haben. Doch mit dem Umfang Tiefe vielleicht die Implikation ist, dass Sie viele Einstellungen haben, so Splitting ihnen in Verantwortungsbereiche (zum Laden und Speichern der Einstellungen) wahrscheinlich sinnvoll ist.

Alle Dinge sind relativ, es hängt wirklich von der Größe des Projekts, und wenn Sie kümmern sich um Wartung.

Wenn Sie das tun kümmern uns um die Wartung dann wollen Sie keine Einschränkungen durch die Konfiguration Quelle auf dem Rest des Codes Basis auferlegt erzwingen.

Der beste Weg, dies zu erreichen ist, um Code zu Schnittstellen und verstecken Sie Ihre Implementierung dahinter. Auf diese Weise Ihren Code, um einen Vertrag mit dem Konfigurationsoberfläche hat und kümmert sich nicht darum, wie sich die aktuelle Konfiguration geladen wird.

public interface IConfiguration
{
    Size ViewSize { get; }
}

public class AppSettingsConfiguration : IConfiguration
{
     public Size ViewSize
     {
          return AppSettings.Views.Windows.Dashboard.Size;
     }
}

Alle raubend Code sollte dann gegen die IConfiguration Schnittstelle codiert werden. Diese Mittel können Sie die Art und Weise ändern Sie Ihre Konfiguration mit minimaler Auswirkung abgerufen werden.

Automatische Generationen können ein Problem für große Projekte sein.

Wenn Sie den erzeugten Code aus einem einzigen Ort verwenden (zum Beispiel ein einzelnes Paket), vielleicht gibt es kein Problem.

Wenn Sie die Verwendung des Codes machen:

var windowSize = AppSettings.Views.Windows.Dashboard.Size;

in vielen Orten, möchten Sie vielleicht einige dieser Kupplung macht eine Methode auf dem AppSettings verbergen:

getSize() {
  return Views.Windows.Dashboard.Size;
}

Aber wenn Sie brauchen dies für alle Klassen zu tun, vielleicht ist es nicht sinnvoll ist.

Die beste Entscheidung hängt von der Größe des Projektes (und wenn es wachsen will), die Zeit, die Sie es zu tun haben, und die Menge der erzeugten Codes.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top