Uncle Bob stirs the pot again with "Dependency Injection Inversion"

Injections can hurt

Uncle Bob posted what was considered a rather controversial blog post, which basically pointed that just because Dependency Injection is a good thing, does not mean you cannot shoot yourself in the foot with the DI framework. He drew attention to the fact that these frameworks in their desire to be more usable have all kinds of bells and whistles, which you might just stop and think about before you jump in and start using them.

My initial reaction to this post was very positive since I always have considered the DI container something external and (potentially) replaceable. Looking from a DDD point of view (I tend to look from that one, don't I? ;) it is infrastructure which is not central to my apps, which means it should not be meshed with my core code. Hence my tweet:


I liked the point he made: you see, you can do Dependency Injection without a container. I would add, I think everyone who is doing Dependency Injection should do an exercise once in a while - write a small app without a DI container. There are two points in this exercise: one - to make sure one remembers the point Uncle Bob made, and two - to appreciate the DI containers.

Towards the end he says:

Most of the time the best kind of Dependency Injection to use, is the manual kind. Externalized dependency injection of the kind that Guice provides is appropriate for those classes that you know will be extension points for your system.
Not so sure how I feel about this one though. Most of the time I do use DI container unless the app is very very small, but unless I try I will never know, right ;)

Interestingly enough the .NET alpha-geek crowd jumped(and again and again) Uncle Bob on this one. Agreed with him for the most part and bashed him for the quote I just mentioned as well as for his example being too simplistic. I feel they are being a bit arrogant(bashing the Java tooling and all that) but they do have a point though. What do you think?

24.01.2010 | Comments [0]
Flokkur: Agile | Forritun | XP
Höfundur: Petar Shomov

Lessons learnt the hard way

I just got off a large project that one of our customers is running. I will not go into details but it should suffice to say that it is a rather large multi-phase project that is supposed to create the future IT backbone for that customer. Before I move on I though I should stop and analyze what we did right, what went wrong and what can I learn from this experience. And I thought I would share it with you dear reader ;)

1. Deploy by the end of the first month to a user
In large companies there are usually many reasons why a project cannot be deployed: dependency on another project which in turn depends on another project and so on, or someone has to get legal approval for something to be released. Yes, there are many excuses not to deploy, but in the end that's all they are - excuses. The business needs to see value, your team needs to get feedback from real users about the system otherwise you are risking building something no one is interested in and/or the business people loosing their business patience. My future rule of thumb would be - if you have not deployed to actual users by the end of the first month of the project, you need to do get angry and demand this to happen right away.

2. Do not accumulate technical debt, push back on Product Owner who does not understand technical debt
Technical debt(from here on referred to as tech-debt) is hard to explain to product owners that have not programmed. This is understandable and there is no easy way around it. We tried all kinds of metaphors but I don't think we succeeded in communicating what tech-debt is and why it is important. The best approach that I can see working is to negotiate a slice of each sprint to go into paying off tech-debt and demand extra on top of that at the first sign of trouble. Letting it pile and telling yourself that it is ok, that you are going to fix it "later" does not work. Never has, not for me. "Later" the debt is usually so big and the bad stuff has usually spread all over the place and fixing it becomes an all-or-nothing mini-rewrites that are very hard to do and are rather unpleasant and unsatisfying experiences.

3. Do not allow architectural astronauts to tell you what tools to use
It is a strange phenomenon but seems quite persistent: a company becomes mid-sized and someone decides that now they need to unify "how we do things around here". And then an Architect (may be even Chief Architect) is appointed who starts googling and creating a list of tools and technologies allowed to be used. And this is the moment when you start to be told what tools to use to do your job by the guy who has never done your job or it has been a while since he has last done your job. Do not let this happen, say "no" to company politics and demand that you decide what tools to use. The list of tools should be coming from you and the rest of the guys that are working in your organization. Architects can be valuable, but this is not the way. Do not buy into tool vendors based on power point presentations and one day carefully orchestrated demos from the salesman. You and your peers should be making the standard in your company. 'nough said.

4. Manage expectations so that they are achievable
I have come to appreciate marketing as a *very* important aspect of product development. The same product may be perceived as two complete opposites depending on how its being marketed. One thing that I've found out is not wise, is to proclaim that your product will be a universal panacea that will fix all there is to fix. This might sound obvious and plain common sense, but I am mentioning it for a reason: the larger the promise you make, the more difficult is to keep it. So I would advise to do small achievable projects and build software products incrementally and iteratively. And the product owners have always to be on the lookout how to generate value with minimum effort.

Well, I am off to the new project ... ;)

02.10.2009 | Comments [0]
Flokkur: Agile | Forritun | Scrum | XP
Höfundur: Petar Shomov

Soft as in "Software" - part II (The Fear of Change)

In my last post I described my epiphany about the way the business looks at IT (or at least one very possible look) and left off just before I described the common reasons for delivering crappy software. So here they come:

  • Fear of change
  • Rigid structure

First, and probably foremost, is the fear of change. The uncomfortable feeling every one of us has felt at one point or another (probably more likely at a lot of points, but may be that's just me ;) ) in his career when he has to change something in code that has been in production. Will it work with all the other components that are deployed? What about the bug that we fixed last month, does it affect the fix in any way? What will happen if it does not work, can I go back to the old version of the code?

These are all questions which we are often quite uncertain about how to answer. How can we eliminate this discomfort?

By building quality in our products and continuously inspecting them for that quality - with unit testing, integration testing, and acceptance testing.

Having nailed down the behavior of your software this way gives you a lot of confidence and eagerness to continue improving and developing your software. Do the green bars mean that you are 100% safe? Definitely not, but now you have a base which will free your mind from trying to remember all the little things you need to make sure your software works as you expect. If you take the time to keep this base growing as your code grows it will allow you to go quite far. The alternative I have seen is where you reach a point where you cannot go any further and remain sane, and then it is time to start over (or the "big refactoring" comes ... ). Time for the bullies to go asking for investment in rewriting.

Next, the Zen of software development ...

15.12.2008 | Comments [1]
Flokkur: Agile | Forritun
Höfundur: Petar Shomov

Dude, where's my C# for the Java Virtual Machine?

 

C# 3.0 has gotten some great new features that are making the language so much more expressive. Two of my favorite are extension methods and lambda expressions. So now, people have started creating all kinds of crazy extension methods to the built-in type String and every other CLR class.

Last week I was working on this Java project and doing some logging as part of my work, and was getting rather annoyed by the idea of having to check the logging level just before every darn log statement. And then I remembered that the same was true for the .NET equivalent of log4j, but in C# you could do so much better. So I decided to sit down and get some C# lovin'. First, just to be sure that you dear reader understand what the issue really is, here is how typical logging is happening using log4net:

    1 private static void LegacyStyleOfLogging()

    2 {

    3     ILog logger = LogManager.GetLogger(typeof (Program));

    4     if (logger.IsDebugEnabled)

    5         logger.Debug(String.Format("The result of the method is {0}", RetrievesSlowData()));

    6 }

Now, that thing on line 4, that is the nasty check I was talking about earlier. It is there purely as an optimization in case the debugging level is set to something higher then "DEBUG" in which case, since the log statement will not be rendered anyway, the logging string will not be evaluated (you do not know how slow that RetrieveSlowData method is, looks pretty slow to me ;) ). So all in all, I understand the reasoning, it's just that I do not want to do it ;).

Enter extension methods! Without further ado here is my extension method for log4net:

    1 public static class LogExtension

    2 {

    3     public delegate string RenderDelegate();

    4     public static void Debug(this ILog log, RenderDelegate renderer)

    5     {

    6         if (log.IsDebugEnabled) log.Debug(renderer());

    7     }

    8 }

So not a lot of code for the extension, basically just an overload of the Debug method which accepts a delegate as its only parameter. The new overload checks for the DebugLevel and only then invokes the delegate which is supposed to evaluate the log message.So let's see how it is being used:

    1 private static void NewShinyStyleOfLogging()

    2 {

    3     ILog logger = LogManager.GetLogger(typeof (Program));

    4     logger.Debug(() => String.Format("The result of the method is {0}", RetrievesSlowData()));

    5 }

So now looking at line 4 you can see there is no checking whether the debug level is "in scope". What you can also see in line 4 is the other new element introduced in C# 3 that I mentioned earlier - lambda expressions. They can be automatically converted to delegates and are extra terse and I think that's what makes this approach feasible. This one has no parameters, thus the strange looking opening and closing braces before the "=>" signature.

With a little bit more effort one could easily add an exception parameter and implement all this for the other levels of logging. And all this without modifying the existing (dare I say ancient) log4net.

You might be wondering if I just put too much effort into saving me a line of code. For those of you who do, I just have to point out the following benefits:

  • this line shows up way too often
  • there is less noise in my code
  • now I can free my mind from having to remember to put in this check
  • it is always there, guaranteed

So, I wonder how long we will have to wait for JSR-666 that will introduce C# for the JVM ;)

26.09.2008 | Comments [6]
Flokkur: Forritun
Höfundur: Petar Shomov

Agile developer tooling

If one picks any of the popular software development languages these days he could easily be dazzled by the wide variety of libraries and frameworks available for that language. In the Java world he would shortly after be also quite confused since most of these libraries take on the same problem but each one with its own little twist. That is especially evident when it comes to UI libraries and frameworks. But what I want to do here is not complain about the library-per-capita phenomena in Java land, but rather draw your attention to two specific (and rather well known) libraries and frameworks. The reason I want to do that is the smooth unobtrusive way they make it easy for me to develop the agile way.

The first one is the famous Spring framework. I noticed it has had quite the effect on my mindset while I am writing code. No longer do I worry about who and how exactly I'm going to get hold of those objects. I know it is not going to be a problem, so I just completely focus on the POJOs and when I have enough of them ready to do something meaningful, then I wire them up using Spring and the thing comes in motion very quickly. Another change in my mindset that is a direct result of using Spring I noticed is I started writing smaller, much more focused classes. I mean since now wiring them together is so easy I really started doing it relentlessly. The application ends up usually with just 2-3 lines of Spring specific code (that is when I am using the Dependency Injection container only, using other parts of the Spring framework is a different thing) so there are no strings attached really (no pun intended ;) . I find myself using the DI container part of Spring the most, but I use other parts of this excellent framework occasionally: AOP, Hibernate integration and just now - Spring Portlet MVC. These allow for using and learning the framework on-demand and gradually, no big bang knowledge transfer required. I really like it ;)

The other library I want to draw your attention to is the no less famous Hibernate. The database indifference it provides I find is not its most attractive feature (although I certainly do appreciate it). Hibernate was the first library I know that successfully implemented persistence ignorance, allowing me to write the core logic of the application with no concern for the database. Only after I had a prototype of the system, I decided to add "real" persistence to a database. With Hibernate it was really easy and more importantly the patterns that this library is encouraging go a long way towards creating maintainable applications. And if you are trying to explore Domain-Driven Design (as I am trying to do), Hibernate will fit right in.

One special note for guys who are doing development in .NET and Java. Since there are ports of both Spring and Hibernate to .NET, using these frameworks allows for really nice reuse of knowledge across platforms, something I personally have experienced since I come to Java from .NET.

24.08.2008 | Comments [2]
Flokkur: Forritun
Höfundur: Petar Shomov


Agile smagile!

Er blogg um Agile, stjórnun, tækni, forritun, gæðamál, fyrirtækjarekstur og fleira sem okkur langar til að skrifa um.



Eldri færslur

<July 2010>
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Innskráning

Sign In