Wednesday 8 April 2009

Dependency Injection

I was thinking about adding DI support to agent-ohm instead of the getModel('somecode') registry style pattern. The problem is, it's a lot of call_user_func_array() calls for every new instance.

It's made me realize that the real problem is allowing any class to be overridden at any time. Allowing this level of functionality complicates every decision and it has to go. There is a balance between overriding objects and forcing the developer to re-implement logic. Neither of them are particularly good solutions to the problem of "I want to change this behavior."

Overriding any class file in the system seems nice at first, but what happens when you have two 3rd party modules both wanting to sub-class and override the core "Product" class? You get a conflict. It's the same problem whether you use DI or config files to determine the actual class name to instantiate at run time. At it's heart, dependency injection is a 1-to-1 mapping, when really you need a 1-to-many plugin system to allow mutliple customizations to the same logic.

DI might be good in some instances, for allowing new product types to be loaded, or selecting custom shipping routines. Perhaps DI could/should be used as a part of a chain of command pattern to allow dynamic plugins to be added to any chain.

Either style of DI should be used judiciously - too much flexibility and the code base becomes flabby and undefined.

"If everything is permissible [and] nothing offers me any resistance, then any effort is inconceivable [and] every undertaking is futile." ~Igor Stravinsky

No comments: