The difference between Infrastructure & Application
Recently I am finding myself writing more and more infrastructure level code. Now, there are several reasons for that, mostly because the architectural approaches that I advocate don’t have a good enough infrastructure in the environment that I usually work with.
Writing infrastructure is both fun & annoying. It is fun because usually you don’t have business rules to deal with, it is annoying because it take time to get it to do something that will give the business some real value.
That said, there are some significant differences between writing application level code and infrastructure level code. For that matter, I usually think about this as:
Infrastructure code is usually the base, it provides basic services such as communication, storage, thread management, etc. It should also provide strong guarantees regarding what it is doing, it should be simple, understandable and provide the hooks to understand what happens when things go wrong.
Framework code is sitting on top of the infrastructure, and provide easy to use semantics on top of that. They usually take away some of the options that the infrastructure give you in order to present a more focused solution for a particular scenario.
App code is even more specific than that, making use of the underlying framework to deal with much of the complexities that we have to deal with.
Writing application code is easy, it is a single purpose piece of code. Writing framework and infrastructure code is harder, they have much more applicability.
So far, I don’t believe that I said anything new.
What is important to understand is that practices that works for application level code does not necessarily work for infrastructure code. A good example would be this nasty bit of work. It doesn’t read very well, and it has some really long methods, and… it handle a lot of important infrastructure concerns that you have to deal with. For example, it is completely async, has good error handling and reporting and it has absolutely no knowledge about what exactly it is doing. That is left for higher level pieces of the code. Trying to apply application code level of practices to that will not really work, different constraints and different requirements.
By the same token, testing such code follow a different pattern than testing application level code. Tests are often more complex, requiring more behavior in the test to reproduce real world scenarios. And the tests can rarely be isolated bits, they usually have to include significant pieces of the infrastructure. And what they test can be complex enough as well.
Different constraints and different requirements.
Comments
"Writing application code is easy, it is a single purpose piece of code. Writing framework and infrastructure code is harder"
I completely disagree. Perhaps your experience with infrastructures is only for the more complex infrastructures - but if an application is complex it is hard as well. For me, at least, writing application code is harder - because it may be single purpose but that purpose makes no sense in our minds, it makes 'business' sense but it's usually a twisted piece of code, with all those little edge-cases.
Framework code is easy, because framework code makes sense.
What gets me going is people trying to write applications like they were frameworks and doing everything super-generic thinking that it will be re-used. Applications aren't frameworks and we shouldn't write them; we should extract them from working applications. Then you get "use" before "re-use".
nomorehacks.wordpress.com/.../turning-applicati...
Writing application code is easy, but reading it is hard, especially after few years. When you're writing infrastructure code, you should concentrate on exposing simple and logical API so your users shouldn't need the documentation to get started. And for application code select a tool that will make the code self-documenting because the source code is often the only documentation of application logic. Ayende, by looking at your code example I can definitely say it's infrastructure code - the code is totally incomprehensible, so you probably have been concentrating on keeping the API simple.
I'm trying to understand why at the very least that method couldn't be broken up into a bunch of smaller easier to understand methods?
Rafal,
Sort of, the code is meant to be production ready, that tend to uglify any piece of code you care to name.
Shane,
It _could_.
The problem is that then you lose the ability to yield from the method, and the way I am using async invocation here make it very important to yield at the appropriate place.
More than that, we also have another problem. If you look closely at each piece of the code, you'll see that it is mostly error handling that is taking all the space.
And trying to split the error handling to multiple functions would cause an even more probelmatic issue, because the particular error handling that is needed at each stage is different.
this is a very good conversation to have.
Another case can be made that the frameworks in particular establish coding conventions & best practice. So, anything that you do to try to simplify those conventions, or to redefine the scope of the framework, in your own application won't scale well across the organization.
Every good app developer should have their own Rhino Commons.
Cali,
Actually, not really. I'll have a post riling against Rhino Commons soon
ayende, what do you mean?
"Trying to apply application code level of practices to that will not really work, different constraints and different requirements."
do you mean don't apply biz logic to the queue because the queue is too low level... hence don't write a queue in your biz logic?
Ah really? I'm looking forward to that. Cuz I often write my own stuff like util.MyServiceUtil, wrap up some service call handling as a higher level abstraction that only me and my own biz logic need to know about and then bundle it outside of the application class structure so that it's explicit to maintainer that "hey, I like to do it this way but you don't have to!"
Cali,
I mean that in many cases, there are totally different requirements from the app code.
For example, an application can puke its guts if there is an error, an infrastructure cannot, it need to recover in a graceful way or crash in a recoverable manner.
Other constraints relates to how you do troubleshooting, monitoring, etc.
App code is things like reserve an order in a concert. There may be a lot of business complexity in it, but there shouldn't be technical complexity.
Infrastructure is usually the other way around.
Those produce different forces for the design.
weird... i typically never disagree with you ayende. i've been following your blog for over a year now and haven't really missed any of your points. Two misses in one night! Is there a ghost in my house?!
By the way that code example is nasty. It's just filthy. I love it.
Cali,
I am not sure that I understand, misses?
Cali,
The post about why I dislike common assemblies will show up on the 29th
i missed your point about rhino commons being bad and i missed your point about complexity in app code. i tend to think that complexity in app code is derived from the business & infrastructure constraints. What if the lead says "sorry, we can't support Lucene. You have to figure out how to write search into the app." They'd be telling you to do something that is bad, but it happens all the time.
ayende, I see your point though that even if you must write a search engine into your app (and you shouldn't) but if you absolutely must then you want to write it in a different way and possibly even in a different language.
do you consider writing your infrastructure stuff in C?
Excuses, excuses... :))
If I need to write infrastructure code?
Yes, it is probably going to be C#. I am not messing around with C++ again, had enough of that.
To take your example, if I need a specialized search engine (and I needed that a few times), I am going to write that as infrastructure code, one that can be later be manipulated by the app code.
The infrastructure is going to only know about searching, the app code knows the meaning
No, not really.
Reasons, not excuses
@configurator - You are absolutely right, frameworks are easier because they make sense (which is why in many projects they always end up in the App code)
@ No More Hacks
Sometimes you don't have the time to define & write the framework so it ends up in your application code.
Comment preview