The Pragmatic Approach

Victor Elizalde
5 min readJan 15, 2021

In this post I will be talking about David Thomas and Andrew Hunts’ The Pragmatic Programmer book, specifically Chapter 2, in this chapter we will talk about The Pragmatic Approach.

The Essence of Good Design

Making a good design is pretty important, not as a rule but as a value. Is is easier to change in the future a good design rather than a bad design. There is a principle called the ETC which means Easier To Change. ETC covers the main reasons for change:

  • Why is decoupling good? Because by isolating concerns we make each easier to change.
  • Why is the single responsibility principle useful? Because a change in requirements is mirrored by a change in just one module.
  • Why is naming important? Because good names make code easier to read, and you have to read it to change it.

Following ETC will help you as a programmer to develop good clean code that meets the user requirements and it is ready for any unexpected change. This adds a los of value to the code and the project, and this is always important. So, don’t see ETC as a rule but as a tool that will help you in the long run and add a lot of value to your project.

DRY — The evils of duplication

DRY is a pretty famous term. It means Don’t Repeat Yourself. And the way this works as an example is by modularizing code so that if you use a certain logic or validation in many places, you should refactor it as a single function, module, etc.

Code and requirements change everyday, is a pretty common thing and the software need to be prepared for this. If you do not apply DRY, let’s assume you use a procedure to calculate age and you use it in ten different places, if a requirement for age changes, then you will need to change the procedure in 10 different places and this can produce a lot of errors and time waste, if you forget to change one of the ten procedures the program will fail. This is what DRY prevents. You will only have to change the main function and that would be all.

You can duplicate code if a situation requires it but don’t get confused, some code duplication is necessary, let’s assume you have 2 functions that require the same logic but for different purposes, here you can duplicate it with no problem and you are not violating DRY.

DRY also applies to comments and data, watch put for duplication the intention of a function if it is already clear in the function itself. When creating an object watch out for extra variables that can be calculated with the ones you already have, for example:

class Rectangle {  Integer length;
Integer width;
Float area;
};

Here we have a duplication, area can be calculated by length and width, so it should look like this:

class Rectangle {  Integer length;
Integer width;
Float area() { return length * width};
};

Whenever a module exposes a data structure, you are coupling all the code that uses that structure to the implementation of that module. Where possible, always use accessor functions to read and write the attributes of objects. It will make it easier to add functionality in the future.

We also have duplication in APIS, data sources and between developers. There are many tools to help you reduce duplication in your APIS and have them shared for the whole team, also in data sources you can use a data structure like a hash map in order to avoid building classes or structs, and between developers the only solution is communication because we never know when someone might need the same function or process as me at the same time and we both end up implementing it, it’s alright but in the merge we need to communicate and only choose one.

Another thing we should notice is that everything you do, you should make it easy to reuse. In this example of the code duplication between programmers, when the merge comes and we have to decide one function, people will always choose the easiest one to use or reuse. If it isn’t easy, people won’t do it. And if you fail to reuse, you risk duplicating knowledge.

Orthogonality

This term is pretty useful in software development. What it suggests is that we have two lines, one pointing north and the other one pointing east. These two line should never touch each other. Each line is seen as a class, module, interface, database, etc. In your system everything has to be orthogonal. This means that if you change the database, you won’t have to change the interface and viceversa. This means that everything is independent and orthogonal. This will make your system easier to update, change and modify. If everything is dependent then a minor change will make you change a lot of code. Nonorthogonal systems are harder to maintain than orthogonal ones.

Reversibility

We can never assume something will be a fact forever, one day the client needs the pen to be blue and in some weeks now it should be red. There are a lot of practices that help us to cover this. But, there are some critical decisions like what architecture we are going to use, which database we will use, etc. These are things not easy to reverse or change, but we might have to do it someday. So, we need to keep in mind that everything should be reversible because nothing is forever.

Tracer Bullets

Sometimes we are developing in an unknown technology or software tool. Soldiers use tracer bullets to have immediate feedback when shooting the weapon. In software we apply something similar, since the software is new and not sure it can make the job, we apply tracer bullets. This means that we put goals in which we receive feedback immediately to know if something is possible or not, of course we will not have time to cover all cases or requirements, but the main goal of a tracer bullet is to shoot and see if we hit the target or not in the exact moment. With this we can validate if a certain tool or language is viable in a small period of time.

Advantages of the tracer code approach:

  • Users get to see something working early
  • Developers build a structure to work in
  • You have an integration platform
  • You have something to demonstrate
  • You have a better feel for progress

Prototypes and Post-it Notes

We build software prototypes in the same fashion as car manufactures and many other professions, and for the same reasons — to analyze and expose risk, and to offer chances for correction at a greatly reduced cost. Like the car makers, we can target a prototype to test one or more specific aspects of a project. Prototypes are designed to answer just a few questions, so they are much cheaper and faster to develop than applications that go into production.

Thins to prototype:

  • Architecture
  • New functionality in an existing system
  • Structure or contents of external data
  • Third-party tools or components
  • Performance issues
  • User interface design

Things you can ignore:

  • Correctness
  • Completeness
  • Robustness
  • Style

--

--

Victor Elizalde

Software Engineer with a passion for sharing knowledge. Also, sports lover, musician, gamer, and a tremendous food fanatic.