Wednesday, January 30, 2008

A legacy application: the story of the fridge and the oven

Today I'll tell a story which inspiration comes from an overheard conversation.

The situation: you have a legacy application which you use in your organization to provide services to your customers. You have no tests. It uses proprietary libraries. Layers are nowhere to be seen. A simple change requires a gargantuan amount of code. And sweat. And chills down your back. You know it will not be able to provide the new services the business needs without a huge architectural and model change.

A possible solution: start a new project adopting an agile and iterative method, focusing on the most important architectural aspects (an UP practice) and on the most valuable features (a practice you find in many methods). Incrementally substitute the old system with the new one (an EVO practice).

The solution from the management: learn everything there is to learn about this application: it is one of our assets, and as such it must be considered. When your experience is consolidated, we'll reuse the same framework for all our new projects.

You can consider this story from two different points of view. The manager, who has no development experience or knowledge, thinks that the problem lies in the team, and fails to acknowledge all the signals the team is giving him. He is afraid and wants to keep things under control. After all, if we have provided the service so far we can go on just as well. Why venture into a new project, with all the risks that new technologies imply, first of all the team's inexperience with them? Another perspective: the management might have dealt a sale of the product within a very short time frame - this might be a confidential information - and he knows - or he's afraid that - the team will not be able to deliver on time.

In each case, most of the times an honest conversation between the management and the team can lead to find a good, if not the best, compromise: a classic win-win strategy.

One last (funny? tragic?) note: the project manager, trying to explain the problem to the management, provided this metaphore :

"Look, we have this huge refrigerator. You need an oven. You're asking me and the team to learn how this refrigerator works, so that we can embed the oven within it. What we really need is a power plug which can work for the fridge and for the oven. Why would you need a fridge to roast a turkey?"

The answer:

"Your oven will have frosting features, which no other oven has. That will be a significant competitive advantage."

Tuesday, January 29, 2008

Which JDK?

More a personal reminder than a real entry... anyway, should you need to start NetBeans using a particular JDK you can modify the netbeans_jdkhome variabile in file IDE_HOME/etc/netbeans.conf; the procedure for GlassFish is similar, as you have to modify the AS_JAVA variable in file AS_HOME/config/asenv.bat.

Monday, January 28, 2008

Where do you (want to) go today?

This morning, like almost every working day, I sat at my desk and wrote down a list of activities, then started my first pomodoro (see here for more informations). Then I got a lot of unmanageable interruptions, and all my good intentions vanished away (CIO beats planned activities list for the nth time running). That lead me to think, once again, how we manage our time and how we're too often distracted from our real objectives.

Objectives can be divided in fundamental, qualifying and desirable. Fundamental objectives often span over a long time period, so we have the tendency to have an "I'll set it aside and deal with it later" attitude. We MUST ensure that our fundamental objectives are reached; qualyfing objectives help us get there, and desirabile objectives are... desirable, but expendable.

Our daily activities fall in two different categories: urgent activities and important activities. Too often we get distracted by urgent activities, which seldom get us closer to our objectives; one common mistake is to decide to deal with all the small urgent matters, "so we'll get rid of all this unimportant stuff", and to postpone important activities. Than can happen for various reasons, but it does happen. And in the end of the day we're not closer to what is really important than we were the day before. Sounds familiar? you're in good company.

We must learn to recognize which activities are important to us, and to delegate or reject the others. That is particulary important if you have a management position: for example, if one of your collaborators comes in your office with a monkey on her back, she must get out carrying the very same monkey. That does not mean you should not help her: you should give everyone the support they need to carry on, but you must not do their job. As a manager, you "manage". And coach, and mentor, and support, and many other things. That will help your collaborators to grow, and they will also know you trust they will get the job done. Learn to prioritize activities not by their urgency but by their importance. And, most of all, keep some spare time in your daily plan to extinguish all those little fires. If you follow these simple rules, your time management will be more effective, and your productivity will improve. Unluckily, sometimes you just have to cope with the circumstances: we cannot avoid all risks, but at least we can reduce threats to our objectives.

The activities I had to perform today are of no importance to me, but they have a great importance to someone else. Someone you can't say no to. That's where the spare time comes in action... I satisfied my manager and went on with my own list. I had to "sacrifice" some of my time, but in the end the outcome required by my fundamental objectives will not be far from the expectations; that also helps you to schedule your activities in such a way to respect your deadlines.

"Deadlines? I love deadlines... most of all, I love the swooshing sound they make as they go by"

Friday, January 25, 2008

Agile budgeting

How do you build a plan for a new software project? There are different approaches, each of which has its peculiarities; I shall discuss them shortly.

Agile teams are very well aware of the fact that requirements do change, so they don't try to prevent it but ride the wave, focusing on delivering, iteration after iteration, the highest priority requirements: they are happy because they will deliver high quality software, they know their customers will be happy because they will steer the project according to their evolving needs... and they lived happily ever after. Until they talked to the management:


I'm exaggerating of course, but I'm sure you get the point. Well... OK, that's what we'll do: we shall meet the customers, explain to them how they will get only the functionality they really need, how they will always be in control, how they will decide how their money will be spent, and all the other advantages of an agile incremental and iterative approach. So they will talk to our management, persuade them, and tell them they are really enthusiastic with our proposal and that we should get a considerable pay raise. Actually they go more or less like that:


Well, we have to reconsider... Agile approaches are really great, but the difficulty lies in persuading a traditional management. Let's take it from their own point of view.

In a traditional approach you spend a lot of time to write a long (and when I say long I mean very, very long) and comprehensive requirements document - which probably no one will ever really read - which in turn is, more or less, accepted by the contractor. At this point you have already invested a considerable amount of resources, but project managers have enough informations to precisely schedule everyone's work for the next months, and that allows them to estimate a fixed price. That makes the management happy because they think they are dealing with the risk of scope creep in an effective way, and customers happy because they know in advance the amount of money to allocate for the project.

That sounds great. But let's face the facts: studies show how 19% of the initial requirements are only rarely used, while 45% are not used at all. And the requirements have changed. They have changed a lot. But the plan did not. So, when the project comes to an end, customers, which have paid a lot of money, will not be happy because they won't have what they really need, managers will not be happy because customers complain, and the blame will be "on those weirdos who developed all this crap".

How can we have happy developers, happy managers, happy clients? a succesful approach is to divide the project in different phases, just like in UP, and contract for the elaboration phase at a fixed price, than use an agile Just-In-Time (JIT) approach for the construction and transition phases. During the inception you only get enough informations to estimate the scope of the project (yes, with this intermediate approach we still want to avoid big creeps) and to do enough architectural modeling to have a sufficient basis on which to produce an initial schedule and budget. In the next phases you let customers steer the project with an agile approach: they'll be more willing to do it because they'll already have the core of the new working, although incomplete, system, and the risks will be smaller. The management will have a reasonable estimate, which will improve iteration after iteration.

Still too extreme? You can follow UP and have two fixed price contracts, the first one covering the elaboration phases, and the second one covering the construction and the transition phases.

And you would get that pay raise, after all.

Forget that. "Money, so they say, is the root of all evil today. But if you ask for a rise it's no surprise that they're giving none away". Thanks to Pink Floyd for the tip (pun intended).

Thursday, January 24, 2008

.MOz on a diet

Now, now... Let's not go too far. Weren't you all satisfied enough with the database shrink?

Database on a diet

Today we stripped (and archived, of course) old data from one of our production databases... bringing it from 110GB to about 15GB. Let's say it was about time.

Wednesday, January 23, 2008

The ultimate dependencies-breaking technique

Yesterday I happened to meet an IT manager (mark this: an IT manager) and we started talking about our projects. I was complaining because at the moment I am dealing with two applications intertwined with cyclical dependencies (application A depends on libraries of application B and vice versa), and he gave me the ultimate answer to one of the most recurrent questions in software development: how do I break cyclical dependencies?

"That's simple... you merge the two applications, duplicate the code base and let the two projects evolve independently!" (note the full-of-pride-exclamation-mark).

Shall I add more?

Some things start out small

Now it's more than a rumor... I have a speech engagement schedule, even if there's only one event... which should be in May. I'll be presenting a seminar on data warehousing at the Università degli Studi di Milano, as an add-on to the data warehousing course. Some news should also appear on the official site of the DICO department of the University; stay tuned for more informations. The seminar should, more or less, be based on my thesis; that means I should be quite prepared, so I hope I won't have too many groceries thrown at me. And if I have... given the prices of groceries, at least I hope they'll be fresh.

The picture is taken from the beautiful "Dinosaur" Disney movie, from which I've also taken the title of this post. The full quote goes "Some things start out big, and some things start out small, very small. But sometimes the smallest thing can make the biggest changes of all."

Tuesday, January 22, 2008

Legacy software and code coverage

According to Michael Feathers, software is considered legacy if it does not have automated tests supporting it. And, not surprisingly, there are (too) many legacy applications out there. And that raises a couple of questions: how do you change legacy code? yes, but how do you change it without feeling the urge to update your cv? Mr Feathers gives a lot of hints on changing code and dependencies-breaking techniques, presenting you with different problems and possible (and tested, of cours) approaches.
At the moment I am working on an "inherited" old (and, yes, legacy of course) application for which I'll have to check several chapters of Feather's book: I can't get this class into a test harness, I can't run this method in a test harness, dependencies on libraries are killing me, my application is all API calls, my project is not object oriented how do I make safe changes, this class is too big and I don't want it to get any bigger, I'm changin the same code all over the place, I need to change a monster method and I can't write tests for it, how do I know that I'm not breaking anything, and so on and so forth.
So... where to start from? The answer is quite simple: I have to write tests. OK, that was easy. Which tests should I write first? short question, long answer. Long story short: check the book for that. But how do I know what's covered and what's not? Thanks to Fabrizio I've discovered Cobertura, a test coverage tool which instruments the bytecode of your classes and produces reports about, well you guessed, test coverage; you can see a sample report here. Fabrizio shows how to integrate Cobertura in NetBeans, which happens to be my favorite IDE. I did it and... well... I have quite a lot of work ahead, but at least I have a new tool.

Monday, January 21, 2008


Reading the wonderful PPP by Robert C. Martin (aka Uncle Bob) I found some useful metrics, which can be calculated using Jdepend. I knew one of our projects had bad dependencies, but I didn't know how bad they were... The tool is quite helpful and it can give you some good indications.

Keyboard error or no keyboard present... Press F1 to continue

What else could I say? .MOz is watching...