Knowledge is power, but you must watch yourself fail in order to leanrn.

There will be code

Specifying requirements in such detail that a machine can execute is programming. Not event a human can is able to do what a customer wants, and not what they say. Wading - impeded by the bad code. We all lock at the mess we’ve done, and leave it for another day.

LeBlankc’s law: Later equals never.

The total cost of owning a mess

The fault is not only the manager’s, but the major part is the developer’s. It’s unprofessional for programmers to bend to the will of managers, who don’t understand the rists of making messes.

Clean code

Code should be elegant and efficient, not to tempt people to make the code messy. Thus it should be full of crisp lines of control and without duplications to make it easy for other people to enchance, and has unit tests. It is a code that has been taken care of.

Don’t believe in all you read, behoove to learn.

Meaningful Names

Names should reveal intent without a context.

Avoid disinformation

Make meaningful distinctions

ProductData, ProdactInfo - non-informative meaningless distinction getActiveAccount(), getActiveAccounts() and getActiveAccountsInfo()

Avoid encodings

NameString

Avoid mental mapping

a, b, c - apples, bananas, cherries

1 word per concept

fetch, retrieve, get

Problem domain names

Separate solution domain names from problem domain names

Functions

Small, do one thing, do it well, do it only. Function that is doing 1 thing can’t be reasonably divided into smaller functions.

One level of abstraction per function

It should describe the current level, and refference to the next one.

Name

Long descriptive name is better than a long descriptive comment.

Commoon monadic forms

Don’t mix input arguments with output arguments.

Flag arguments

Are ugly, as it implies that the function does more than one thing.

Dyadic functions

assert(expected, actual)

No side effects

as they are lies.

Command query separation

Either do or answer

DRY (Don’t repeat yourself)

Comments

// skip this section

Data Abstraction

Procedural code makes it hard to add new data structures because all the functions must change. OO code makes it hard to add new functions because all the classes must change.

The law of Demeter

A module should not know about the innards of the objects it manipulates.

// Appears to violate the Law of Demeter if they are not data structures, but have behavior.
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();

It is better to ask to do smth

final BufferdOutputStream bos = ctxt.createScratchFileStream(classFileName);

DTOs, Bean, Active Record

class Dto { // Pure data structure
  public String name;
}

class Bean { // Bean
  private String name;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}

Objects should expose behaviour and hide data.

Easier to add kinds of objects wihtout changing existing behaviors. Data structures expose data and hove no significant behaviour. Easier to add new behaviors without changing existing data structures.

Error Handling

Use exceptions rather than return codes.

try {
  tryToShutDown(); // I like the function name
}

Define normal flow

Null

When we return null, we are foisting problems upon callers.

Boundarie

Wrapping third-party API minimizes the dependency on it.

Unit Tests

Test code is just as important as production code. Good architecture gives the posibillity to make changes, tests allow to make changes.

A dual standard

It is perfectly fine to have uneficient tests, as long as they are clear.

Classes

SPR

Class should have one reason to change.

Cohesion & Coupling

OCP

DPI

Classes should depend on abstraction, not on concrete details.

Systems

class System {
  public Service getService() {
    if (service == null)
      service = new MyService(); // tied to dependency
    return service;
  }
}

Startup code is different from runtime code

Main -> LineItemFactory -creates LineItem-> <- OrderProcessing
Implement only today’s stories, then refactor and exapdn as the system grows to implement new stories.

Cross-cutting concerns

Logging, transaction management, security, performance monitoring, etc. In AOP (Aspect-Oriented Programming) these concerns are called aspects and are separated from the main business logic.

class Bank {
  public void makeDeposit(int amount) {}
}

class PersistentBankProxy {
  private Bank bank;
  private TransactionLog transactionLog;
  public void makeDeposit(int amount) {
    bank.makeDeposit(amount);
    transactionLog.logDeposit(amount);
  }
}