Digital Edition

SYS-CON.TV
The Benefits of Well-Written Software
Make excellence a habit

Mae West, the indomitable actress/comedienne of the 1930s and '40s, left us with some unforgettable quotes. She gave us such lines as, "When caught between two evils, I generally pick the one I've never tried before," and "Too much of a good thing...can be wonderful." She also offered the ironic observation that "Virtue is its own reward."

It does seem that way at times, even for software developers. During the heyday of the "dot-com boom," signing bonuses were being passed out for anyone who could spell "HTML" and the benefits of well-written software were passed over in favor of "speed-to-market." But perhaps virtue does offer more than Ms. West thought. Where are the dot coms today that embodied such questionable values? Maybe virtue is more like a slowly ripening fruit.

We often associate virtue with noble acts - or at least with the avoidance of ignoble ones. But virtue has a more ancient meaning - one associated with strength, courage, and excellence. As software developers, these are values that are very germane to writing excellent code.

But with virtue comes temptation. Given a software project, there's both an easier and a harder approach. The easy way is to design/code/plan simultaneously. The slogan for this approach might have been taken from a popular ad campaign: "Just Do It." In this approach, we decide what the requirements are and then start coding. We'll know where we're going when we get there.

The harder way is to design software according to sound software engineering practices. Doesn't sound nearly as exciting as jumping into code, does it? Such an approach relies on us knowing what good practices are and how to implement them, and this is seldom a simple task.

Before you dismiss the first approach as something no self-respecting developer would use, consider the pressures from clients and managers to adopt it. Clients want the job done yesterday. There's no time to plan: we have to get coding! And for many managers, a developer who isn't coding isn't working. Then, there may be pressure from within: coding makes us feel like we're being productive. Planning is often frustratingly slow, with nothing but a few diagrams to show for it.

Worse, there's often very little apparent difference at the moment the software is deployed. In both cases (hopefully!), the code "works." But the difference between good and shoddy workmanship reveals itself over time. Whether the job is plumbing or programming, poor workmanship springs leaks. Yes, the code may work now, but how adaptive will it be to the changes that are inevitable? To the maintenance that consumes, on average, 70-90% of the cost of software over its lifespan?

Most of us do maintenance programming even though in most cases, it is not the favorite aspect of our jobs. For all but the most trivial of changes, there's usually a great deal of studying of existing code to be done before we can integrate the new functionality with the current program. Often the change seems simple to the client and manager, who remain blissfully unaware of how that change will affect the rest of the program.

Unfortunately, we're often unaware, too. Existing software is like the ancient Gordian knot - an intractable knot that an oracle decreed would be loosed by the person who would rule over all of Asia. Everyone who tried the knot failed - until Alexander the Great. Studying the problem, Alexander unsheathed his sword and "loosed" it by hewing it in two. After solving that problem, Alexander went on to rule Asia and is considered by some to be the greatest military commander of all time. That's all well and good, but Alexander never had to write software...

The way out of the problem of maintaining software doesn't lie in a sword, but in following proven software principles. I was recently re-reading The Pragmatic Programmer by Andy Hunt and Dave Thomas, and was struck by their discussion of what they term "orthogonality." The term is borrowed from geometry, where two lines are said to be "orthogonal" if they meet at right angles. Andy and Dave explain: "In vector terms, the two lines are independent. Move along one of the lines and your position projected onto the other doesn't change."

Applied to software, orthogonality means that one module is independent of another so that you can make a change to one module without making a change to the other. The term, orthogonality, is original to the book, but the ideas are not: they express the twin virtues of tight cohesion and loose coupling found in good software engineering practices. Components that cohere are highly focused. They have a well-defined sphere of responsibility. Components that are loosely coupled do not need to know about other components to do their work.

While the absolute realization of these virtues is probably beyond possibility, even an imperfect implementation provides considerable benefits. Orthogonal components lead to greater productivity:

  1. Code for orthogonal components is easier to write and test. Because the component is largely self-contained, component code doesn't need to be concerned about how other components will be affected by its internal implementation. All that is required is a clear, consistent interface to the component.
  2. The chance for reuse is much higher in orthogonal code. As the functionality of a piece of code increases, the chances for it to be useful to another application decreases. Orthogonal components = simpler components = more code reuse.
  3. Developers can more easily divide responsibility for separate pieces of a project. These pieces can then be given to other developers or teams of developers. With dependencies reduced and the nature of each module well-specified, developers are freer to write their own pieces of the application on their own. This leads to a decrease in the amount of formal communication (read "meetings") needed to keep the project coordinated.
Orthogonal components lead to decreased risk:
  1. Code that is found to be faulty is isolated to a single component, decreasing the chances that bad code will have an infecting influence on the entire application.
  2. Changes to the requirements of an application over time are a foregone conclusion. But often small changes are confined to a single module while large changes may occasion an entirely new module. In either case, the risk of introducing a bug while adding a feature declines.
  3. The chance that all software will be thoroughly tested is greater with orthogonal code. Trying to test an entire system full of dependencies is a daunting task, so daunting, in fact, that full testing is often omitted. With small, discrete components, testing is much easier to do and, therefore, more likely to be done.
All this talk of the benefits of orthogonal code does not, unfortunately, get us any closer to the goal of ensuring that our code is orthogonal. Nor will good intentions alone bring us to the mark. One thing that will help, though, is the faithful implementation of an application framework that is built to support the twin goals of tight cohesion and loose coupling. Fortunately, we have two such frameworks in Fusebox 4 (www.fusebox.org) and Mach-II (www.mach-ii.com).

Both frameworks will support and encourage you to write orthogonal code, though in different ways. Fusebox was written for procedural programming while Mach-II supports object-oriented programming. Ah, but surely OO is better? Consider this quote from The Pragmatic Programmer: "Object technology can provide a more orthogonal system, but because it has more features to abuse, it is actually easier to create a nonorthogonal system using objects than it is using a procedural language....While you can always write ‘spaghetti code' in a procedural language, object-oriented languages used poorly can add meatballs to your spaghetti." No matter how venerable the buzzword, it seems there is no escape from the need for a deep understanding.

When speaking at user groups and conferences, I usually run into someone who tells me confidently that the code he or she writes is superior to Fusebox, Mach-II, or any other system. Often they think this will provoke a reaction. It does: "I wouldn't be surprised at all if your code is tighter or better performing," I tell them quite sincerely. When they appear surprised, I explain that creating a software application is something very different from creating a system for developing software applications. "Can you grill a better burger than McDonald's?" I ask them. Most of the time, they assure me they can. "Me, too," I tell them. "But what I can't do is create a better system than McDonald's has for predictably, repeatedly producing burger after burger that meets its specifications."

To have predictable, repeatable software successes, we need to understand and implement the principles of good software engineering. Tight cohesion and loose coupling - orthogonality - are two of the most important of these virtues. Learning how to properly implement these virtues is the work of a lifetime. I began this article with a quote on virtue from Mae West. I'll end it with this one from Aristotle: "Excellence is an art won by training and habituation. We do not act rightly because we have virtue or excellence, but we rather have those because we have acted rightly. We are what we repeatedly do. Excellence, then, is not an act but a habit."

About Hal Helms
Hal Helms is a well-known speaker/writer/strategist on software development issues. He holds training sessions on Java, ColdFusion, and software development processes. He authors a popular monthly newsletter series. For more information, contact him at hal (at) halhelms.com or see his website, www.halhelms.com.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

I feel disappointed with this article. It alludes to offer insight into sound software practices, which it does to some extent, before switching tracks and without justification declaring Fusebox 4 or Mach-II as a champion of both concepts and hence the right choice. I've heard better explanations of why the frameworks are valuable.




ADS BY GOOGLE
Subscribe to the World's Most Powerful Newsletters

ADS BY GOOGLE

The explosion of new web/cloud/IoT-based applications and the data they generate are transforming ou...
CI/CD is conceptually straightforward, yet often technically intricate to implement since it require...
Containers and Kubernetes allow for code portability across on-premise VMs, bare metal, or multiple ...
Enterprises are striving to become digital businesses for differentiated innovation and customer-cen...
Digital Transformation: Preparing Cloud & IoT Security for the Age of Artificial Intelligence. As au...
DevOps is often described as a combination of technology and culture. Without both, DevOps isn't com...
DXWorldEXPO LLC announced today that All in Mobile, a mobile app development company from Poland, wi...
The now mainstream platform changes stemming from the first Internet boom brought many changes but d...
DXWorldEXPO LLC announced today that Ed Featherston has been named the "Tech Chair" of "FinTechEXPO ...
Chris Matthieu is the President & CEO of Computes, inc. He brings 30 years of experience in developm...
Bill Schmarzo, author of "Big Data: Understanding How Data Powers Big Business" and "Big Data MBA: D...
Andi Mann, Chief Technology Advocate at Splunk, is an accomplished digital business executive with e...
In this presentation, you will learn first hand what works and what doesn't while architecting and d...
The Internet of Things is clearly many things: data collection and analytics, wearables, Smart Grids...
To Really Work for Enterprises, MultiCloud Adoption Requires Far Better and Inclusive Cloud Monitori...
We are seeing a major migration of enterprises applications to the cloud. As cloud and business use ...
If your cloud deployment is on AWS with predictable workloads, Reserved Instances (RIs) can provide ...
Disruption, Innovation, Artificial Intelligence and Machine Learning, Leadership and Management hear...
We build IoT infrastructure products - when you have to integrate different devices, different syste...
Consumer-driven contracts are an essential part of a mature microservice testing portfolio enabling ...