liveBook · Manning

Consistency

As explained in Simple Object-Oriented Design: Create clean, maintainable applications

Consistency is the property of related software or domain data satisfying required rules and remaining mutually coherent.

Consistency means keeping an object’s state synchronized, valid, and coherent with program rules and user expectations. A consistent object rejects changes that would make it invalid, so clients can trust it without repeating checks or coordinating related fields themselves. This reliability reduces bugs and makes changes easier to maintain. section 3.1 section 1.2.2

Put responsibility for an entity’s data consistency in the entity that owns that data. Encapsulate fields and expose operations that perform a complete valid change, rather than exposing internal structures or requiring callers to update several values in sequence. When clients must remember follow-up updates, the design has distributed a single invariant across the system. section 3.1.1 section 3.0

Move the invariant into the operation

An Offering has employees, a maximum capacity, and available spots. A fragile design lets a client check capacity, add an employee directly to the employee set, then decrement available spots. Missing any step leaves the offering invalid. Prefer addEmployee(): it rejects enrollment when no spots remain, adds the employee, and decrements the count as one controlled operation. Do not return the mutable employee collection when clients could bypass that operation. section 3.1.3 section 3.4.2

Use consistency as a practical design test:

  • Ask whether a client must do work to keep an object valid. If so, move the rule and its state update behind an object operation. section 3.1
  • Avoid setters for attributes governed by business rules; reserve ordinary setters for descriptive attributes, or give rule-enforcing operations meaningful names. section 3.4.2
  • For complex object graphs, use aggregate roots to protect invariants; consider direct access or eventual consistency only after weighing performance or framework benefits against maintenance cost. section 3.7 section 3.5.1
Listing 3.3 Offering entity with the new addEmployee() method
class Offering {
 
  private int id;
  private Training training;
  private Calendar date;
  private Set<Employee> employees;
  private int maximumNumberOfAttendees;
  private int availableSpots;
 
  public Offering(Training training, Calendar date,
    int maximumNumberOfAttendees) {
    // basic constructor
  }
 
  public void addEmployee(Employee employee) {     #1
    if(availableSpots == 0)
      throw new OfferingIsFullException();
 
    employees.add(employee);
    availableSpots--;
  }
 
  public int getAvailableSpots() {                 #2
    return this.availableSpots;
  }
}

The listing contrasts caller-managed capacity with an operation that owns the enrollment rule and synchronized update. section 3.1.3

Consistency is not an argument for unnecessary elegance. Some persistence, performance, or boilerplate constraints can justify relaxing aggregate boundaries, but make the tradeoff explicit. If related aggregates must remain aligned, domain events can notify the other aggregate while accepting eventual consistency. section 3.5.1

Keeping objects consistent is one part of controlling complexity over time. Alongside simple code, dependency management, abstractions, infrastructure handling, and modularization, it helps produce code that developers can modify with more confidence. section 1.2 section 1.7

How Simple Object-Oriented Design: Create clean, maintainable applications covers it

How deep it goes
Explains encapsulated invariants through an Offering refactoring, setters, validation, and aggregate-root tradeoffs; defers deeper aggregate design.
Examples
Illustrates capacity-controlled enrollment in an Offering and contrasting protected and unprotected baskets.
What it assumes
Assumes object-oriented classes and methods while teaching consistency from encapsulated state changes.
What you can do after
Apply it by placing invariants and synchronized updates inside entity operations rather than in clients.
How it connects
Connects consistency with encapsulation, validation, setters, aggregate roots, domain events, and eventual consistency.

Also explained in

Compare how 20 books explain consistency →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Simple Object-Oriented Design: Create clean, maintainable applications. The section links point to the parts of the book it draws on.