Archive for October, 2009
I used to believe that the most important quality of code is its extensibility. The code had to be prepared for future changes so I would code lots of things not necessary now. But after realizing that I never was right upfront guessing what the future changes will be, and after having quite a few maintenance and handover nightmares, a few a years ago I decided that I will take the opposite approach to what good code is. Ever since I did that, I am every day more convinced that the key characteristic of good code is simplicity. Simple code is easy to read and easy to change. And because it is simple, it is less prone to have bugs (the more complex the algorithm you are creating the more changes to make a mistake).
Whenever you are coding, I recommend you to check every time if your code is still simple, and remember: “there are no hard problems, only hard solutions”
The seven main characteristics of simple code are:
1.- Easy to read.
Simple code doesn’t need additional documentation, or it only needs minimal documentation to be understood
2.- Easy to use.
Whoever is using your code will find it intuitive to use your objects.
3. Easy to change.
Simplicity means that there is no duplicated logic. A change should match a single place in your code.
4. Doesn’t use any non-necessary third party, tool or technology.
Through my experience I have observed how some developers just love to use technologies, tools and frameworks just for the sake of making the project more “cool”. Every time you use them, you are adding extra complexity, and extra complexity means that is more difficult to understand, to maintain and is more prone to failures.
5. It looks simple.
If it doesn’t look simple, it is not simple! You know your code is simple if when you finish you are astonished at how simple the final solution is and you ask yourself how it was possible that it took you so long.
It only does what is necessary, and nothing else. I think most seasoned developers would agree that trying to anticipate the problems your code will have to face in the future is impossible.
7. Is straight forward.
It doesn’t have unnecessary indirections; the most important operations only require a straight method call.
How can we develop simple code?
The key of producing simple code is continuous refactoring, and the only way to do this is continuous testing.
You are going to need refactoring because every time you add a new line to your algorithm, you are probably making it more complex. So every now and then you should refactor to get it back to a simple stage.
You need many tests because you are doing so much refactoring, and if you don’t have a safety net you are going to introduce bugs into your system.
Are we in front of the next era for software development? Are you ready? or are you going to become a dinosaur developer?
I remember that around 10 years ago object oriented started becoming the main stream in software development, even though C++ was already been used, it was not up to the consolidation of Java that companies started moving to OOP massively, that at least, was the experience I had in Spain where I was working back them (I suppose this would happen a few years before in US, but I would appreciate very much the feedback from any reader to confirm it), back in those days, companies expended huge amounts of money training people that was previously working with some other not object oriented languages as C, Pascal, Cobol… there was a lot of excitement, frustration, success stories and also complete catastrophes… it was a revolution as some of you will probably remember, well, in my opinion, something similar is happening again.
199x – The source code revolution (The OOP revolution)
As I said above, UML, Java, OOP paradigm… were the buzz words back in the 90s, people believed again that they had found the silver bullet for development, if you didn’t know how to do a UML class diagram or Java, you were not on the cool side of programming.
Lots of programmers had to learn a new software development paradigm, which was not easy, the most veteran developers were the most troubled, some couldn’t adapt and end up doing “sequential” programming embedded in objects, (which of course defeats the whole purpose of OOP), some of them eventually change their mindset and eventually started thinking in objects, and for some others, quite a big group actually, that mindset change was impossible, and they end up maintaining legacy code, (in the worst case scenario you can still find some dinosaur programmers still doing this “sequential” programming nowadays).
200x – The process revolution (Agile/lean…)
Now we are in the middle of the next revolution, this time not focused on the source code, but in the processes, the buzz words are: agile, lean, TDD… As with the previous revolution there is probably going to be a big readjustment, and the big question is: “Are we prepared for it?” As in the 90’s, there are going to be a lot of professionals which won’t be able to keep up with all the changes, so the big question is: Are we going to be one of those future dinosaurs developers? My own recommendations are:
- Try to be as informed as possible. Read, ask, do some training, but above all make sure you understand, it is almost as dangerous to learn about something without understanding it than no knowing it at all (think on all the programmers that still think that TDD is all about testing).
- Be proactive. Show initiative; show that you actually do understand the new processes.
- Don’t be religious. As with the OOP source code revolution, there are some people that believe that these changes are the silver bullet for software development, be aware that there is no such thing, so be wise and don’t accept something just because is new, first put that in your project context and analyze if it will work for you.
Bonus: 201? – The source code revolution II? (Functional programming?)
Well, if what I called the “Process revolution” is a revolution which in my opinion is happening right now, the “Source code revolution II” is something which I’m guessing will happen just after the “Process revolution” just as soon as people start to understand that is not the silver bullet, so my guess is that the focus will go back to the source code and we will probably see the commercial massive adoption of new programming paradigms as Functional Programming… What do you think? Will this become the next revolution? Is the Process revolution the current revolution?
A few weeks ago I published “10 commandments for creating good code”, the article was focused on the physic code characteristics but it didn’t mention anything about best practices to follow to produce such code, to compliment it in this article I would like to present what in my opinion are the five more important practices to take into consideration to create good code.
Keep it simple
I strongly believe that the number one problem with unreadable code is over engineering, we learn so many techniques, frameworks, tools, patterns… that we actually believe that if we can use them, we should use them, and it actually should be the opposite, the best solution is always the simplest solution, remember: “There are no hard problems, only hard solutions”.
As I wrote in a previous post, there are four main traps that may keep you away from keeping things easy:
- If all you have is a hammer, everything looks like a nail.
- Because you can, It doesn’t mean you should.
- The more things that can fail, the more things that will fail.
- The more prepared is your code for change, the more difficult is to change your code.
Visit the article: For god’s sake! Keep it simple! to see a detailed explanation on these 4 traps
Make it work, then make it fast.
“The best is the enemy of the good.” Voltaire
“More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason – including blind stupidity.” W.A. Wulf
“We should forget about small efficiencies, say about 97% of the time: Premature optimization is the root of all evil.” Donald Knuth
They are great to:
- Perform regression testing
- Help you design new code
- Validate your new code
- Boost your productivity
Test early, test often, test automatically! If you are interested in further reading, you might want to check out: How to write a good test case and Top 5 considerations to build software without defects.
My five tips on code reviews are:
- Make your code reviews often. At least once a day.
- Make your code review short and Informal. Something like: “Hi Mike! You mind coming over to my for a quick code review”
- Make your code review with different reviewers.
- Keep a positive attitude.
- Learn to enjoy the code reviews. A code review should be seen as a learning opportunity
For more details check the article 5 tips to make good code reviews.
A special mention deserves pair programming, pair programming is the ultimate way of code reviewing, not only makes code reviews unnecessary, but it also increases the code quality and the productivity.
One of the biggest recent mindset changes is from refactor = bad to refactor = good, saying that refactor is good is saying that you know that you are going to make mistakes, but that you are going to be ready to fix them, that’s quite different from the refatoring is bad mindset, where you put a lot of effort in not making mistakes, which is obviously wasted because, let’s face it, that’s impossible.
Have you not ever seen one of this super duper cool architecture diagrams? You know, the ones with dozens of colors and boxes, the ones that when you read them, you think: “WTF is this!?”
Not all architecture diagrams are like this, not at all, an architecture diagram is supposed to explain what are the different high level components of the application and how they interact with each other, but some times they don’t, and when this happens, you just have to believe they will just work as if by magic, that’s why I like to call this: “Magic architecture”.
Magic architecture, is bad, really bad, and is even worse when it comes from some other team in your company, because it will be more difficult to change.
How can we detect magic architecture?
As for many other phases in software development, the main indicator for magic architecture is WTFs/minute, but because this is quite a subjective measure, you may find the following useful to objectively determine if your project suffers from magic architecture.
All are implementation details.
Here is a common scenario: You receive an email from the architect with the latest architecture diagram, you open it and you see only 3 boxes: the input manager, the process manager and the output manager, you obviously think WTF!! So you just pick the phone and call the architect for more details, and the architect tells you: “oh, what is outside of the diagram are just implementation details”.
While the example I used is an exaggeration, it serves the purpose of showing how ridiculous is to draw something which is so vague that it actually doesn’t help to build the project at all.
Forgetting what’s the purpose of the architecture.
You receive an architecture diagram for your Hello world application, you open it, and to your surprise, the architect has included way too much, there is a messaging service, an authentication service, a database… When this happens, is usually because some architects are eager to show how “cool” their architectures can be, if so, is good to remind that the architecture has to provide with a structure to support absolutely all the product requirements, (well, at least the most important), AND no more than that.
Not doing an architecture diagram, but a shopping list.
This is one of the funniest architectures you can find, instead of showing the different components of the application, you get a list of the different tools/technologies to be used, like: “there will be a Websphere server which will read messages from Active MQ, depending on the messages it will store some information in Oracle, we will log with log4j”. A good architecture shouldn’t be tied with any technology or tool (this is actually quite hard to accomplish 100%, but to break this rule of thumb you should have a very good reason).
Before you leave…
Remember to consider if you need an architecture, probably if your application is not big, it won’t be necessary, but if it is, and you have a magic architecture, well you better expend some time trying to convince the stakeholders to change it.
How to determine the cost and schedule of a software project? The mythical BPUF (Big planning upfront)
How to determine the cost and schedule of a software project is one of the most important questions around software development. My opinion probably is going to be polemic, but here it is. It is impossible to determine what the cost and schedule of a software development is going to be.
Why is it impossible? (The Iron triangle)
A very good and well known analogy to help me explain it, is the iron triangle analogy which recently Mike Cohn has refined with his one handed clock. What these theories say is that in a software project (and basically in any project), assuming that the quality remains static (projects should always aim to have high quality), there are other three variable elements: Schedule (how fast you want to deliver the solution), Budget (how cheap you want your product to be) and Features (how many cool stuff you want your application to perform). What is really interesting is that these three variables depend on each other so that is impossible to give more priority to one of them without taking it from the others.
What makes it impossible to determine the cost and schedule, is that it is impossible to fully know the scope of the Features of the application upfront, no matter how much analysis, and requirements gathering you perform (yeah, I know I am going to get a lot of hate for saying this…), so how can you calculate the other two sides of the triangle? Even when the cost is fixed, or the schedule is fixed it is impossible to calculate the other vertex of the triangle.
For the sake of the argument, let’s suppose that I’m wrong and you actually can determine the Features of the application up front, so you will have to estimate then, I suppose we all will agree that an estimation at the end is just expressing a probability, when we say “it will be finish in a month”, we mean something like “there is a 80% chance that I will finish this in a month”, and when you chain probabilities, the probability of being right in all them drops exponentially meaning that even if you know all the features the combined probability of being right in all their estimations is ridiculously low.
The solution for this problem is to change the mindset and look at planning not as a one off big activity performed at the beginning of the project, but as continuous activity performed through its hole life, the more you have developed the application, the more you will be able to refine your previous plans.
There’s a vicious circle, a software development won’t get approved until is cost and schedule is estimated, but they can’t be determined because you will only know the real scope of the features by the time you start developing them, anyway, that shouldn’t stop you from starting the project and creating initial estimates and refine them as long as you keep developing the product. Be aware than trying to create an initial planning, and using it as a contract, will seriously affect all the parties involved, the customer won’t probably be able to specify any change during the development, and the development team will have to work under high pressure to meet the deadlines, at the end the final product won’t be what the customer was expecting and its quality will be poor.
This is how planning usually happens: Fred, the project Manager, spends weeks creating a really cool, colourful Gantt Diagram, then, it is presented to the team which show some concerns so Fred does a few changes and the plan gets approved… as the time goes by, the plan gets more and more outdated BUT amazingly Fred doesn’t blame the plan and he even keeps pushing people to follow it.
This dynamic, which is obviously wrong, is sadly a dynamic that lots of teams still follow; these teams are blinded by the plan. Blinded teams forget that they main purpose is to ship the best solution as possible, not to follow a plan.
A plan should be used to
- Evaluate the risk of not delivering on time. If my deadline is in two months, and my high level estimate shows a figure of one month, then I can relax, if it shows two months, I will have to look the estimation in more detail.
- Have a high level expectation of the next deliveries.
- Help communicating the different stakeholders. In your project may be involved Marketing, some management, the customer… A plan always helps communicating by setting the expectations.
A plan shouldn’t be used to
- As a contract that details the specifications of the product and their deliveries. If you see your plan as a contract, you won’t be ready to accept any change, and change management is fundamental for software development.
- As a one-off big activity performed at the early stage of the project.
- As a tool to press developers to deliver in unreal deadlines.
Make everyone understand that the plan is just a tool not the end.
This is the most important thing to do, when the stakeholders see the plan as an end, or a contract, the project usually ends up having the different parties not collaborating at all.
“In preparing for battle I have always found that plans are useless, but planning is indispensable”. Dwight David Eisenhower.
Planning adds a lot of value to the team, instead of BPUF (Big planning up front) keep planning every day and revisit your original estimations as needed.
Don’t detail your planning further than one week ahead.
Detailing more than one week of work ahead is almost impossible, so just don’t do it, also, bare in mind that: detailed planning and high level planning usually are equally accurate.