Skip to content

Instantly share code, notes, and snippets.

@wataruoguchi
Last active May 17, 2021 00:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wataruoguchi/61e3730a3d5c4f217a8c7d06744e348c to your computer and use it in GitHub Desktop.
Save wataruoguchi/61e3730a3d5c4f217a8c7d06744e348c to your computer and use it in GitHub Desktop.
Clean Architecture - PART 2 - Starting with the Bricks: Programming Paradigms #bookclub

Clean Architecture

PART II - Starting with the Bricks: Programming Paradigms

Chapter 3 - Paradigm Overview

Structured Programming

Born in 1968.

Structured programming imposes discipline on direct transfer of control.

Object-Oriented Programming

Born in 1966.

Object-oriented programming imposes discipline on indirect transfer of control.

Functional Programming

Born in 1936.

Functional programming imposes discipline upon assignment.

Food for Thought

Each imposes some kind of extra discipline that is negative in its intent. The paradigm tell us what not to do, more than they tell us what to do.

Here, I see sometimes that people discuss about what paradigm is the best - this type of discussion doesn't do anything. The good factors of paradigms can live together.

Conclusion

We use polymorphism as the mechanism to cross architectural boundaries; we use functional programming to impose discipline on the location of and access to data; and we use structured programming as the algorithmic foundation of our modules. Notice how well those three align with the three big concerns of architecture: function, separation of components, and data management.

Chapter 4 - Structured Programming

About Dijkstra. Compared to his era - programming by punched cards, we can code way faster. We should embrace this and take advantage - keep making iteration faster.

Proof

Dijkstra's solution was to apply the mathematical discipline of proof. His vision was the construction of a Euclidian hierarchy of postulates, theorems, corollaries, and lemmas.

A Harmful Proclamation

"Go To Statement Considered Harmful."

main() {
    int i;
    for (i = 1; i < 5; i++) {
        printf("Index is %d", i);
        if (i % 2) {
            goto isEven;
        }
    }
    isEven:
      printf("The number %d is even", i);
      return 0;
}

In that letter Dijkstra argued that unrestricted GOTO statements should be abolished from higher-level languages because they complicated the task of analyzing and verifying the correctness of programs (particularly those involving loops).

Functional Decomposition

Structured programming allows modules to be recursively decomposed into provable units, which in turn means that modules can be functionally decomposed.

No Formal Proofs

The "Go To Statement Considered Harmful." had never proved. Mathematical proofs are not the only strategy, another strategy is scientific method.

Science to the Rescue

(T)he nature of scientific theories and laws: They are falsifiable but not provable.

Tests

"Testing shows the presence, not the absence, of bugs."

Such proofs of incorrectness can be applied only to provable programs. A program that is not provable - due to unrestrained use of goto, for example - cannot be correct no matter how many tests are applied to it.

If the module is not testable, we don't know if it's "provable" - that that is not even falsifiable.

Conclusion

It is this ability to create falsifiable units of programming that makes structured programming valuable today.

Software architects strive to define modules, components, and services that are easily falsifiable (testable). To do so, they employ restrictive disciplines similar to structured programming, albeit at a much higher level.

React.js is a good example here, The rise of functional components allow developers to code with a restrictive way by its design.

Chapter 5 - Object-Oriented Programming

What's OO?

"The combination of data and function."

"A way to model the real world."

  • Encapsulation
  • Inheritance
  • Polymorphism

Encapsulation?

(A) line can be drawn around a cohesive set of data and functions. Outside of that line, the data is hidden and only some of the functions are known.

With the C lang example, it tells that functions declared using Point do not have knowledge of Point. Then, with the C++ example, encapsulation is done with public, private and protected. The properties are private (encapsulated).

many OO languages have little or no enforced encapsulation.

Developers need to follow the team's "Coding Style Guide". e.g.,) class Foo { constructor (x) { this._x = x; } } in JavaScript. The _x is accessible.

Inheritance?

We had a kind of inheritance before OO languages. OO languages made it easier to code inheritance without a trick.

Polymorphism?

polymorphism is an application of pointers and functions.

Then OO languages made polymorphism trivial - safe to use, easy to use.

The example with C is File handlers. Web APIs could also be, if we were to make more examples.

The power of polymorphism

Thus, you don't need to know the details of IO devices, you don't need to recompile every time. IO devices are the plugins to the code.

OO allows the plugin architecture to be used anywhere, for anything.

Dependency Inversion
  • Fig 5.1 - Source code dependencies versus flow of control

every caller was forced to mention the name of the modules that contained the callee.

The flow of control was dictated by behavior of the system, and the source code dependencies were dictated by that flow of control.

  • Fig 5.2 - Dependency inversion

The fact that OO languages provide safe and convenient polymorphism means that any source code dependency, no matter where it is, can be inverted.

Example - arrangement of code modules (UI, Business Rules, Database)A

  • Fig 5.3 - The database and the user interface depend on the business rules

The UI and the DB can be plugins. The business logic doesn't need to know UI's / DB's details.

  • Question - Any DI's benefit other than with tests?
  • Question - Does anyone take advantages of independent deployability?

Conclusion

OO is the ability, though the use of polymorphism, to gain absolute control over every source code dependency in the system. It allows the architect to create a plugin architecture, in which modules that contain high-level policies are independent of modules that contain low-level details.

Chapter 6 - Functional Programming

Squares of Integers

This leads us to a surprise statement: Variables in functional languages do not vary.

^ <3

Immutability and Architecture

Why would an architect be concerned with the mutability of variables? The answer is absurdly simple: All race conditions, deadlock conditions, and concurrent update problems are due to mutable variables.

The question you must be asking yourself, then, is whether immutability is practicable.

The answer to that question is affirmative, if you have infinite storage and infinite processor speed. Lacking those infinite resources, the answer is a bit more nuanced. Yes, immutability can be practicable, if certain compromises are made.

Segregation of Mutability

One of the most common compromises is to segregate the application, or the services within the application, into mutable and immutable components.

React hooks, for example. State management and side effects are defined in hooks.

Event Sourcing

Now imagine that instead of storing the account balances, we store only the transactions. Whenever anyone wants to know the balance of an account, we simply add up all the transactions for that account, from the beginning of time. This scheme requires no mutable variables.

Event sourcing is a strategy wherein we store the transactions, but not the state. When state is required, we simply apply all the transactions from the beginning of time.

Question: Does anyone take this in their app?

Conclusion

Software is not a rapidly advancing technology. The rules of software are the same today as they were in 1946

The rise of frameworks / new stack are quick, but the principles are steady.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment