Human-driven development

Naveen Muguda
5 min readMay 1, 2018

Writing software is a unique challenge, It has to be understood by computers that execute them and humans who develop, enhance and maintain them. Computers and Humans have contrasting characteristics, which need to be addressed in the process of software development.

Computers excel in doing repetitive tasks, doing them fast and for long, they are reliable, cheap, can handle large quantities of data, and transmit them at breakneck speed. Humans are costly, heterogenous, goal-oriented, and creative, they ideate and convert those ideas into code. Unlike machines, they have limited memory, energy, and working hours.

Consider the code snippet below, which is from Java Integer’s bit count method.


public static int
bitCount(int i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}

Computers won’t have a problem executing it, while most programmers will have a tough time understanding it. The program might be fast and efficient but isn’t maintainable. Almost always, the gains in program efficiency don’t offset the loss in programmer productivity.

We need machines to execute programs, and humans to build, enhance and maintain them. Programs can invoke distinct responses from computers and humans.

Unfortunately we, the programmers have been taught, incentivized, and conditioned to think the language of machines, which means problems like the ones caused by the code snippet above are prevalent. The rest of this post suggests tools and techniques to mitigate these kinds of problems.

Writing code is like ..writing

Programs like poems, posts, or novels need to be understood by other programmers. Code enters into maintenance mode after the first statement is written. Writing comes in many flavors, prose, poetry, essays, novel, stories, etc. Let’s see what these have in common with programming.

Thriller vs Report

One of the good thriller movies, I have watched is “Gone Girl”. A good plot like this drops clues, has twists and turns, occasionally and intentionally misleads viewers, and delays jumping to the crux, before coming to a grand finale while keeping the audience engaged throughout.

compare the experience with this report. The first paragraph provides a summary and each subsequent paragraph adds more detail. One can stop reading in between and get detail commensurate with the amount read.

consider the implementation of bit count shown above, understanding that code has similar twists and turns, feeling of intrigue, and a-ha moments as some of the thriller plots.

given that more time is spent reading vs writing code and programs are read many times programs should be closer to being reports than thrillers.

What makes a good thriller?

some of the qualities are 1)complex characters 2) confrontations and 3)careening

Their opposites of simplicity, collaboration, and predictability should be what we seek in programs

Let’s now look at what makes a bad report. The qualities are 1)Doesn’t answer the brief 2) Badly structured 3) Too much/too little/irrelevant material 4)Doesn’t relate results to purpose. These qualities would make programs bad as well.

unlike a novel, which is read when it is completed, programs may be read by other programmers during their evolution, and some projects can run for years or even decades. Other programmers contribute code as well, which makes software development an act of collaborative reading and writing.

if a novel were to have too many characters or is too complex, it wouldn’t be an enjoyable read, Similarly, software needs components and modules with just enough character to facilitate effective storytelling/composition.

Responsibility Driven Design

Responsibility Driven Design is a design technique that focuses on assigning and distributing responsibilities amongst objects and classes. It involves concepts such as well-known stereotypes, one or a few of which are assigned to different kinds of objects. As well as identifying mechanisms, metaphors, stories, and themes.

Essence over Ceremony

remember how irrelevant details make reports bad, the same is true for programs. Programs with irrelevant detail have a high signal-to-noise ratio. Programmers have limited time and energy, and badly written programs can make them spend these inefficiently.

Composed Method

A simple and yet effective technique is composed method pattern. This layers code by hiding ceremony from the essence.

Abstractions

often quoted, but not sufficiently applied is the faculty of abstraction. the word abstraction is derived from subtraction, it is about taking away unnecessary information by elimination and delegation. It is the basis of principles such as KISS, DRY, and YAGNI. It is applicable both in data as well as control dimensions.

A common source of resistance to abstractions is the lack of familiarity, which is mistakenly perceived as complicatedness. In mediums such as novels, the writer has time to build characters. Similar patience levels might be missing in peer programmers. A culture of experimentation, knowledge-seeking, and refactoring is key to overcoming this form of resistance.

Declarative Programming

Declarative programming is a way of abstracting control mechanisms through composing higher-level abstractions.

Find below two implementations of the sum function. notice the expressiveness of the latter.

int sum(List<Integer> list) {
int sum = 0;
for(int index = 0; index < list.size(); index++)
sum += list.get(index);
return sum;
}
int sum2(List<Integer> list) {
return list.fold(0, (x,y) -> x + y)
}

You might encounter similar problems learning and adopting declarative programming as another well-abstracted code. Having a good culture is the answer to mitigating these problems as well.

Ubiquitous Language

Often important stakeholders aren’t just programmers. They might be users, product managers, domain experts, and business owners. Their understanding, expertise, and feedback are key to good software. Their strengths and limitations are similar to those of programmers. Building a ubiquitous language is a way of reducing semantic gaps, and impedance mismatches, and improving the agility of change. This language has to be based on the domain model, it is another manifestation of good abstractions.

Domain-Specific Languages

Domain-specific languages are amongst the most powerful abstractions. They provide a language that resembles the business. The development of DSLs can be broken down into building rich semantic models and encoding them as language. often the former itself brings significant Return Of Investment. Domain-Specific Languages can be considered to be machine-readable versions of Ubiquitous language.

BDD and DDD

Behavior Driven Development and Domain Driven Design are methods to actively engage the stakeholders in the development of software. You can consider BDD as testing of the system from the lens of Ubiquitous language.

Conclusion

Humans are key to building useful, relevant, and agile software. Writing well needs knowledge and deliberate practice, writing software is no different. Speaking the language of business, and hiding details from the essence is the key to the techniques listed in this post. One can pick and choose a subset of the techniques based on your organization and business context.

--

--