Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The Dependency Inversion Principle in the Wild (martinfowler.com)
65 points by henrik_w on May 1, 2013 | hide | past | favorite | 33 comments


I thought it was just Martin but apparently my lack of being able to quickly grok these articles extend to the contributors on his site. There has got to be a way to communicate the kernel of what he's saying without pedantic language, lots of acronyms, and way too abstract language.


Use of stupid jargon is strongly correlated with fuzzy thinking; sometimes, particularly where there's a dollar at stake, confusion is the intent.


I've met Martin Fowler. Super nice guy. I don't question his intent.

It just seems to me that "software architects" see the world in abstractions. Another friend calls this world view "enterprisey".

Fowler and I would likely agree on the principles of reducing the cost of change, DRY, YAGNI, etc.

But we wouldn't agree on the mechanics for achieving those goals.


I don't have an opinion about Fowler, but whenever someone is pushing this sort of bafflegab, it can be a useful exercise to ask them: why can't you speak simply and directly? None of these concepts are difficult -- it's not a lecture on topology or Lie algebras or something. So why so much impenetrable jargon?


Totally.

My thesis is that some people truly think that way. What I find to be obtuse, obfuscated, tortured, overwrought is apparently pure poetry to others.

On the flip side, I know that how I work drives many other people absolutely nuts.


My summary:

Your code should not deal with things at a lower level of abstraction than itself. External libraries tend to expose lower level interfaces than you need (because the API needs to be flexible enough to deal with a variety of use cases) , so build an abstraction in the middle between your code and the library that gives you exactly the functionality you need and nothing more.


The TL;DR is there are two levels of code high level domain relevant code, and low level implementation specific code. Your high level code should depend on interfaces not the low level implementation specific code. It is kind of no shit these days but it was the first cave man to add smart back when it was introduced.


Huh! are people still stuck on this? Yet another post that justifies this comment[1] James Shore made about 7 years back: "Dependency Injection is a 25-dollar term for a 5-cent concept"

[1]: http://www.jamesshore.com/Blog/Dependency-Injection-Demystif...


I just skimmed the original article and found it relatively opaque, but it specifically states that it is talking about something distinct from dependency injection.


I agree about the distinctness and the opaqueness of the article, but I find that the Fowler's dependency injection article is relevant because dependency inversion is similarly a $25 word for a $0.05 concept, and similarly described pedantically, opaquely, and poorly.

Articles like the dependency injection one are why I shy away from the Java community; pedantry about simple concepts that should be obvious good design indicate to me that the point really needs to be pounded home in the community due to widespread bad design. It can be nice to have terms to refer to different practices, but it just seems too much to me. That said, I know lots of good developers who use Java a lot, and I guess it's a good way to get a lot of mediocre programmers to make maintainable code.


why I shy away from the Java community; pedantry about simple concepts

Agree.

Please note the cultural context. Java, XML, design patterns, and enterprise (CORBA, MQ) all hit about the same time. So there was a temporal grouping for all those things.

I started a design patterns study group about 15+ years ago. (It continues to this day. We've covered many other topics over the years, including SICP, concurrency, HTML5, computational intelligence, etc.)

There was no bigger fan of "design patterns" than me. Now, I think learning "design patterns" are a phase of a developer's maturity. Kind of like only a master jazz musician knows how to break the rules of jazz.

Unfortunately, it's hard to expunge (deprecate) bad ideas. For many, it's simply easier to get a fresh start by adopting a new language, tool stack, community.

Java is a pretty good language. What it needs is a do-over. What would Java look like today, following the original principles of the Oak Team?


Disagree.

Have a look at more modern Java; for example Acteur[1]. Guice and a focus on annotations have dramatically reduced the annoying boilerplate that used to surround EJB. Spring appears to be on the way out, which I think everyone can be thankful for - although the latest versions of Spring are starting to become quite good now, so maybe it will survive.

Plus with the way Android is going, if you want to write something that actually runs on the devices you own, you'll want to know Java. ;)

[1] https://github.com/timboudreau/acteur-tutorial


Quote from a buddy of mine:

"Dependency Injection is great. For the 6 to 8 classes you need to wire up! In which case, why would you need a framework?"


I like the Logger example. Logging is the Vietnam of Java.


I read it and I don't quite understand it. Many of Fowler's articles have a point where it just clicks and I want to rewrite my code (I'm looking at you event sourcing), but this one didn't. Both the logging and database examples made perfect sense, at this moment I can't relate it to the overall concept


1. None of your objects should know how to create objects from other modules (just in case you happen to need the flexibility later).

2. Everything used in the same place should use the same set of concepts (aka "level of abstraction", even tho abstractions can't always be split into clear levels).

So instead of your code knowing how to do something simple like create and use a database connection, you pass it a wrapper around a database connection and have it know how to use (but not create) that instead.

I'm not entirely clear on where the inversion-of-control (framework vs library) part fits in tho...


Do the two examples connect as part of a common theme for you?

To me they seem related as in both cases you're ensuring that each part of the code only has to deal with functionality it directly cares about, through interfaces that ensure that it isn't overloaded with extra information.

(I hate the name though. Because that's never clicked with me at all.)


How is that different than the Gateway pattern that he mentions in the logging example?

Lets say I was going to ship something building on what this article talks about. Instead of interacting directly with my shipping objects (Fedex, Usps, etc), I'd write a common interface for them (ShippingGateway). In addition Id need so sort of mapper for each shipping object that would translate my ShippingGateway calls to the respective object (FedexMapper etc).

My code would eventually look like:

    shipping = new ShippingGateway(...)
    estimate = shipping.estimate(address, 'fedex', ...)
and that should never have to change only the mappers and objects themselves would. What am I missing?


It's slightly more.

Your code wouldn't create it's own ShippingGateway - it would be passed in (or "injected"). That Shipping Gateway could be a RealShippingGateway (for when the application is running in production) or a MockShippingGateway (for unit testing), or some other variant for when your test users don't want to actually ship things. It doesn't matter which of those it is to the object it's passed into, all it knows is that it has a ShippingGateway, and when/how to call it.

So it's Adapter Pattern + Interfaces together that matter.


Makes sense. So basically this is DI for adapters/gateways?


That's my understanding. But I'm not 100% I haven't missed some subtlety.


Click through the gateway link. Notice the direction of the Arrows. Your high level code is still directly dependent on the current low level implementation. The "Gateway pattern" is nothing more than create an abstraction so your code can work with domain concepts instead of directly with the API.

Now look at the arrows in the DIP example. There is an inverted arrow by comparison to the gateway diagram. This is because you have inverted the dependency so that your high level code no longer depends directly on the implementation.


It's gibberish.


Dependancy Inversion seems to be used even in situations where it's unlikely that it will ever be needed [1]. This often makes code harder to follow through (as each jump may go through dozens of layers of abstraction).

[1] http://c2.com/xp/YouArentGonnaNeedIt.html


A recent discussion with co-workers led me to produce this screencast [1] to try and grok the Dependency Inversion Principle and Inversion of Control (IOC) in the realm of front-end code.

[1] - http://www.youtube.com/watch?v=mU1JcPikdMs


I'm not familiar with Backbone.js so I think some of the "ah-ha" was lost to me. I thought it looked more like bug fixing since the first method without Dependency Injection didn't work entirely and Dependency Injection should as I understand it just make code more flexible.

The comment on zeroed setInterval's clearing the stack were appreciated though, something I'll keep in mind.


Yeah it is definitely more context-specific inside the realm of Backbone.js and Browser Quirks; thanks for watching :)


Note that despite being on martinfowler.com, this is an article by Brett L. Schuchert, not Martin Fowler. I only noticed when the article cited 'Martin Fowler' as someone else on something. Although I had been thinking, gee, I don't find this nearly as clear as I'm used to from Fowler.


Not being a coder, I read only the synopsis and then thought about how it applies to life generally. On example I thought of is how your product should not depend on a "guru," unless that guru is the product.

I wasn't confused by the rest because I didn't attempt it.


I think I need to write up the Dependency Perversion and Perversion of Control antipatterns one of these days... after all, they're far more applicable to real-world software development.


It's kind of sad to see this kind of things on martinfowler.com. Clearly when it comes to writing about writing code without writing code, this guy is far less effective than Martin.


Superfluous verbosity as my old chemistry teacher once wrote on my paper :-)


I think the only thing this article is lacking is a competent editor!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: