I am a bit stuck with a design of a project, where many objects has to have access to the same piece of information. It could be some data, to construct a global-like object for themselves or the object itself (essentially a config object).
Essentialy these object are in a tree: On a top is a ‘Router’ object, which has ‘Interface’s, which has ‘Host’s. Router creates interfaces and interface creates hosts. Also, the router object gets that config object as parameter in constructor.
I would like to keep the code clean and easy to test, keeping the neccessary mocking at minimum and allowing easy test setups.
Which methods is recommended for providing access to this config object accross the project?
- use a singleton instance of the config object
- use a superglobal config object
- Each object (router, interface, host) should get the config object via the constructor -> in every new object calls there should be this config object. It would be like: Host->new({config => $self->config})
- Each object should have a reference to the parent router. Interface and Host will have access to the Router (which will be passed to them in the constructor -> weak_ref to the main Router object), and they will access the router’s config object
- Interface will have a delegate method to retrieve the config object from the router and Host will have access to this config object through this method -> this implies, that everyone should be aware of it’s parents (host should have a reference to the parent interface, interface should have a reference to the router etc.)
- Or maybe have a singleton global object-storage, from which everyone could retreive what they want (config object, database handle etc)?
- Or use some existing dependency injection system, which seems like an overkill (a lot)
My vote is for managing the dependencies through the constructors of your classes (#3). You can use whatever mechanism you feel is appropriate to generate the config object.
Handing your objects their dependencies through the constructor is essentially a poor man’s form of Dependency Injection. The only thing you will miss by not having a DI framework is the ability to have centralized configuration of your dependencies. You will not need this unless your system is large and you have to manage many dependencies.
1