A site devoted to discussing techniques that promote quality and ethical practices in software development.

Monday, May 18, 2009

Why would some company want to project having a blurred vision?

I have seen companies wanting to project themselves as having clear vision but have not heard of one wanting to advertise itself as having a blurred vision until I was shown the one.

See for yourself. Below is a company's propaganda poster, doctored to hide the company name & logo saving it from embarrassment. I was told it was plastered all over the hallway prominently.

Perhaps, there is some truth in that poster!

Thursday, May 14, 2009

Commercial software subjected to public scrutiny

Bruce Schneier reports a court case in which the accuracy or quality of the embedded software in an alcohol breathalyzer is being questioned in a court case and the court decides to subject the software in question to an independent proper assessment, i.e. a proper code review, despite protests naturally from the vendor.

For people interested in seeing a professionally compiled thorough code review can read the full report and a separate deeper analysis report. Both reports are very educational, particularly the second one.

When I am digging through this report, which I do not recommend people to print out the full 57 pages, it reminds me of the similarity in the quality (or lack of) in an Australian-made ERP software. To be honest, the ERP software is far worse by a large margin.

For example, it is not uncommon in the Australian-made ERP software to have far higher density of code exceeding the CC of 105, admittedly, though inexcusably, the ERP software has more LOC. I have personally seen CC higher than 150-200 after discounting the accuracy of the metric measuring tool.

Another issue identified by this review that is wide spread in this Australian-made ERP software is the frivolous and gratuitous use of global variables; this was caused by lack of training in good software practices, lack of reviews and aided by the development tool. In fact so wide spread that it was used as an excuse to avoid an architectural design correction exercise. In the company's view, it is much cheaper to let their poor users to foot the bill of their frivolous resources wastage, the result of its architectural flaws and ignorance, by paying much higher hardware costs.

Public review of commercial and proprietary software should be a normal public quality assurance process to safe-guard the welling being of the software consumers; it is similar to safety rating of cars or electrical appliances. Such public review would have unearthed the glaring mistakes committed by this Australian-made ERP system allowing the users to seek compensation.

Currently, the playing field is severely tilled towards the producers, as reported, allowing them to discharge all responsibilities and to take all rewards.

Companies have often invoked the commercial-in-confidence or proprietary IP excuses to escape such scrutiny. But this report stated in court that
Base One found that the code consists mostly of general algorithms arranged in a manner to implement the breath testing sequence. "That is, the code is not really unique or proprietary."
I doubt there are too many genuinely proprietary IP stuff in many today's commercial software. The more well established they are, the less they are and many are just a quilt of widely publicised algorithms poorly implemented to meet the so-called commercial dead lines.

In my opinion as a developers with over 20 years of experience, I believe those hiding being the veil of proprietary secrecy are too afraid to be caught using unsafe practices, not using industry best practices and ignorance of their mistakes in their own coding; the Alcotest did not even realise that they have committed buffer overruns and including others surprises in the published findings.

The review report attempts to nail down the reasons for the high CC has this to say:
source code appears to have evolved over numerous transitions and versioning, which is responsible for cyclomatic complexity.
While this is a likely cause, and is in agreement with my experience in the Australian-made ERP software, it only indicates both companies have a very poor software maintenance process. Most likely it is based on code-and-fix with little regards to refactoring during a bug fix phase.

The review findings and my own personal experience in this industry indicate that bad software practices are more universal with no geographical boundaries.

Saturday, May 9, 2009

Showcasing the genuine ones in financial hard time

Justin Brown decided to showcase those companies that stand by their staff in financial hard time by creating a web site. Well done.
"At the moment the world is all doom and gloom, recession, credit crunching and downsizing. This site gives you a chance to gloat that your business has not fallen victim to short-sightedness, that even through bad times you value your staff enough to keep them for when times are good."
Most companies only give lip-service when they tout that they value staff as assets but tough times sort out the sheep from the goats causing them to reveal their true selves.

Mincom, Pacific Brands and Vision Australia need not apply.

Sunday, May 3, 2009

Designing API - Bad API can really hurts

An article titled "API Design Matters" is a must read article for any one in charge of designing API and has this to say:
Good APIs are a joy to use. They work without friction and almost disappear from sight: the right call for a particular job is available at just the right time, can be found and memorized easily, is well documented, has an interface that is intuitive to use, and deals correctly with boundary conditions.

So, why are there so many bad APIs around? The prime reason is that, for every way to design an API correctly, there are usually dozens of ways to design it incorrectly. Simply put, it is very easy to create a bad API and rather difficult to create a good one. Even minor and quite innocent design flaws have a tendency to get magnified out of all proportion because APIs are provided once, but are called many times. If a design flaw results in awkward or inefficient code, the resulting problems show up at every point the API is called.
The article went on to provide a list of guidelines. It also offers the following top advice:
APIs should be designed from the perspective of the caller. When a programmer is given the job of creating an API, he or she is usually immediately in problem-solving mode: What data structures and algorithms do I need for the job, and what input and output parameters are necessary to get it done? It's all downhill from there: the implementer is focused on solving the problem, and the concerns of the caller are quickly forgotten.
This alternative definition requires the implementer to think about the problem in terms of the caller.
This recommendation is not dissimilar to the advice "Your users is not you" or another saying is "there are more users than developers".

The best way to deal with this as alluded in the article is to use TDD (Test Driven Design) to combat this. Let the customer, as suggested by the paper, to write the Unit Test code.

A good API reads correctly and sensibly in the user's code and not in the implementer code. Far too many 'designer' starts the API design from an implementation point of view concerning too earlier with the implementation details, which can lead to a break down in abstraction. APIs are the visible interfaces to these abstractions.

In component technologies that heavily relying on interfaces, it is important the consultants or designers begin the process on the interface.

Using UML diagram is a good starting point as you can quickly play out the scenario to see the effect. At the same time it can document the requirements (Activity/Use case diagrams), how it is to be used (sequence diagrams), or error states (State Diagrams). Then at a later stage, have executable documentation in the form of Unit Test code.

The second most import point in my mind is to strive for 'miminalist' approach:
The fewer types, functions, and parameters an API uses, the easier it is to learn, remember, and use correctly. This minimalism is important. Many APIs end up as a kitchen sink of convenience functions that can be composed of other, more fundamental functions.
This topic was given a detail treatment by Scott Meyers, "When it comes to encapsulation, sometimes less is more.". Or the YAGNI principle.

I once worked for a company that prides itself in designing kitchen-sink API, regardless if it is COM or pure C-style interface. Methods are thrown into any place it can stash regardless if they make sense. Management only interested in getting things out quickly and applying bums-on-seats resource allocation algorithm and the result speaks voluminously of the foolishness of this myopic style, for a long time.

The article touches on the issue confronting the immutability, a term not used by alluded to, which can cause "
crud that, eventually, does more damage than the good it ever did by remaining backward compatible.". When that happens, it is better to start again!

The paper correctly lays blame on education, particularly many developers are not interested or have the patience and time to learn the art and are only interested in getting something 'working' in the IDE. Experience is also overlooked when selecting someone to the task, as identified by the paper.

The example the author used to illustrate a bad API design touches on a topic that .Net/Java should have considered. The author complains about the destruction of the input parameter when using the Select() method and the API method was not dutifully documented.

In C++, you have const member function and const parameters to allow compiler to catch any misuse and to tell user of the consequence of calling the method. But this is sadly not available in .Net/Java. While you have out and ref qualifier but they serve a different purpose.

In .Net/Java, one cannot be sure what would happen to a parameter when you make a call; the method could change the state of the object, as illustrated in the example, it could take a copy of the data (cloning it), or it could hold onto the reference of the object. The latter allows the holding object to change the state of an object it has a reference to and that changes can then be reflected in some other part which has also holds a reference to this object.

All these unknowns require explicit documentation that not too many developers read and can make the API harder to use. My advice is if in doubt, use the "Learning Test" test pattern, which also has an effect of detecting changes in API's behaviour over time.

CLR does not have any support to make sure a method does not alter the state of an object; VB has a language-level construct but it is just a smoke and mirror.

On the topic of cloneable, this can be a double-edged sword. In defense of .Net, the general recommendation is not to implement ICloneable. One such problem is what if an inner class does not support ICloneable and the other is that the caller has no idea if a deep or shallow copy is used. In many way this is the flip side of C++ in which copying an object is a natural behavior.

"Test-Driven Development - by Example" by Kent Beck, Addison Wesley, 2004, Chapter 26, "Learning Test"

Friday, May 1, 2009

Web Pages/Application - a glorified dumb terminal?

I have always equipped with my web developer friends that in my opinion, web pages/applications are nothing more than a modernised dumb terminal applications with colourful pictures. Now I have found an author in agreement with my observation:
In many ways, the programming model has gone back to the model that dominated the mid1970s, when large mainframes served output to terminals connected directly to them. Users would submit jobs to the mainframe and get output to their terminals. So, what’s changed here? First, the terminal is a lot fancier—it’s a powerful PC running a browser that interprets HTML. The endpoint to which the browser connects is a Web server (or perhaps a server farm). Finally, the connection protocol used by the client and the server is indirect (and a request can quite literally cross the globe before the user sees a result).

"Microsoft ASP.NET 3.5 Step by Step" by George Shepherd, Microsoft Press 2008

Blog Archive