Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I care that passing in a class representation of an XML settings file violates the law of demeter?

I'm using a tool to automatically generate a class representation of a hierarchically organized XML file. The XML file is a settings file my app need to be able to access (read-only).

If I pass in the top-level node (e.g., AppSettings) to a class that needs to access one or more settings, I can easily end up with code that looks something like this:

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

This seems to be a serious violation of the Law of Demeter, but I'm wondering if I should care. I could take great pains to only pass in the exact settings I need for each class, but I'm having trouble seeing how those multiple dots are going to hurt me in this case.

Is tightly coupling my code to my XML file format likely to create maintenance issues or other problems in the future, or is this an example where it makes sense to not religiously follow an OOP design principle?

like image 375
devuxer Avatar asked Feb 26 '23 06:02

devuxer


1 Answers

Yes, you should care, for a very pragmatic reason!

The classes where you want to use your settings absolutely don't need to be dependent on the way those settings are stored.

Imagine in the future you want to support multiple themes for your application. You will end up with not one, but many possibilities for your dashboard size, for example:

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

Your UI class still only needs one thing, a value for its variable windowSize, it doesn't need to know which theme is currently used.

It's true wherever you have an XML interface, you don't want to be dependent on the schema everywhere in your code but only in one central place.

For example you could put the settings in a Map to be used internally, like this:

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

Then you just have one place to refactor to support a theme, like this:

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

A final note, just because my mix of pseudo code and java code may confuse people, especially the appSettings.Views + theme + Windows.Dashboard.Size: when working with an XML interface, xPath is usually very useful, even when working with objects thanks to the nice library JXPath (for java, I don't know for other languages).

like image 53
Damien Avatar answered Apr 07 '23 23:04

Damien