public business secrets

Software Development

Post navigation

During the last three years gamification became quite popular in everyday applications, e.g. marketing or social media. A simple, but often observed technique is to award users with badges for specific actions and achievements. This technique can be used in pretty simple ways, e.g. member titles in forums based on the number of posts, but may also be rather elaborate, e.g. StackOverflow’s system of granting badges to users based on on their reputation and other aspects. Some companies even announced to, or already do, include gamification aspects in consumer and business software, e.g. SAP or Microsoft.

Besides adding fun and a little competition to everyday activities, gamification can also be useful by encouraging users to explore the features of software and, by doing so, discover functionality they are yet unaware of*.

Considering software development, there are also some gamification plugins for IDEs and other tools, which are worth to take a look at. The following provides an incomplete list:

Jenkins Continuous Integration Game: A rather simple gamification plugin, in which users can score by triggering successful build or adding tests (and in turn are punished with negative scores for breaking the build).

At one of our customers I do C++ consulting in a mid-sized project which uses cmake as build system. A clean build on our Jenkins CI server takes about 40 minutes (including unit tests) which is way too long to be considered “fast feedback” in an agile kind of way.

Because of that, we do clean builds only 2 times a day – some time during the night and during lunch break. The rest of the day the CI server only does a “svn update” and a normal “make”, which takes about 3-10 minutes depending on what files have been changed.

With C++ there are lots of ways to unnecessarily lengthen your build time. The most important factor is, of course, #include dependencies. One has to be very (very) disciplined in adding #include directives in header files. Otherwise, the whole world suddenly gets rebuild when some small header file somewhere in a little corner of the code has been changed.

And I have to say, for the most part, this project is in pretty good shape with regard to #include dependencies.

So what the hell has suddenly increased our build time from 3-10 minutes to 20-25 minutes? was what I was thinking some time last week while waiting for the CI server to spit out new latest and greatest rpm packages. For some reason, our normal, rest-of-the-day build started to compile what felt like everything in our main package even on the slightest code change in a remote .cpp file.

What happened?

In order to have the build time available (e.g. to show in an “about” box), we use a preprocessor symbol like REVISION_DATE which gets filled in a CMakeLists.txt file. The whole thing looks like this:

Since the beginning of the time these lines of CMake code lived in a small sub-sub-..-directory with little to no incomming dependencies. Then, at some point, it became necessary to have the REVISION_DATE symbol at some other place, too, which led to a move of the above code into the CMakeLists.txt file of the main package.

The value of command date +%F_%T changes every second which leads to a changed REVISION_DATE on every build – which is what we initially intended. What changes, too, of course, is the value of the ADD_DEFINITIONS directive. And as CMake is very strict with the slightest change in this value, every make target below that line gets rebuild – which in our case was everything in the main package.

So there! Build time killing creatures are lurking everywhere in our C/C++ projects. Always be aware of them!

I keep hearing stuff like:
“we as software developers are craftsmen and should honor our craft and write clean code”

Using the metaphor of a craftsman we should also realize that we are building software for people (to use) not for its own sake.
Imagine a chair which is perfectly crafted and beautiful to look at but you can’t sit on it?
It might be art but nobody can use it for its original purpose.

Most if not all of the software we write is for people to use, to be empowered and yes, to be delighted.
But to what use (besides art) is a software which is cleanly built but unusable?
We as software developers have shied away for too long from learning to craft useable interfaces.
I think we should not neglect that we develop software for others to use.
A program is not an island, it only excels when it interacts with users or other programs.

There is a saying that if you don’t be embarrassed by code that you wrote six month ago, you haven’t learned anything. Recently, I stumbled upon a C/C++ project that dates back to the very early days of my programming career – this was many * six months ago – and I can tell you, I was very embarrassed.

I had just “learned” C++ and object-orientation at that time and, of course, wanted to program that way. The result was terrible. The only small piece of object-orientation was the use of the keyword class. There were public fields all over the place, no interfaces or abstractions of any kind, switches over type-ids, and so on.

Another highlight was the vast amount of literals scattered all over the code. For example, as it was a curses-based application, I had to read and display user input using curses methods like

int mvwgetch(WINDOW *win, int y, int x);

and

int mvwaddch(WINDOW *win, int y, int x, const chtype ch);

And what did I do? I hard-coded y and x positions on every call of those methods. So it would often be the case that I changed, say, the y position in one part and … well, you guessed it already.

Naming of variables was also big. Boolean values would often be called “flag”, a name length of more than 4 was considered way too long.

But there was also progress. In later parts of the software I started to use “advanced” things like auto_ptrs, std::list, and std::map. Hooray!

The only positive thing about this project was that since I made every possible mistake one can imagine, I learned quite lot about programming. And I remember that at the end of the project, I was already very embarrassed about the whole thing…

So if you like reading horror stories, try digging up your old code ;-) And share if you like.

Usually in every project ideas are abundant. Your client has many ideas what features he wants. You and your coworkers have a rich background in the problem domain and the technologies you use so that solutions are not sparse. But often this experience and confidence leads to abandoning an important trait: simplicity.
Most of the time you are focused on getting good solutions for the problems that arise. From past experiences with clients who could not exactly explain what they really need (which is different from what they want most of the time) you tend to include a little extra flexibility in your system. Maybe you need this and that variation some time in the future but at this very moment it’s a guess at best. And often this guess costs you. You could argue that you are investing into your project. But how many times did this investment really pay off? And how many times did you have a hard time just because you did not want to make restrictions? At first it seems like a little work. But with the next feature you have to continue supporting your little ‘extra’. Over time it infuses your system like leaven does it with bread. In the end it is more work to make it simple than to keep it simple.
So with every project you approach there should be a stakeholder for simplicity. Someone who focusses on simple solutions. Sometimes you have to cut a bit away from the feature or you have to view the problem from a different angle. Some other time you have to dig deeper into the problem domain or you need real data from your users (which is always better than what you can make up in your mind). Finding simple solutions is work but it is much more work to support your over-engineered solutions.

Recently we participated in a local effort (site in German) to help making our environment cleaner by removing waste which was left by other people. When you take a look at your environment you may come to the conclusion that many people are irresponsible. Waste on the streets and in the parks, prohibition signs everywhere which name things and actions you wouldn’t even think of and when did people forget to flush the toilet?. And it doesn’t stop in the material world, you even find waste in your code. Allowing waste and not removing or preventing it leads to two effects:

even more waste (according to the broken window theory)

over time the waste becomes more and more intertwined with the environment

Imagine a plastic cup in a forest: When first thrown there it is clearly distinguishable from the mud, the leaves and its surroundings. Easy to see and easy to remove. But over time it is trampled over, crushed, hidden under leaves, wash over with mud, … in the end you may not even spot it when you look at the place where it was left.
The same happens to your code: You start with a small clearly defined part of bad smelly code and leave it alone. Now the first additional features come in, you add code, there and elsewhere. The surroundings change. You refactor. You move code. And in the end the once good known waste is littered all over your code and hard to remove.
So be responsible now! And don’t wait until the waste is hard or impossible to remove. Collective ownership (of code or of your environment) does not mean nobody is repsonsible, it means you are responsible.

One thing I observe is that students don’t have difficulty separating the old topics from the current ones, even if they hear both of them for the first time. It seems that subject matter ages by itself, just like source code does. So, I’m constantly searching for new topics to include in the lectures, replacing the oldest ones.

The idea of missed opportunities to tell some fundamentals to my students struck me. I compared my presentations to the list, finding the leading two topics covered to a great extent. The last one, corporate politics, is a bit off-topic for a technical lecture. But nevertheless, it’s too important to omit completely, so I already had included some Tom DeMarco lessons in my presentations. Perhaps I can build this part up a bit in the future.

What they should have taught me

Soon afterwards, I though about things my lecturers missed during my study. Here’s the list with only two points in addition to Alan’s list:

Age and “maturity” of topic: When I was a student, I quickly identified old topics, like my students do nowadays. What I couldn’t tell was if a topic was mature (a classic) or just deprecated. It would have helped to announce that a topic was necessary, but of little actual relevance in modern software development craftmanship. Or that a topic is academical news, but yet unheard of in the industry and lacking wide-spread acceptance. Both extremes were blended together in the presentations, creating an unique mixture of antiquated and futuristic approaches. This is a common problem of Advanced Beginners in the Dreyfus model.

Ergonomics and Effectiveness: I still can’t believe I didn’t hear a word about proper workplace setup from my teachers. I had courses teaching me how to learn, but not a single presentation that taught me how to work. This topic ranges from the right chair over lighting to screen size and quantity and could be skimmed over in less than an hour. But it doesn’t stop with the hardware. Entire books like Neal Ford’s “The Productive Programmer” cover the software side of effective workplace setup. And even further, the minimal set of tools a software developer should use (e.g. IDE, SCM, CI, issue tracker, Wiki) wasn’t even mentioned.

I hope to provide all these topics and information to my students in a recognizable (and rememberable) manner. They deserve to learn about the latest achievements in software engineering. Otherwise you aren’t prepared to work in an industry changing fundamentally every five to ten years. Of course, hearing about the classic stuff is necessary, too.

Give me feedback. What are your missed topics during apprenticeship, study or even work?

—

Update: In case you can’t visit my lectures but want to know a bit about ergonomics, I’ve written two blog articles on this topic: