Agile Projects in Design Troubles

More and more reports indicate that larger agile projects are running into design problems. In order to deliver functionality fast in small increments code gets written without too much thinking about overall design.

The code gets deeper and deeper in “technological dept” (I like that term), resulting in slower and slower speed regarding the implementation of new features, and increasing costs per feature.

Is seems to me that the term “architecture” is poopoed by proponents of agile methods, and it is being derided frequently as “big upfront design” that is never finished.

Even big names in software engineering are only very carefully suggesting (not to look like a SW engineering relic in an modern, agile world) that thinking about overall design before you start is not generally a bad idea.

I do agree with the statement that “big upfront design” often happens, delays implementation, and is never finished. But that does not mean you should have no upfront design at all, or that you should not write any code before the design is completely finished.

When you start implementing software without planning and agreeing on a general layout of your application (aka architecture) you keep adding pieces that eventually will form a structure, one way or another.

That structure could be called an architecture – some call it an “emergent architecture” – but isn’t that just a nice technical term for something that rather “somehow happened” opposed to “has been systematically constructed”?

Having a structure makes it much easier to guess where functionality has been implemented (in example, to fix a bug or add a feature), just like sorting a list makes it easier to find an item.

Sorting is an additional effort that doesn’t even change the items. But it adds information to the data that is useful. When you know the overall picture, it is fairly easy to determine where a puzzle piece needs to go.

The compiler is happy with anything that compiles; architecture is mostly there to help humans to understand how the system works and how it can be extended.

So: Architecture is there to help you to get the job done, not another bump in the road that needs to be flattened.

Do spend some time on thinking about architecture when you know enough about the requirements to do so.

Make sure that newly added code fits that architecture. Adapt the architecture if it doesn’t fit new requirements. Treat architecture like a feature of the system.

The Cost of Quality: Two Hands, Two Bodies

Paying attention to software quality does pay off. Anybody who ever had to understand, repair, or extend existing software knows that lack of documentation (preferably on higher than code level), architecture, and coding guide lines, can turn maintaining even small amounts of code into a lengthy, risky and thus costly adventure.

Then why is software quality the first thing tossed over board, long before scope or – often arbitrary – deadlines?

Well, software works even with very low quality, if left untouched.

Having worked with a few large companies I found that the people benefiting from higher software quality are often not the same people that develop the software originally. Here is one concrete, real-world example.

Department A is responsible for initial software development. Department B is responsible for maintaining the software. B would clearly benefit from good documentation, architecture and so on once other developers than those comprising the original team are making changes to the software. But it is A that has to pay for additional quality that has little or no value to A.

What happened? Shortcuts taken by A mushroomed into exponentially rising costs for even the smallest changes by B, much to the dismay of the customer (department B, that is). Unfortunately there was no instance at the customer controlling cost of A and B in the context of the project they worked on.

That this won’t work is obvious – A has no incentive to spend extra money, and B has no influence on original development. Sounds contrived, unrealistic, and exaggerated? I wish it was…

So: If you find yourself in a similar situation try to find a sponsor that sees both sides, and inform him or her that investing in software quality pays off when the whole process is taken into account. Or at least inform somebody responsible for departments A and B that major and easily avoidable money wasting is in progress…

Prerequisites for Offshoring

One of my clients was trying hard to outsource software development, and has implemented processes for identifying candidate projects. The rules were pretty reasonable:

  • Existing software is documented in a suitable way (from requirements over specification and design to programming and rollout). “Suitable” means “competent people without prior knowledge of the project have access to enough information to extend the software successfully with reasonable effort”. That, by the way, is a pretty good definition of the quality any documentation should have.
  • The customer is aware that development is being done offshore, is willing to live with that, and accepts that documents provided by him to the project and documents produced by the project are written in English.
  • Processes are in place that allow for clear specification of stable requirements, and clear separation of phases and responsibilities.
  • The offshore workforce is reasonably stable so trained personnel is available over a longer period of time.

The problem was that pressure to increase the amount of offshored projects was so high that projects got moved to India, no matter the cost – ironically.

Here an example of a gone wrong (= more expensive then before) project transition:

  • The existing software was developed under high pressure, meaning “coding before design” and “we’ll do documentation when we have time”. That meant no overall design, and no documentation.
  • The customer did neither produce nor accept documentation written in English. All documents exchanged with the customer had to be translated at additional cost that couldn’t be billed to the customer. Translation was done in India, and results had to be proof-read by German personnel.
  • Because of sluggish processes a of lot of time got wasted between the customer voicing a request and the production of usable requirements.

The offshoring guidelines were very reasonable, but they were completely ignored. I can’t give any other advice than to “stick to the plan”, if the plan is reasonable.

Comparing Work by Cost Only

A company I worked for recently stated that “the internal hourly rate has to be brought down to xy Euros” in order to compete with other companies. This argument was mainly made to emphasize the importance of doing more (cheap) work off shore, thus lowering the average hourly rate.

Somewhat concerned I looked at the sentence for a while, thinking about whether this might be hinting at an unpleasant development that could have implications for me as a freelancer (I never ever have worked for as low as xy Euros per hour).

Then I relaxed.

You only may compare prices for specific services rendered if you are talking about the same kind of service, “the same kind” as in “same amount of work done per unit of time” and “same quality”. When buying a car you would never look at the price only: What make, what model? How old is it, what is the mileage, what is the condition?

Compared to German programmers, offshore resources only cost a quarter – on paper. In reality, the offshore partner regularly puts more people at the same task then the German side would. Some key people of the offshore partner will receive training on the project in Germany, and there will be a permanent on-site manager. So, add travel and hotel expenses, plus lost work time on the German and offshore side.

What if the customer doesn’t like documentation in English, and the offshore partner does not understand German? Ka-ching, add cost for translation, and load your tolerance module for accidentally introduced errors. And then, oops, personal that was trained in Germany leaves the offshore partner for sunnier shores. In the end, the cost is closer to 75% of the German rate.

“75% of the German rate” still doesn’t sound all bad. But this is for the development portion only. Sales, marketing, project management, requirements analysis, specification, design, testing, and roll out is all done in Germany. Development maybe is one third of the overall cost. In the end you would save about 8%.

“Saving 8%” is not nothing, right? Yes, but are you sure there aren’t any other ways to increase productivity, which essentially means getting more bang for your buck? Offshoring often has the side effect of alienating people working for you “at home”, and in my personal opinion offshoring is doing your local economy a disservice.

Why do people start with offshoring when they try to save money? When optimizing a program you start with an analysis first, identifying the code where most of the time or memory gets consumed. It is here that optimization effort gets you the greatest effect.

Blindly aiming for a lower hourly rate by using offshore resources is a brute force approach that does not look at underlying causes that drive cost up.

There are quite likely easier ways to improve productivity then transferring work abroad. Analyze your cost structure. Start working on the biggest items first. Review you processes. Educate and cherish the people working for you. Try a little harder at home!

Why Racing Probably Will Slow You Down

Many programmers will have gone through the following cycle.

The project time line has been tight from the beginning. Finally the specification gels into a vaguely discernible form, though pretty late. No time any more for architecture, design, and generally engaging the brain before typing. The deadline must be made! Everybody rushes to the goal, best practices and common sense are trampled into the ground, and hackers feel finally freed from those bureaucrats that call themselves architects.

Inevitably the project is late anyways, and the code is a huge mess that will be cleaned up when there is time. That is: never. Time is money; where should the money come from?

The customer? “Hey, the stuff finally works, why would we pay for beautifying the code? And, by the way, don’t you guys advertise high coding standards?”

Your own company? “Well, the budget is blown, and the customer won’t pay for it! And, by the way, aren’t you guys using best practices?”

A good solution would have taken maybe 20 or 30% longer than the ordered estimate. In the end the project consumes the same amount of time. Additionally you get a much poorer result, angry customers, frustrated programmers, and the kind of code that makes you want to switch projects before the next release. Cutting corners when your experts beg for some time to think before coding will buy you nothing in the long run.

Fighting Software Entropy – Intermediate

Recently I read an IEEE article on software metrics that identify potential dangerous constructs in code, such as brittle base classes. One short example: “Foo” declares and uses a method “bar()” that may be overridden by an extending class, potentially breaking functionality in the base class.

Metrics like this can really help to improve software quality. Considering the state of code that I see every day as part of my consulting business metrics like the one described above would be the final touch on top of a long list of measures and rules I would recommend to employ first. As long as methods with more than 200 lines abound, copying code is a design pattern, and “verifyOrder()” changes the delivery address in the data base you’ve got bigger problems to tackle first.

When washing your car you don’t start polishing before you hosed away the mud – that would be spending a lot of effort in the wrong place. Getting rid of the mud takes 20% of the cleaning effort and gets 80% of the job done. When you optimize a program you first analyze where most of the CPU time gets spent and concentrate on these hot spots. Likewise, there is a rather small number of coding guidelines that go a long way to improve code quality.

Here is my hit list of the most important code improvements:

Nomen est Omen: The name should fit the meaning. Don’t call a method “verify()” – the name strongly implies read only access – when the method changes data or even creates and deletes whole records in the data base. You don’t like documentation? Well, choose good names; together with the next rules your code will be as easy to read as pseudo code. There is no excuse for bad names: refactoring has made renaming safe and painless.

One method, one purpose: If it is difficult to find a concise name you probably packed to much functionality into one method. Break the method in smaller methods that each do only one thing, and make that thing the name of the method. Again, refactoring makes this simple.

Break down long methods and expressions. Introducing more local variables will not slow down your program; modern compilers will optimize execution better than you can (at least in this regard). Break down methods into smaller methods, too. You might even find redundant code that you can eliminate, or that methods become usable for other than the original purposes.

[This article is going to be extended]

Fighting Software Entropy – The Basics

In many companies code formatting and checking tools such as the Eclipse code formatter (or better: the cleanup function), Checkstyle, PMD, and FindBugs are pretty much the only measure taken to improve code quality. To continually use these tools is a very good measure – as long as one realizes code formatting and checking are the very basics of code improvement, not the pinnacle.

Through 16 years of professional programming experience I am certain that not tools and rules will create software quality, but genuine insight. In example, I worked for a large telco as a software architect. But instead of designing a system that, just as an example, decouples business logic from specific XML parsing frameworks through the use of domain data classes and transformers I found myself having discussions with certain programmers about the number of characters per line.

Some programmers were using expressions that extended over 200 characters and longer, and considered it their personal right and freedom to do so, as long as the code works. I disagree, since not only the compiler has to understand the code, but humans. Such an attitude neglects the rights and freedom of others, in example the right to understand the code of coworkers in a reasonable amount of time and the freedom to concentrate on implementing functionality, not having to reverse engineer cryptic source code first.

Sticking with the overy long expression example I maintain that nobody can intuitively grasp the meaning of such a monster. This is not how the human mind (specifically short term memory) works. So: Break long expressions down. Use refactoring to introduce methods and local variables. “account.isNew()” contains more information than “account.getNumber() == null” and is way easier to read and understand (and what happens if in the future accounts can be new and already have a number?).

Let us assume you are in a role that is supposed to improve software quality. Now, how do you create insight? The term “insight” implies that it is something that a person develops for her- or himself. It is nothing that you can forcefully create; it has to come from inside the person. You can try to foster insight, by appealing to having an open mind, showing good and bad examples, and providing positive feedback (eventually enjoying the results of a better programming style).

What do you do if all that does not help, and a programmer expresses his or her low opinion of the suggested programming style verbally, or worse, in code?

Well – I personally expect that professionals try to improve their skills all the time. Backed by the insight and research of others and by my own professional experience I have an opinion on what good and bad programming style looks like. I know what programming style means to a project in the short and the long term. As a developer I have often enought felt the anger, frustration, desperation, and hopelessness that comes with having to understand, maintain, and extend steaming heaps of code that nobody dares touching any more.

The difference in programming style and attitude is so great (measured by criterions such as less stress, higher productivity, more deadlines kept, lower cost, less overtime, and – yes, more joy!) that if I have the choice I’d rather work with programmers who employ a good programming style, and let the others go to work on other projects.

Mantras

[This article is going to be extended every now and then]

All Redundancy Is Evil

Really, if you can avoid redundancy, do it. If it costs some unpleasant effort, bear it – you’ll get repaid later again and again.

Copy and paste is a surefire way to pain and suffering. It is very hard to see if different but similar code really does the same thing – you’ll have to compare the two spots down to the last character. And when there are differences, are they the result of deliberate modification or some accidentally incomplete update?

If it can be generated, don’t check in the product but polish the source (and, if necessary, the generator and/ or its configuration) and automatize the process. There are way too many projects where the results of some generator run have been checked in. After a few months nobody can tell for sure anymore whether the generated stuff has been modified by hand (and don’t do that).

Don’t “Unstructure” Information

Enterprise Architect, a very good UML modelling tool, allows you to attach RTF documents to an UML element (the tech term is “linked document”). I’ve seen projects where all information is in the RTF document, and none in the fields and links that Enterprise Architect generously provides (pre- and postconditions, scenarios, actors etc.).

Why in the world anybody would do something like that is beyond me – you loose all opportunities to generate reports (ensuring a standard look and feel), run crosschecks, enforce documentation standards, perform context-specific searches, visualize dependencies, trace relationships, access information via an API and much more.

Beware of Scripting

Before I even start: I will use scripting (probably with Perl) any time to get a job done – if the job is suitable for scripting. Now you may read on :-)

I recently read an IEEE Computer Society article “In Praise of Scripting”. Having been a big Perl fan who ran into big problems with a not even sooo big Perl project I have a comment or two on the article.

In the article (and elsewhere) scripting is displayed as the method of choice for free, creative spirits who develop the groundbreaking, innovative (web) software of tomorrow while the use of compilers with strict typing is the tool of narrow-minded syntax-watchdogs who develop unremarkable applications by committee.

I beg to differ, having used Perl heavily for about seven years between 1993 and 2000. Perl does an incredible job when a single programmer has to interpret text files and transform data. This is the kind of job I still often use it for today.

But scripting languages like Perl can be a big problem when a team has to create a really large application with complex data structures and elaborate functionality. During the dot com boom a lot of very successful software was written in Perl. What people might not realize is that maintaining and extending these applications was a nightmare, and I know people who quit their job because they could not get away from having to install and maintain these contraptions.

Perl is excellent for many things including shooting your own foot. Neat features can produce obscure errors that are very hard to find. In example, variables don’t need to be declared, and have no type. Of cause it is nice that a variable just springs into existence when you need it (less typing, in example). Or that you don’t have to care about conversions from strings to numbers and the other way round. Or that complex data structures can be created, extended, and modified on the fly because associative arrays give you all that.

On the other hand, what if you misspelled a variable name? Or the second parameter of a function was supposed to be the forename of a customer, not the year of his birth? Your program will produce odd results but no error. And you then painfully realize, too, that there is no IDE such as Eclipse to help you track down the mistake you made. The compiler won’t help you either, because a = b + c is fine for it whether b and c are strings, numbers, or a combination of the two.

Some find it nice that Perl allows you to program in a number of different styles. You can make the code look like C or Java, or more like Visual Basic. There are a number of constructs that don’t exist in other languages that allow you to express yourself even more concise, such as “…unless”.

But since these constructs do not exist in other languages, people not familiar with Perl have a hard time understanding what is going on intuitively, and some constructs are just not very intuitive (“do this, this, and this – unless something is so and so” – you first follow that “this and that” will be done, but – surprise! – not under the following condition). Different styles, non-intuitive and surprising developments are great in a book or movie, but not in source code.

This article obviously is not exhausting the subject; I’ll give it a shot another time.

Software Industry != Software-Industrialization

In my opinion somebody has been seriously confusing the production of material goods with the development of software.

Let’s look at the example of Lego bricks. A lot of effort goes into setting up injection molding machines and a distribution network. Once the complex machinery is in place you produce millions of identical items by employing the same steps over and over, with very little human intervention.

This is not how software is being produced. The multiplication and distribution is the smallest problem. In the case of software created for a specific project and purpose the product might be installed only once. Pretty much all of the effort goes into the specification, design, and development of a single unique product.

Where is the industrialization in that? What is industrialization, anyways? Making a single item is expensive. Constructing a machine for creating a single item is even more expensive. But using that machine to make a lot of items reduces the cost per item enormously.

So what that is software industrialization then? The best analogy I can think is the use of tools like IDEs, debuggers, or maybe even MDA. And using standardized methods, tools, and processes. But the advantages of applying all this only go so far; creating software is done mostly by working with the head, not with tools.

This means that developing software is not an industrial process performed in an automated factory, but rather tool-assisted handcrafting in a manufacture, gladly employing sophisticated methods. This is not a bad thing; better methods and tools will help a lot to improve the quality of software, and to speed up the development process.