TPP Topic 8: The Essence of Good Design
Tags: thepragmaticprogrammer, book, programming, education
Published: 2019-07-20 11:19:13

---
categories:
- The Pragmatic Programmer
published: true
tags:
- The Pragmatic Programmer
- book
- programming
- education
title: 'TPP Topic 8: The Essence of Good Design'
---

> This post originally appeared on [steadbytes.com](https://steadbytes.com/blog/the-pragmatic-programmer-20th/topic-8-challenges/) 
<div></div>
> See the [first post](https://dev.to/steadbytes/the-pragmatic-programmer-20th-anniversary-edition-series-1e2l) in The Pragmatic Programmer 20th Anniversary Edition series for an introduction.

## Challenge 1

> Think about a design principle you use regularly. Is it intended to make things easy-to-change?

Pure functions! Outside of [Functional Programming](https://en.wikipedia.org/wiki/Functional_programming), this is perhaps a lesser used/considered design principle - often superseded by principles such as [SOLID](https://en.wikipedia.org/wiki/SOLID) and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). However, I have found it to be a very effective principle to follow no matter the programming paradigm being used.

> In computer programming, a pure function is a function that has the following properties:
>
> 1. Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).
> 2. Its evaluation has no side effects (no mutation of local static variables, non-local variables, mutable reference arguments or I/O streams).

> -- Pure Function, [Wikipedia](https://en.wikipedia.org/wiki/Pure_function)

This definitely makes code easier to change. Since a function depends only its inputs, it can be understood _independently_ of the surrounding system. This means, for example, that the function can be changed with the knowledge that it's not going to break something else through shared, mutable state.

## Challenge 2

> Also think about languages and programming paradigms (OO, FP, Reactive, and so on). Do any have either big positives or big negatives when it comes to helping you write ETC code? Do any have both?
>
> When coding, what can you do to eliminate the negatives and accentuate the positives?

I'll address a few points for several paradigms only - this could be an entire book in itself! Please do note the emphasis on phrases such as 'it can' and 'in theory'. These are not absolute truths and I don't believe that any programming paradigm is outright incorrect or bad. These are _pragmatic_ assessments of some of the positive and negatives of each from my experience.

### Object Oriented

#### Positive

Classes _can_ split Software up into small pieces of functionality/behaviour. Each provides an interface which can be used by other classes to exercise the _behaviour_ of that class without needing to understand the algorithms used to achieve it. This, in _theory_, makes Software easier to understand by hiding details behind _abstractions_ and allowing the internals of these classes to change without requiring changes to the rest of the system.

#### Negative

Actually splitting the behaviour of Software into discrete classes becomes difficult for any non-trivial scenario. This can often lead to [leaky abstractions](https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/) and complex [inheritance hierarchies](<https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)>) - both of which make code **harder to change** and manage over time.

### Functional

#### Positive

A program is modelled as a _composition_ of many small functions. Each of these functions performs one small operation (usually in a pure manner) upon some data. The program is therefore a set of _transformations_ of data which can each be be easily reasoned about. This compositional design can make changing a program simple - compose some function with another to produce a different output.

#### Negative

Due to a large number of small functions, it _can_ become difficult to find where to change the code to affect the intended behaviour change. Furthermore, it _can_ be difficult to change the underlying data within the program. Since a functional program is a series of transformations on some simple data structures, adding new keys and/or values to these _can_ causes cascading changes throughout the program. There are of course ways to design a program to where this is not the case, however this can take a lot of skill and experience to do effectively.

### Procedural

#### Positive

A program reads from 'top to bottom', in theory allowing one to comprehend the process/steps performed by a program. This can make changes easy as it is clear where each step in the program takes place and how it works.

#### Negative

For any non-trivial scenario, it can be very easy for procedural programs to fall into the trap of [spaghetti code](https://en.wikipedia.org/wiki/Spaghetti_code). Furthermore, since the algorithms and inner working details of each step are present it can become difficult to parse out the high level steps (the 'what') from the low level details (the 'how').

## Challenge 3

> Many editors have support (either built-in or via extensions) to run commands when you save a file. Get your editor to popup an ETC? message every time you save and use it as a cue to think about the code you just wrote. Is it easy to change?

Using [Vim](https://www.vim.org/) on Ubuntu (and most Linux distributions), this can be achieved using the [Autocommands](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) and [notify-send](http://manpages.ubuntu.com/manpages/xenial/man1/notify-send.1.html) :

```bash
:autocmd BufWritePost * !notify-send "ETC?"
```