---
# System prepended metadata

title: Programming Is the Easy Part | J. B. Rainsberger
tags: [evolutionary-design, design]

---

###### tags: `evolutionary-design` `design`

# Programming Is the Easy Part | J. B. Rainsberger

_https://www.youtube.com/watch?v=SbGiSH_8UGk_ 

{%youtube SbGiSH_8UGk %}

Programming is the easy part COMPARED to the other parts :smile: 

Most of the time, when I work with teams and we sit down together in front of a programming problem, after a couple of hours we find out that the real problem, the real reason that we are having this conversation, goes beyond the issues of programming, it's not technical...

## How to master programming: Evolutionary Design :bulb: 
There's a lot of lack of confidence... like
* _I could never do that_, 
* _I wish I have had different kind of training_, 
* _he's born for that, I'm not_

...nonsense...

One of the secrets to programming well is **becoming confident with Evolutionary Design**.

**Evolutionary Design** means willingness to allow the design to evolve: the design is evolving while you are guiding the shapes of the code.

Ok, but how do you do that?

* Kent Beck's 4 rules of simple design
* Coupling and Cohesion concepts
* SOLID principles 
* the ideas in the seminal book "Object-Oriented Software Construction" by Bertrand Meyer

can all be reduced to two basic ideas:

* **remove duplications**
* **improve names**

All principles we use in designing software are "linear combinations" of **remove duplications** + **improve names**.

## How does this work? Removing duplication creates the need to naming things

While writing code, you note **duplications** (of code, of procedures, of ...). Duplications can cause bugs (you change 9 places out of 10 of duplicated logic => you've just introduced a bug...), so you **remove the duplication**, creating a new "container" in your system. 
This new "container" may be 
* a constant
* a variable, 
* a class, 
* a function, 
* a method, 
* a namespace, 
* a package, 
* a module, 
* _whatever..._

Removing a duplication you're actually reducing the amount of things you need to change.

Now, when you create a new structure, **you have to give this "thing" a name**.

### Naming things is an iterative process

We programmers are not very good at naming things.
The first name given to this new "thing" is not very good... but explaining what that thing is to another person can help you find a better name, from nonsense to intention revealing, improving it and making a little better every day.

Arlo Belshee has a very detailed process for naming things https://www.digdeeproots.com/articles/on/naming-process/

![](https://i.imgur.com/0od9pC9.png)

![](https://i.imgur.com/jscyXXV.jpg)

*(see also https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names)*

When you name things better (honestly, precisely), patterns in the names suggest patterns in the design.

E.g. you start to notice that the name of a given technology domain concept ("persistent", "customer", "transaction", ...) is scattered in many places throughout the code.

### Simple rule of cohesion in names

* **Names that are related to each other should be closed together**
* **Names that are not related to each other should be further apart**

This is what we call **Cohesion**.

Following this rule, what happens is that **responsibilities** in the code starts to move and gather in a sensible place:
* related code moves closed together
* unrelated code moves father apart

This in turn makes it **easier to change code**, because there's a higher chance that **changes are all localized** in one "place" instead of creating a "domino effect" where we change here, than we have to change there, and there and there ..., where the changes ripple throughout the codebase.

The change is also easier because when changing code you don't have the risk of changing unrelated things at the same time, because the unrelated stuff has been moved in another place, far from here: you are more confident that **you only change the parts that need to change**.

See also Kent Beck's talk about Coupling and Cohesion: https://hackmd.io/2fXGQXhZQWutE7C-ZhSw_w?view#Cohesion

### New abstractions emerge

While you keep improving **Cohesion** by moving similar thing closed together and different things farther apart, you are going to be able to treat each new "container of similar things" as one thing in the way it interacts with the code nearby: you won't need to know all the details of everything that is happening inside that "container". 
This is what **Abstraction** is like.

**Abstraction means hiding details**: looking at the code, I can treat it a single thing.

* some abstractions can be useful, if you hide the details that don't matter, 
* some abstractions are bad, if you hide the details that are important.

While you keep introducing new abstractions, you can look at your code and see the key parts that you need to know in order to use that codebase, the parts the outside world actually cares about, with all the noise and distraction of details hidden behind the abstractions.

Having no more distractions, you can now see bigger patterns, higher level patterns.
You see higher level forms of DUPLICATIONS! :recycle: 
And back now to remove duplications!

### The loop :curly_loop: 

Remove duplications => add new structures to the system => give names to those structures => slowly find better names => code moves closed together that should be closed together, and further apart that should be farther apart => easier to introduce new abstractions => easier to ignore 90% of code and see higher-level patterns => notice new forms of duplications at a higher level of the system => ... until you get to the entry point of the system and there's nothing left to do.

![](https://i.imgur.com/2DH2Hgb.png)

## Evolutionary Design

Evolutionary Design allows us to deliver features sooner, and that is a key factor for stakeholders.
But we devs should practice Evolutionary Design because it make things easier for programmers, as it allows us to **build a system with confidence even without knowing all those needs to be done in advance or having a clear design in mind**, improving the design of code a little bit every day, so that introducing a new feature will not that hard.
That's why is important to practice evolutionary design!

**Evolutionary Design helps in being more confident to add features to the system over time.**
TDD is a way of practicing evolutionary design, not the only way possible though.

Evolutionary Design helps you learn the principles of modular design.
From modular to functional programming? Fine!
Objects are just cohesive collections of partially-applied functions, the constructor is just partially-applying parameters in a function.

## Beyond being a master of programming...
Being a master of programming won't solve all of our problems: not all problems are related to code or design, many problems are outside the tech side.

### Having time to learn new stuff

Time is not your problem!

* *I don't have enough time* => hopeless
* *I have too much to do?* => now you have a new option: **figure out what you shouldn't be doing, then don't do it**

That's the essence of real Agile (*maximizing the amount of work not done*).

#### 2-minutes rule
When somebody ask to do something...

* `<` 2 minutes? => do it now
* `>` 2 minutes? => add it to your plan

Keep track of the all things that you agree to do, that "plan" will be huge, full of stuff...  Stop and realize that you should be honest and star doing less.

### Navigating the people
To improve interaction with other people: **Satir's interaction model**, to debug bad conversations with people.

Satir interaction model has four parts.

The last parts: 
* **significance** => interpretation
    * *what is causing this person to say this to me, this way, in this context, right now*
    * *what is she thinking?*
    * we are interpreting what's happening
* **response**: that's the reaction to the other person's behavior

We typically try to change the other person's response (*stop yelling to me*, *stop saying that thing*, ...), and that won't work.

That's because how we respond, the path from interpretation to response, is automatic and entwined in our human being. 
It's
* automatic
* hard to change
* perfectly rational (we would have the same response given the same interpretation)

So, you should not try to change the way they're acting (they're response), because that's hard (being automatic, involuntary and rational)

So, focus on interpretations instead.

One technique: **3 interpretations**:
when someone behave in a way that you don't like, try to think to at least 3 different ways they could interpreting what's going on that would lead them to behave that way.
To recover the conversation.
I'm going to change the way I act, change what I say to let you interpret me the way I mean to be.


## References

* [JB's notes for the talk](https://www.dropbox.com/s/bph16bsi9ogy8dh/20191106-Programming%20Is%20the%20Easy%20Part.pdf?dl=0) (PDF)
* [Putting An Age-Old Battle To Rest](https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest) (blogpost)
* [The Four Elements of Simple Design](https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design) (blogpost)
* [Continued Learning: The Beauty of Maintenance - Kent Beck - DDD Europe 2020](https://hackmd.io/@pierodibello/Continued-Learning-The-Beauty-of-Maintenance---Kent-Beck---DDD-Europe-2020) (notes)