1 Introduction


This chapter covers

  • Important tradeoffs in production systems
  • Consequences of unit testing versus integration testing
  • Understanding that code and architecture design patterns do not fit every problem

When designing our code, APIs, and system architectures, we need to make decisions that impact maintenance, performance, extensibility, and many other factors. Almost always, the decision to go in one direction limits the possibility to evolve in a different one. The longer systems live, the harder it is to change their design and withdraw from previous decisions. The design and programming tradeoffs presented in this book focus on choosing between two or more directions in which your system can evolve. It’s important to understand that, whatever you decide, you will need to live with one direction’s pros and cons.

Depending on the context, time to market, service-level agreements (SLAs), and other factors, the team needs to make those hard decisions. We will show you the tradeoffs that we need to make in production systems and compare them with alternative ways of doing things. We hope that after reading this book, you will start to notice the design decisions that you make every day. Noticing these allows you to make conscious choices when considering their pros and cons.

1.1 Consequences of every decision and pattern

1.1.1 Unit testing decisions

1.1.2 Proportions of unit and integration tests

1.2 Code design patterns and why they do not always work

1.2.1 Measuring our code

1.3 Architecture design patterns and why they do not always work

1.3.1 Scalability and elasticity

1.3.2 Development speed

1.3.3 Complexity of microservices