Live data from Hacker News

The inverse of IoC is Control

comoyo.github.com

51–60 of 66 posts

Re: The inverse of IoC is Control

#51

Java culture (IDE-dependence, AbstractFactoryVisitorFactory patterns, Maven and XML monstrosities) is hideous. It's based on the idea that reading code is a lost cause. You can no longer trust code, so you need all these wonky tool configurations to compensate for the fact that you're trying to make an army of inept programmers build something that is (unless it fails) going to become the next generation's legacy blo…

I think the issue is that there is no such thing as Java culture, there is Enterprise culture which is responsible for all that you said above. But there is a start of a new "Java culture" which is encouraging, see what Google did with Guava, see the Java version of Play framework, even Spring framework 3+ is not that bad, no XML, all annotations, JPA is nice as well. Look at stuff done by Yammer, Twitter, Google and other Java/Scala based companies.

I wouldn't go and dismiss one of the most popular Enterprise frameworks, as a user of Spring / Hibernate for last 7+ years, it makes a lot of sense to me in the enterprise context, just like Ruby on Rails and Play Framework makes sense to me in the SaaS contect, for instance, having Play framework with a Spring module is a nice interim solution for bringing newer technology to the enterprise world.

It all depends on what you need to be doing. Spring is great for a large enterprise app, that have long lifetime, needs to connect to legacy stuff, needs common enterprise integration patterns etc.

Also if you check SpringSource latest stuff, you'll find out they are investing in lot's of cool new things, e.g. the scripted text editor - (https://github.com/scripted-editor/scripted/) and are influenced a lot by the Rails, Django, Node.js and Play communities.

The enterprise world is not that stupid, it's perhaps just a bit behind but it's still making tons of money from it's software, in billions, and it's more likely to be written in Spring / Hibernate than with Rails / ActiveRecord.

Just give it some time and patience.

Re: The inverse of IoC is Control

#52

I have found that in a lot of cases IoC ends up being completely misused and abused in really horrible ways. One of the more common antipatterns I encounter is creating an interface for every single thing in the application ("because hey, the implementation might change and it'll be easy to swap out"). No, if you're building a webshop or a task management application, abstracting and injecting your business logic or…

> creating an interface for every single thing in the application

Ditto turning everything into a "service" a la WSDL and now SOA. CORBA lives!

Re: The inverse of IoC is Control

#53
post #20
post #17

Most places I have seen DI frameworks being used, they solve a problem the programmer shouldn't be having in the first place.

Interesting. Do you mind expanding on this? What problems were they trying to solve?

I don't buy that wiring up code explicitly in plain old java without the help of an injection framework is as painful as some people seem to think -- and if it really is: I suspect the reason is bad design or that they just haven't given the problem much thought. That happens.

If people need the assistance of a framework to wire up their application, it is probably because the API design sucks ass and there are too many moving parts the programmer is forced to pay attention to. (And when I say API design: all code design is about APIs -- every time you create a class or an interface you are creating an API of some sort). Good APIs hide and abstract. And good implementations take care of things you don't need to see or know.

And I say if, because most of the time, applications are not so complicated that you need help to manage wiring them up. Most of the projects I have worked on the past 15 years can usually be wired up in less than 40-50 lines in a Main.java. I have worked on some projects that needed considerably more, but interestingly, managing that code was never a problem.

Explicit wiring you can read from start to finish beats vague declarative shit that you may be able to figure out if you pay close attention.

Re: The inverse of IoC is Control

#54
post #48
post #47

IoC is automating the code required to wire up objects that are properly decomposed. When you spend a long time learning how to effectively work with static languages, a few things come out. Dependency inversion and composition. Where does this leave us? It often means we have classes that need one or more other objects when they are instantiated. This often results in chains of objects. For example, new Repository(n…

> new Repository(new SessionFactory(new Configuration())) > Writing that code is pretty painful. If you think you are making things less painful by obfuscating the code snippet above I would challenge you to think about what you are doing. The above is incredibly clear. There is no doubt what is happening and if you screw up the compiler will yell at you. If you obfuscate it through annotations and force readers of y…

You don't annotate anything. It simply becomes the following,

  ...
  public Repository(ISessionFactory factory)
  ...
The repository never knows about IoC or where things come from. Nor should it.

Re: The inverse of IoC is Control

#55

Earlier quoted context omitted.

Always love all the Java hate on ycomb. I'm not sure how a dynamically code hotswapping Ruby app with 10k classes and 1k domain objects works, but I suspect many of the same patterns emerge as have been solved in Java.

Large single programs should almost never exist. There are exceptions, but the typical bloated business app is not one of them. Managerial idiots like overambitious single-program IT projects because it makes it easier to allocate "headcount" when the programmer-to-program relationship is inverted (many programmers to one program, instead of the right way, which is one programmer working on many programs). The truth…

Large networks of small programs fail in exactly the same way: static typing fails on versioning issues (an RPC call carries inherently less type information than a function call) and compile-speed problems (compiling 200 small services can take just as long as compiling one behemoth). We also don't have mature tooling for the "network program" you're talking about.

I don't know what your metric of "large program" is, but AAA games often weigh in at 10-100 million lines and are typically architected as a single large codebase with auxiliary small programs, and doing them any other way is not a sensible approach.

Re: The inverse of IoC is Control

#56
post #53
post #20

Earlier quoted context omitted.

Interesting. Do you mind expanding on this? What problems were they trying to solve?

I don't buy that wiring up code explicitly in plain old java without the help of an injection framework is as painful as some people seem to think -- and if it really is: I suspect the reason is bad design or that they just haven't given the problem much thought. That happens. If people need the assistance of a framework to wire up their application, it is probably because the API design sucks ass and there are too m…

Thank you for clearing that up, much appreciated.

I also noticed that most of the time the container tends to be used as a Service Locator indiscriminately around the code base, which tends to create more problems than it solves. On the other hand, I think it is a good refactoring step if your plan is to eventually move all the composition logic at the entry point of the application.

Coming from .NET, I tend to do the wiring as close as possible to the entry point as well, but I still use a container because it makes object lifecycle management much easier, and with convention over configuration it is trivial to associate interfaces to implementations: this not only reduces wiring up code for complex applications to a few lines, it also makes the rest of the application container-agnostic, which is quite cool.

Re: The inverse of IoC is Control

#57
Sure you have to use it where it makes sense, but IoC containers and frameworks like Spring can really make things easier. If you have to talk to anything complex (pick your messaging poison), need to keep transactions across these items, need to run under multiple different web containers and swap out configuration you are going to have some messy code to handle all of this sort of stuff. For enterprise integration problems I will pick Spring any day. For instance I can write a complex messaging bridge between two different messaging systems using nothing but some xml configuration. The mess of doing all the JNDI lookups, getting all my XA transactions right, handling firing messages after certain things happen all can be done without explicitly putting things all over the code. The beauty of IoC containers and AOP programming is that you can mix in a well tested piece of code across all your application with minimal effort. You can mixin authentication, transaction management, request cleanup, caching, etc. without making major changes to your app.

I know there are many people here that might crucify me for the opinion but I call bullshit. They just have never had to work on something sufficiently complex where IoC and frameworks like Spring can become a huge time savings. Obviously with any tool you have to make sure you don't chainsaw off your leg, and its really stupid to do certain things with any tool. The black magick of aop and IoC can make reasoning about things a little harder, but the shear power of the tool makes solving hard problems in complex applications tractable. Try auditing transaction management in an application with 10 thousand tables written by hundreds of people of various experience levels. Or just use spring transactions and inject the well tested behavior across the entire application.

Re: The inverse of IoC is Control

#58
post #54
post #48

Earlier quoted context omitted.

> new Repository(new SessionFactory(new Configuration())) > Writing that code is pretty painful. If you think you are making things less painful by obfuscating the code snippet above I would challenge you to think about what you are doing. The above is incredibly clear. There is no doubt what is happening and if you screw up the compiler will yell at you. If you obfuscate it through annotations and force readers of y…

You don't annotate anything. It simply becomes the following, ... public Repository(ISessionFactory factory) ... The repository never knows about IoC or where things come from. Nor should it.

Oh yeah, because pure magic makes it so understandable.

Re: The inverse of IoC is Control

#59
post #56
post #53

Earlier quoted context omitted.

I don't buy that wiring up code explicitly in plain old java without the help of an injection framework is as painful as some people seem to think -- and if it really is: I suspect the reason is bad design or that they just haven't given the problem much thought. That happens. If people need the assistance of a framework to wire up their application, it is probably because the API design sucks ass and there are too m…

Thank you for clearing that up, much appreciated. I also noticed that most of the time the container tends to be used as a Service Locator indiscriminately around the code base, which tends to create more problems than it solves. On the other hand, I think it is a good refactoring step if your plan is to eventually move all the composition logic at the entry point of the application. Coming from .NET, I tend to do th…

> t also makes the rest of the application container- > agnostic, which is quite cool.

Not least because containers have a tendency to fall out of fashion. For instance if you suggest using Spring for a large project now, people will queue up to punch you like a meat pinata.

Re: The inverse of IoC is Control

#60
post #47

IoC is automating the code required to wire up objects that are properly decomposed. When you spend a long time learning how to effectively work with static languages, a few things come out. Dependency inversion and composition. Where does this leave us? It often means we have classes that need one or more other objects when they are instantiated. This often results in chains of objects. For example, new Repository(n…

Everything you're saying is true. But so is a lot of what the author said. Especially in the last section.

I've run into situations with Windsor along the lines of what he describes, and it really is a distressing situation to be in. You're happily coding along, whipping the project together, hacking decorators, auto-registering everything with a great set of conventions, and generally having a grand old time. And then something goes kachunk and suddenly it's damn near impossible to figure out how to tell the container exactly how everything needs to be wired up without creating a raft of custom dependency providers to deal with special cases that the container just wasn't designed to handle properly. And the configuration becomes increasingly diffuse, devolving into a mishmash of conventions, manual registrations, and registrations that are implied by custom implementations of IFooResolverProviderFactory, until eventually you realize that you're working with a modern-day edition of what Dijkstra was talking about when he wrote GOTO Considered Harmful. And at that point it might be time to tearfully say goodbye to the IoC container and hand code some abstract factories, because not only will they be less opaque but you'll soon discover to your own horror that they actually reduce the SLOC count.

But - butbutbutbutbut - where I depart with the author is in thinking that this means that IoC containers are bad. Quite the contrary. Avoiding an IoC container because your dependency graph might, just might turn out to be more complicated than what the container was designed to handle is a premature optimization. And will probably lead to worse code than what you'll get if you start out with an IoC container and are forced to give it up later, since using an IoC container really does encourage SOLID code.

I guess what I'm saying is, IoC containers are only "mostly amazingly great." It's still a young technology with some kinks to work out. Even venerable old Windsor is still experiencing significant API flux. They don't necessarily have an answer to every use case yet, even if they are getting damn close.

Oh, and writing libraries. If you're a library, you are not the composition root, by definition. And if you're not the composition root, you don't get to use an IoC container. Sorry. Have a facade.

Post reply on HN