1

I know that the Singleton design pattern is frowned upon for various reasons. They're not easy to mock for unit testing, they're not thread safe, etc, etc. But now and again, I'm faced with a situation where an application is driven by a configuration file (application metadata). Everything about this application is contained in its configuration file (let's say json, that the app downloads when its config changes). The only purpose of this app is to serve the user a UI that wraps the configuration and allows flow. Without this config file, the app is useless. I'm thinking that this is a pretty common scenario for a lot of applications.

So given an application that's 100% driven from a config file, how would you design code to avoid using a singleton? Would you constantly read from this json file only when needed, and only a specific section? Meaning, you'll have to deserialize the json into objects whenever the UI calls for it? I mean, isn't this config file the same thing as a singleton anyway? I'd be interested in hearing how people would approach this.

u84six
  • 4,604
  • 6
  • 38
  • 65
  • Possible duplicate of [Singleton for Application Configuration](http://stackoverflow.com/questions/373626/singleton-for-application-configuration) – jaco0646 Feb 02 '16 at 02:47
  • Context pattern would help here. You load the config properties / JSON file into while constructing context. Context will strip all the necessary details and keep in memory as object with no reference to the underlying file. Do not provide any setters but only getters. Pass around this context object. – Sivaramvt Feb 02 '16 at 11:33

1 Answers1

2

One of the (many) problems with singleton is that it hides dependencies between classes. Because the singleton is universally accessible, these hidden dependencies tend to spread like a plague throughout your program, increasing coupling and hindering testing where it goes.

A better design is to use a (non singleton) class for the configuration (that may or may not reload your data upon every call, up to you), that is passed around to clients that need it. This configuration class will act as a facade for the configuration file, providing easy methods for retrieving parts of the configuration. Since there is no way for the dependencies to hide, it will soon become clear whether your design is good or not. Also, it is probably not a good idea to send the entire configuration to clients, but only the data that is actually needed. If the config changes often, it may be interesting to use the observer pattern such that clients can get notified of configuration changes.

You may also be interested in dependency injection as it separates the responsibilities between use and construction of classes (where construction is typically taken care of using a DI framework).

rinde
  • 1,181
  • 1
  • 8
  • 20
  • I don't see how your first part is any different from a singleton, other than being able to instantiate more than one object when you don't need more than one object. – u84six Feb 02 '16 at 15:30
  • Also, dependency injection just seems like like a way to set the methods, data, that each client needs rather than calling the class within the client's methods. I can see some benefits to this. Maybe easier to mock objects for unit test, but otherwise, you're just feeding the class the same reference to methods it will need. – u84six Feb 02 '16 at 15:32
  • An important difference between such a class and a singleton is that there is no way to retrieve that instance via a static method (i.e. no `getInstance()`) this means that you are actually forced to think about the design instead of accidentally coupling everything together. During the run of your app you may need only such instance, however, during testing you most certainly want to be able to instantiate more instances. Using DI you can indeed achieve a similar thing, but much cleaner, which is the whole point in my opinion. – rinde Feb 02 '16 at 15:37
  • Never mind, I've found a pretty good example here: https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab#.tq87rdlxb – u84six Feb 02 '16 at 15:48
  • For DI in Java, you can also take a look at [Dagger](https://google.github.io/dagger/) and [Guice](https://github.com/google/guice). – rinde Feb 02 '16 at 15:51