Make Interfaces Easy to Use Correctly and Hard to Use Incorrectly

Make Interfaces Easy to Use Correctly and Hard to Use Incorrectly One of the most common tasks in software development is interface specification. Interfaces occur at the highest level of abstraction (user interfaces), at the lowest (function interfaces), and at levels in between (class interfaces, library interfaces, etc.). Regardless of whether you work with end users to specify how they’ll interact with a system, collaborate with developers to specify an API, or declare functions private to a class, interface design is an important part of your job.

Make the Invisible More Visible

Make the Invisible More Visible Many aspects of invisibility are rightly lauded as software principles to uphold. Our terminology is rich in invisibility metaphors — mechanism transparency and information hiding, to name but two. Software and the process of developing it can be, to paraphrase Douglas Adams, mostly invisible: Source code has no innate presence, no innate behavior, and doesn’t obey the laws of physics. It’s visible when you load it into an editor, but close the editor and it’s gone.

Message Passing Leads to Better Scalability in Parallel Systems

Message Passing Leads to Better Scalability in Parallel Systems Programmers are taught from the very outset of their study of computing that concurrency — and especially parallelism, a special subset of concurrency — is hard, that only the very best can ever hope to get it right, and even they get it wrong. There is invariably great focus on threads, semaphores, monitors, and how hard it is to get concurrent access to variables to be thread-safe.

Missing Opportunities for Polymorphism

Missing Opportunities for Polymorphism Polymorphism is one of the grand ideas that is fundamental to OO. The word, taken from Greek, means many (poly) forms (morph). In the context of programming polymorphism refers to many forms of a particular class of objects or method. But polymorphism isn’t simply about alternate implementations. Used carefully, polymorphism creates tiny localized execution contexts that let us work without the need for verbose if-then-else blocks. Being in a context allows us to do the right thing directly, whereas being outside of that context forces us to reconstruct it so that we can then do the right thing.

News of the Weird: Testers Are Your Friends

News of the Weird: Testers Are Your Friends Whether they call themselves Quality Assurance or Quality Control, many programmers call them Trouble. In my experience, programmers often have an adversarial relationship with the people who test their software. “They’re too picky” and “They want everything perfect” are common complaints. Sound familiar? I’m not sure why, but I’ve always had a different view of testers. Maybe it’s because the “tester” at my first job was the company secretary.

One Binary

One Binary I’ve seen several projects where the build rewrites some part of the code to generate a custom binary for each target environment. This always makes things more complicated than they should be, and introduces a risk that the team may not have consistent versions on each installation. At a minimum it involves building multiple, near-identical copies of the software, each of which then has to be deployed to the right place.

Only the Code Tells the Truth

Only the Code Tells the Truth The ultimate semantics of a program is given by the running code. If this is in binary form only, it will be a difficult read! The source code should, however, be available if it is your program, any typical commercial software development, an open source project, or code in a dynamically interpreted language. Looking at the source code, the meaning of the program should be apparent.

Own (and Refactor) the Build

Own (and Refactor) the Build It is not uncommon for teams that are otherwise highly disciplined about coding practices to neglect build scripts, either out of a belief that they are merely an unimportant detail or from a fear that they are complex and need to be tended to by the cult of release engineering. Unmaintainable build scripts with duplication and errors cause problems of the same magnitude as those in poorly factored code.

Pair Program and Feel the Flow

Pair Program and Feel the Flow Imagine that you are totally absorbed by what you are doing — focused, dedicated, and involved. You may have lost track of time. You probably feel happy. You are experiencing flow. It is difficult to both achieve and maintain flow for a whole team of developers since there are so many interruptions, interactions, and other distractions that can easily break it. If you have already practiced pair programming, you are probably familiar with how pairing contributes to flow.

Prefer Domain-Specific Types to Primitive Types

Prefer Domain-Specific Types to Primitive Types On 23rd September 1999 the $327.6 million Mars Climate Orbiter was lost while entering orbit around Mars due to a software error back on Earth. The error was later called the metric mix-up. The ground station software was working in pounds while the spacecraft expected newtons, leading the ground station to underestimate the power of the spacecraft’s thrusters by a factor of 4.45. This is one of many examples of software failures that could have been prevented if stronger and more domain-specific typing had been applied.