You thought technical debt was the worst?

Meet design debt!

@julientopcu.com

‪@josianchevalier.bsky.social‬

CHAPTER I

When model exploration
   Whirlpool 
      turns into
 model sinking

TODo

Current Quest

Done

Selectable Overlapping Cruises

Bug

[Ancillary]
Wireless Carrier Pigeon Connection

Feature

JIRA

Past Ships Displayed in Search

Bug

Add Cancellation Insurance

Feature

TODo

Current Quest

Done

Selectable Overlapping Cruises

Bug

[Ancillary]

Wireless Carrier Pigeon Connection

Feature

JIRA

Bug

Add Cancellation Insurance

Feature

Past Ships Displayed in Search

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW", "PANORAMIC_VIEW", "LOUNGE" ],
            "deckOptions": [ "ANY", "UPPER_DECK", "MIDDLE_DECK", "LOWER_DECK" ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true
          },
          {
            "comfortClass" : "SECOND",
            "price": "50€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW" ],
            "deckOptions": [ "ANY", "MIDDLE_DECK", "LOWER_DECK" ],
            "selected": false,
            "booked" : false
          }
        ]
      },
      {
        "number": "B",
        "bound": "outbound",
        "departureDate": "2025-10-06T15:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "80€",
            "selected": false,
            "booked" : false
          }
        ]
      },
      {
        "number": "C",
        "bound": "inbound",
        "departureDate": "2025-10-16T12:00",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "90€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW", "PANORAMIC_VIEW" ],
            "deckOptions": [ "ANY", "UPPER_DECK", "LOWER_DECK" ],
            "preferences": {
              "seat": "PANORAMIC_VIEW",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked": true
          }
        ]
      },
      {
        "number": "D",
        "bound": "inbound",
        "departureDate": "2025-10-16T14:00",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW", "PANORAMIC_VIEW" ],
            "deckOptions": [ "ANY", "UPPER_DECK", "LOWER_DECK" ],
            "selected": false,
            "booked" : false
          },
          {
            "comfortClass" : "SECOND",
            "price": "50€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW" ],
            "deckOptions": [ "ANY", "LOWER_DECK" ],
            "selected": false,
            "booked" : false

          }
        ]
      }
    ]
  }
}

Search

Booking

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW", "PANORAMIC_VIEW", "LOUNGE" ],
            "deckOptions": [ "ANY", "UPPER_DECK", "MIDDLE_DECK", "LOWER_DECK" ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true
          },
          {
            "comfortClass" : "SECOND",
            "price": "50€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW" ],
            "deckOptions": [ "ANY", "MIDDLE_DECK", "LOWER_DECK" ],
            "selected": false,
            "booked" : false
          }
        ]
      },
      {
        "number": "B",
        "bound": "outbound",
        "departureDate": "2025-10-06T15:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "80€",
            "selected": false,
            "booked" : false
          }
        ]
      },
      {
        "number": "C",
        "bound": "inbound",
        "departureDate": "2025-10-16T12:00",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "90€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW", "PANORAMIC_VIEW" ],
            "deckOptions": [ "ANY", "UPPER_DECK", "LOWER_DECK" ],
            "preferences": {
              "seat": "PANORAMIC_VIEW",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked": true
          }
        ]
      },
      {
        "number": "D",
        "bound": "inbound",
        "departureDate": "2025-10-16T14:00",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW", "PANORAMIC_VIEW" ],
            "deckOptions": [ "ANY", "UPPER_DECK", "LOWER_DECK" ],
            "selected": false,
            "booked" : false
          },
          {
            "comfortClass" : "SECOND",
            "price": "50€",
            "seatOptions": [ "ANY", "AISLE", "WINDOW" ],
            "deckOptions": [ "ANY", "LOWER_DECK" ],
            "selected": false,
            "booked" : false

          }
        ]
      }
    ]
  }
}
public record Search(UUID id, Criteria criteria, SearchType searchType, List<Ship> ships) {

    public Search {
+ 		if(!hasBookedShips()){
          assert ships.stream()
          			.noneMatch(ship -> ship.departureDate().isBefore(now()))
                : "Some ships are departing in the past";
+ 		}
    }
}

Fix booking history regression #2097

Josian merged 10 commits into

cruising:main

+ 532

- 385

public record Search(UUID id, Criteria criteria, SearchType searchType, List<Ship> ships) {

    public Search {
-		if(!hasBookedShips()){
-         assert ships.stream()
-         			.noneMatch(ship -> ship.departureDate().isBefore(now()))
-               : "Some ships are departing in the past";
 		}
    }
}

Fix "Flexible Dates" Feature #2099

Josian merged 57 commits into

cruising:main

+ 1278

- 843

The Mighty

Spaghetti Code

a.k.a Big Ball of Mud

Business Need

Search Cruises

guides

Exploration

&

Experimentation

Business Need

Search Cruises

Concepts

Relations

Behaviors

Cruise

Book

Destination

Fare

Define

select

guides

Exploration

&

Experimentation

Business Need

shapes

Domain Model

Search Cruises

Concepts

Relations

Behaviors

Cruise

Book

Destination

Fare

Define

select

must account for a new

Selecting a fare

guides

Exploration

&

Experimentation

Business Need

shapes

Domain Model

guides

Exploration

&

Experimentation

Business Need

shapes

Modeling

must account for a new

Selecting a fare

Domain Model

Iterative

guides

Exploration

&

Experimentation

Business Need

extends

must account for a new

Domain Model

Modeling

Iterative

guides

Business Need

Exploration

&

Experimentation

Sinking

Model

Domain Model

extends

must account for a new

guides

Exploration

&

Experimentation

Business Need

Domain Model

must account for a new

extends

guides

Exploration

&

Experimentation

Business Need

Obsolete

Domain Model

extends

must account for a new

$$$

guides

Exploration

&

Experimentation

Business Need

Domain Model

must account for a new

shapes

No Model (business code)
is inherently extensible !

guides

Exploration

&

Experimentation

Business Need

Domain Model

shapes

Exploration

Model

must account for a new

challenged by a new

Not a confirmation bias

guides

Exploration

&

Experimentation

Business Need

Domain Model

must account for a new

shapes

Exploration

Model

Business Need

by shaping

Domain Model

New Model

can

deprecate

Exploration

&

Experimentation

challenged by a new

Accidental Design Debt:
the invisible engine of BBOMs

One does not simply

challenge the model

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "ships": [{
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [{
            "comfortClass" : "FIRST",
            "price": "100€",
          }]
      }]
}

Search

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "ships": [{
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [{
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
          }]
      }],
    "selectionComplete" : true,
    "totalPrice" : "230€",
}

Search

Selection

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "ships": [{
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [{
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true, 
          }]
    }],
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
  }

Booking

Search

Selection

Design Debt

The accidental

Technical Debt

- Ward Cunningham

Deliberate choice to ship code that does not fully fit, reflecting a still incomplete understanding of the problem, in order to move faster

Design

Technical Debt

Deliberate choice to ship code that does not fully fit, reflecting a still incomplete understanding of the problem, in order to move faster

design a model

Design

Technical Debt

Deliberate choice to ship code that does not fully fit, reflecting a still incomplete understanding of the problem, in order to move faster

Design Debt

Accidental

Model

generates through misguided decisions

manifests as complexity in

Design Debt

undermines cohesion

increases complexity

& erodes model reliability!

introduces coupling

Bugs that appear in unexpected places?

A simple change that forces you to modify the model everywhere?

Bugs appearing in unexpected places?

 Features that take more and more time? 

Bugs appearing in unexpected places?

A simple change that forces you to modify the model everywhere?

Features taking longer to develop?

More bugs in unrelated parts of the model?

Simple change causing widespread model updates?

The Unyielding

Model Entropy

Features taking longer to develop?

More bugs in unrelated parts of the model?

Simple change causing widespread model updates?

The WTF level

of the design

a.k.a

Model Entropy

 Energy gets burned fighting accidental complexity

a.k.a the WTF level

High Entropy

less coherence, consistency & cohesion

unclear outcomes

unexpected regressions

Model Entropy

generates through accumulation

Design Debt

dissipates the structure and clarity of

Model

generates through


misguided decisions

Spaghetti
Code

dissolves the model into

Model Entropy

generates through accumulation

Design Debt

dissipates the structure and clarity of

Model

generates through


misguided decisions

Spork Effect:
unveiling the roots of model fragility and rigidity

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true

Booking

Search

manifests as

Refactoring

KISS
DRY
YAGNI

Deadline Pressure

Sunk cost Fallacies

{}

Intrinsic coupling

fosters

fosters

Refactoring

KISS
DRY
YAGNI

Booking

Search

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true

Booking

Search

Booking

Intrinsic coupling

spork  effect

{}

translates into

Accidental Design Debt

Responsibility Coupling

Intrinsic coupling

may induce

"Spork Effect"

"Spork Effect"

causes

Model Fragility

Intrinsic coupling

translates into

may induce

leads to

Model Rigidity

Model Entropy

increases

produced by

accumulation

{}

Accidental Design Debt

Responsibility Coupling

Booking

Search

Intrinsic
Coupling

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true

Booking

Search

Booking

Search

Booking

Distinct Models!

Search

Booking

Booking

Model tension as signals of accidental design debt

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true

Model Tension

The Fearsome

is the result of

Accidental
Design Debt

Intrinsic Coupling

may
induce

is a design smell that signals that we are stretching the model beyond its conceptual integrity

Model Tension

Model
Tension

conceptual integrity

Conceptual Integrity

Each business concept stays true to what it represents, without being stretched to do something else 
or overloaded with responsibilities.

Conceptual
Integrity

erodes

prevents

Conceptual Integrity

Model
Tension

is the result of

Accidental
Design Debt

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true

Model
Tension

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true
{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true

Model
Tension

Booking

Search

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "seatOptions": [ "ANY", "..." ],
            "deckOptions": [ "ANY", "..." ],
            "preferences": {
              "seat": "LOUNGE",
              "deck" : "UPPER_DECK"
            },
            "selected": true,
            "booked" : true

Booking

Search

Booking

Selection

Selection

Model
Tension

Crystallized
Model Tension

The Unstoppable

compromises

"fibrosis"

unresolved


leads to

erodes

Model
Entropy

raises

Model
Tension

Crystallized
Tension

Conceptual
Integrity

Obsolescence

Signals

unresolved


leads to

Model
Tension

Crystallized
Tension

as a signal of accidental design debt

Model Tension

The Fearsome

invisible

as a signal of accidental design debt

Model Tension

The Fearsome

Exploring (intrinsic)
model tensions heuristics

visual elements © Alberto Brandolini

Search
Bound

Select
a Fare on a Ship

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Check Selected Fares
Completion

visual elements © Alberto Brandolini

Search
Bound

Select
a Fare on a Ship

Ship + Fare Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Check Selected Fares
Completion

Fares Selection
COmpleted

Selected Fares

Fares Selection Found Incomplete

Selected Fares

visual elements © Alberto Brandolini

Search
Bound

Select
a Fare on a Ship

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Check Selected Fares
Completion

visual elements © Alberto Brandolini

Search
Bound

Select
a Fare on a Ship

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Fares Selection Found Incomplete

Check Selected Fares
Completion

Selected Fares

visual elements © Alberto Brandolini

Search
Bound

Select
a Fare on a Ship

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Check Selected Fares
Completion

Linguistic Tension

Salience Bias

Linguistic Tension

Salience Bias

A cognitive bias that predisposes people to focus on  information that are more prominent or visible

visual elements © Alberto Brandolini

Search
Bound

Select
a Fare on a Ship

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Check Selected Fares
Completion

Search
Bound

Select
a Fare on a Ship

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

Ancillaries

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Selected
Fares

Ancillaries

Concept Relationship Tension

Cognitive Binding Effect

Selected
Fares +

Ancillaries

The association of seemingly independent concepts hides a concept that contains them

Selected
Fares +

Ancillaries

Concept Relationship Tension

Cognitive Binding Effect

 

 

Selection

 

 

The association of seemingly independent concepts hides a concept that contains them

Concept Relationship Tension

Cognitive Binding Effect

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

Selection

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Price
Selection

Total Price Computation

Selection
Priced

Check
Completion

Fares Selection
COmpleted

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

Selection

Priced
Selection

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Check
Completion

Fares Selection
COmpleted

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

Price
Selection

Total Price Computation

Selection
Priced

Priced
Selection

Selection

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Check
Selection
Completion

Check
Selection
Completion

Selection
COmpleted

Selection

Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

Incomplete
Selection

complete
Selection

Price
Selection

Total Price Computation

Selection
Priced

Priced
Selection

Selection

visual elements © Alberto Brandolini

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Check
Selection
Completion

Check
Selection
Completion

Selection
COmpleted

Selection

Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

Incomplete
Selection

complete
Selection

Price
Selection

Total Price Computation

Selection
Priced

Priced
Selection

Selection

visual elements © Alberto Brandolini

Search
Bound

Select
a Fare on a Ship

Ship + Fare
Selected On Bound

Compute Total Price

Total Price Computation

Total Price Computed

Check
Completion

Fares Selection
COmpleted

Selected Fares

Selected Fares

Fares Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Incomplete
Selection

complete
Selection

Priced
Selection

visual elements © Alberto Brandolini

Check Selected Fares
Completion

Lifecycle Tension

Implicit Lifecycle

The lifecycle of a concept is derived from the states of other concepts

Lifecycle Tension

Implicit Lifecycle

Ancillary
Ship

Select
Ancillary

Ancillary
Selected

Search
Bound

Ship + Fare
Selected On Bound

Check
Selection
Completion

Check
Selection
Completion

Selection
COmpleted

Selection Found Incomplete

Ancillaries

Retrieval

List
Ancillaries

Ship

Fare

Ancillaries
Listed

Ancillaries

Select
a Fare on a Ship

Incomplete
Selection

complete
Selection

Price
Selection

Total Price Computation

Selection
Priced

Priced
Selection

Selection

visual elements © Alberto Brandolini

Selection

Select
Ancillary

Check
Selection
Completion

Selection
COmpleted

Selection Found Incomplete

Price
Selection

Selection
Priced

Select
a Fare on a Ship

Ancillary
Selected

Ship + Fare
Selected On Bound

SELECTION

visual elements © Alberto Brandolini

{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "selected": true,
            "booked" : true
{
  "search": {
    "id": "XXX",
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "fares": [
          {
            "comfortClass": "FIRST",
            "price": "100€"
          },
          {
            "comfortClass": "SECOND",
            "price": "50€"
          }
        ]
      },
      {
        "number": "B",
        "bound": "outbound",
        "fares": [
          {
            "comfortClass": "FIRST",
            "price": "80€"
          }
        ]
      },
      {
        "number": "C",
        "bound": "inbound",
        "fares": [
          {
            "comfortClass": "FIRST",
            "price": "90€"
          }
        ]
      },
      {
        "number": "D",
        "bound": "inbound",
        "fares": [
          {
            "comfortClass": "FIRST",
            "price": "100€"
          },
          {
            "comfortClass": "SECOND",
            "price": "50€"
          }
        ]
      }
    ]
  }
}
{
  "selection": {
    "id": "YYYY",
    "isComplete": true,
    "totalPrice": "190€",
    "outbound": {
      "number": "A",
      "fare": {
        "comfortClass": "FIRST",
        "price": "100€"
      }
    },
    "inbound": {
      "number": "C",
      "fare": {
        "comfortClass": "FIRST",
        "price": "90€"
      }
    }
  }
}
class Selection {
  TripType tripType;
  Map<Bound, Fare> selectedFares = new HashMap();

  void selectFare(Bound bound, Fare selectedFare) {
    selectedFares.put(bound, selectedFare);
  }

  Price totalPrice() {
    return selectedFares.values().stream()
            .reduce(Fare::add)
            .get();
  }

  boolean isSelectionComplete() {
    if (tripType == ONEWAY){
        return selectedFares.size() == 1;
    } else {
        return selectedFares.size() == 2;
    }
  }
}
public record Search(UUID id, Criteria criteria, SearchType searchType, List<Ship> ships, PaymentMean paymentMean) {

    public Search {
            assert ships.stream().noneMatch(ship -> ship.departureDate().isBefore(now())) 
				: "Some ships are departing in the past";
    }
    /*...*/
}
public record Search(UUID id, Criteria criteria, SearchType searchType, List<Ship> ships, PaymentMean paymentMean) {

    public Search {
        if (!hasBookedShips()) {
            assert ships.stream().noneMatch(ship -> ship.departureDate().isBefore(now())) 
				: "Some ships are departing in the past";
        }
    }
}

public record Search(UUID id, Criteria criteria, SearchType searchType, List<Ship> ships, PaymentMean paymentMean) {

    public Search {
        if (!hasBookedShips()) {
            assert ships.stream().noneMatch(ship -> ship.departureDate().isBefore(now())) 
				: "Some ships are departing in the past";
        }
    }

    public boolean hasBookedShips() {
        Map<Bound, Long> bookedShipsPerBound =
                ships.stream()
                        .flatMap(ship -> ship.fares().stream().filter(Fare::booked).map(_ -> ship))
                        .collect(groupingBy(Ship::bound, counting()));

        if (searchType == SearchType.ONEWAY) {
            return bookedShipsPerBound.get(OUTBOUND) == 1;
        } else { //RoundTrip
            return bookedShipsPerBound.get(OUTBOUND) == 1 && bookedShipsPerBound.get(INBOUND) == 1;
        }
    }

    public List<Ship> getBookedShips() {
        var bookedShips = ships.stream().filter(ship -> ship.fares().stream().anyMatch(Fare::booked)).toList();

        if (bookedShips.isEmpty()) {
            return Collections.emptyList();
        }

        List<Ship> cleanedShips = new ArrayList<>();
        for (var bookedShip : bookedShips) {
            Fare bookedFare = getBookedFare(bookedShip);
            Ship cleanedShip = new Ship(bookedShip.number(), bookedShip.bound(), bookedShip.departureDate(), asList(bookedFare));
            cleanedShips.add(cleanedShip);
        }
        return cleanedShips;
    }

    private Fare getBookedFare(Ship bookedShip) {
        Fare bookedFare = null;
        int i = 0;
        while(i < bookedShip.fares().size()) {
            Fare fare = bookedShip.fares().get(i);
            if(fare.booked()){
                bookedFare = fare;
            }
            i++;
        }
        return bookedFare;
    }

    public void book() {
        if(paymentMean == null) {
            throw new IllegalStateException("Payment mean is missing");
        }

        if (hasBookedShips()) {
            throw new IllegalStateException("Ships are already booked");
        }
        var selectedFaresPerBound = new ArrayList<Entry<Bound, Fare>>();
        for (Ship ship : ships) {
            for (Fare fare : ship.fares()) {
                if (fare.selected()) {
                    selectedFaresPerBound.add(entry(ship.bound(), fare));
                }
            }
        }

        if (selectedFaresPerBound.isEmpty()) {
            throw new IllegalStateException("Ships must be selected before booking");
        }

        var numberOfSelectedFarePerBound = selectedFaresPerBound.stream().collect(groupingBy(Entry::getKey, counting()));
        if (searchType == SearchType.ONEWAY) {
            assert numberOfSelectedFarePerBound.get(OUTBOUND) == 1 && numberOfSelectedFarePerBound.get(INBOUND) == 0 : "Inconsistent number of selected fares";
        } else { //RoundTrip
            assert numberOfSelectedFarePerBound.get(OUTBOUND) == 1 && numberOfSelectedFarePerBound.get(INBOUND) == 1 : "Inconsistent number of selected fares";
        }

        for (Entry<Bound, Fare> selectedFare : selectedFaresPerBound) {
            selectedFare.getValue().book();
        }
    }

    public boolean isSelectionComplete() {
        Map<Bound, Long> selectedFaresPerBound = ships.stream().flatMap(ship -> ship.fares().stream().filter(Fare::selected).map(_ -> ship)).collect(groupingBy(Ship::bound, counting()));

        var selectedOutBounds = selectedFaresPerBound.get(OUTBOUND);
        var selectedInBounds = selectedFaresPerBound.get(INBOUND);

        if (searchType == SearchType.ONEWAY) {
            //This should never happen 👇
            assert selectedOutBounds <= 1 && selectedInBounds <= 0 : "Too many fares are selected";
            return selectedOutBounds == 1;
        } else { //RoundTrip

            //This should never happen 👇
            assert selectedOutBounds <= 1 && selectedInBounds <= 1 : "Too many fares are selected";
            return selectedOutBounds == 1 && selectedInBounds == 1;
        }
    }

    public Price getTotalPrice() {
        return ships.stream().flatMap(ship -> ship.fares().stream().filter(Fare::selected).map(Fare::price)).reduce(Price::add).orElse(Price.ZERO);
    }

    public void selectFareOfShip(Bound bound, String shipNumber, ComfortClass comfortClass) {
        var fareToSelect = ships.stream().filter(ship -> ship.number().equals(shipNumber) && ship.bound() == bound).flatMap(ship -> ship.fares().stream().filter(fare -> fare.comfortClass() == comfortClass)).findFirst().orElseThrow();

        var previousSelectionOnBound = ships.stream().filter(ship -> ship.bound() == bound).flatMap(ship -> ship.fares().stream()).filter(Fare::selected).findFirst();

        previousSelectionOnBound.ifPresent(fare -> fare.setSelected(false));
        fareToSelect.setSelected(true);
    }
}
{
  "search": {
    "id": "XXXX",
    "criteria": {
      "outBoundDate": "2025-10-06T12:00",
      "inBoundDate": "2025-10-16T11:00"
    },
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "ships": [
      {
        "number": "A",
        "bound": "outbound",
        "departureDate": "2025-10-06T13:30",
        "fares": [
          {
            "comfortClass" : "FIRST",
            "price": "100€",
            "selected": true,
            "booked" : true
public record Search(UUID id, Criteria criteria, SearchType searchType, List<Ship> ships) {

    public Search {
		assert ships.stream().noneMatch(ship -> ship.departureDate().isBefore(now())) 
			: "Some ships are departing in the past";
    }

   /*...*/
}
public record Booking(UUID id, List<Ship> ships, PaymentMean paymentMean, Boolean finalized) {

	public Booking {
    	
        	assert ships.stream().noneMatch(ship -> ship.departureDate().isBefore(now())) 
				: "Some ships are departing in the past";
       
    }
}
public record Search(UUID id, Criteria criteria, SearchType searchType, List<Ship> ships) {

    public Search {
		assert ships.stream().noneMatch(ship -> ship.departureDate().isBefore(now())) 
			: "Some ships are departing in the past";
    }

   /*...*/
}
public record Booking(UUID id, List<Ship> ships, PaymentMean paymentMean, Boolean finalized) {

	public Booking {
    	if(!finalized){
        	assert ships.stream().noneMatch(ship -> ship.departureDate().isBefore(now())) 
				: "Some ships are departing in the past";
        }
    }
}

CHAPTER 2

When model sclerosis  
      turns into model

Fragmentation

CRUISING

POST-BOOKING

Text

offloads

Spaghetti
Model

New
Model

Cruising

Post-Booking

Pursued Lead

Investigation

Our respective systems form a distributed monolith

POST-BOOKING

CRUISING

Search

Exchange

Cancellation

Search

Booking

Selection

POST-BOOKING

CRUISING

Search

Exchange

Cancellation

Booking

Selection

Search

Selection

Booking

POST-BOOKING

CRUISING

Search

Exchange

Cancellation

Search

Booking

Selection

Selection

Booking

POST-BOOKING

CRUISING

Search

Exchange

Cancellation

Search

Booking

Selection

Selection

Booking

Search

Exchange

Cancellation

noDepartureInThePast()

noDepartureInThePast()

POST-BOOKING

CRUISING

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

POST-BOOKING

CRUISING

Selection

Booking

Search

Exchange

Cancellation

Architectural Tension

Business Logic Leak

Business logic, lifecycles, etc. are scattered across the code of several business domains or even services

Architectural Tension

Business Logic Leak

POST-BOOKING

CRUISING

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Booking

Exchange

Selection

Booking

Search

Exchange

Cancellation

Cancellation

Booking

Exchanged
Booking

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Cancelled
Booking

Selection

Booking

Search

Exchange

Cancellation

POST-BOOKING

CRUISING

Booking

Exchanged
Booking

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Cancelled
Booking

Completed
Booking

Selection

Booking

Search

Exchange

Cancellation

POST-BOOKING

CRUISING

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Created

Completed

Exchanged

Cancelled

Selection

Booking

Search

Exchange

Cancellation

POST-BOOKING

CRUISING

Cart

SHOPPING

Order

ORDER

Parcel

DELIVERY

Booking Lifecycle

Created

Completed

Exchanged

Cancelled

POST-BOOKING

CRUISING

Exchanged

Cancelled

POST-BOOKING

CRUISING

fix ship departing in the past

Created

Completed

Booking Lifecycle

Architectural Tension

Fragmented Lifecycle

When different business domains manage the states of the same concept, while sharing several concepts, personae and rules.

Architectural Tension

Fragmented Lifecycle

POST-BOOKING

CRUISING

MOBILE APP

Booking

Exchange

Cancellation

Determining the current status of a booking

checks if the booking exists

checks if the exchange or cancellation exists

Completed

Booking

Created

Completed

Exchanged

Cancelled

POST-BOOKING

CRUISING

checks if the exchange or cancellation exists

checks if the booking exists

BOOKING

MOBILE APP

Determining the current status of a booking

can be both

Architectural Tension

Distributed States

Knowing the state of a concept requires consolidating data coming from several business domains or even services

Architectural Tension

Distributed States

POST-BOOKING

CRUISING

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Booking

Exchange

Cancellation

Selection

Booking

Search

Exchange

Cancellation

POST-BOOKING

CRUISING

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Booking

Exchange

Cancellation

Selection

Booking

Search

Exchange

Cancellation

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Booking

Exchange

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

POST-BOOKING

CRUISING

Fragmented Model

Cancellation

POST-BOOKING

CRUISING

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Booking

Exchange

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

Extrinsic Coupling

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WTW/bRlx1MDAxML37V1xi6jXd7M7sx0xuddKiuVx1MDAwNC2SXCKHXCJcdTAwMDdGoiXCNCmQVGwh8H/vI62Iolx1MDAxY4PlQVwid2bfzs68+fh+tVgsu8MuX75ZLPOHVVZcdTAwMTbrJrtfvurXv+VNW9RcdTAwMTVENHy39b5ZXHKa267btW9ev1x1MDAxZXeYVX33tCsv87u86lro/YvvxeL78Fx1MDAwYkmx7veG61x1MDAwZvff2j/efb752316+Och/HnY2GHroPTDmLKo8nH1XHUwMDAxS55scMY6XCJOITlcdTAwMTfDSXyA2EUvyTgrXHUwMDFhyHtcdEwn8X2x7ra9irXRXHUwMDA0ZVx1MDAxN5SSXHUwMDA0SnxS2ebFZttBh1mMXHUwMDE3JatCUayMKlm1KXvT7Gml7Zr6Nn9bl3XTm/zLzc1aY1x1MDAxY63+mq1uN029r9Ynna7JqnaXNfDQqHdTlOXH7lA++TZbbffN2d2fTvl8vIO/WD/ta2tEYtyFYzfbKm/bicX1LltcdTAwMTXd4clcdTAwMTen1d7G3fv1XHUwMDEwsi+jVU12l7/vY1bty/K0XFxU67xcdTAwMGbH8mtrJ8dV6+NxP1x1MDAwMj5Gk44rj6Pxed4jO++sXHUwMDBilml088g65vBs+UNdXHJcdTAwMTQki3h7XHUwMDA0UUfD2nfgXjfg3mRlm49x6I37/YyX4yX3u3X2tMUlL15EQVx1MDAwMDcyXHUwMDBiNLy99EBZr25/csquLs5p3z/j22JcZsLwcXr/8uqn2qyG1FF0njVEq+58969cdTAwMWFNhLlcdTAwMTZcdTAwMTKI4Ig5OC/GeVx1MDAxYlx1MDAwM1x1MDAwNVx1MDAwZkhNXHUwMDFhJnguOSPqI1tkiCRcdTAwMTKeXHUwMDAzRNhcZnFUVSchsnqeXHUwMDAyijc24jRKSfDj5vDIsWFHgrSLXHUwMDAyU3Vcblx1MDAxN8WosGWnkkBcdTAwMTlJs/6zbGKMQlx1MDAxNn5KLHRxYVx1MDAxN4xPmqJLluBcdTAwMTidxVx1MDAxMzXqhcVbTkphel3vXGbH6PCIT4l49ro+qnFsI+pcdTAwMGI452DGXHUwMDE0L5mA69rQXHUwMDE3s6Czt1xyPlx1MDAxOOGg3jqxzFx1MDAxN2xJYlxiLmVcIlx1MDAwZt+iMs7BRW/Br1x1MDAxZVx1MDAwN1x1MDAwZVJYMfVdXGIos1x0skDMqCNhXHUwMDBlXHUwMDBmjjYsnPDPgtJ9yVx1MDAxNYRcdTAwMWWhwEGeXGLVIM7hwSlcdTAwMDY8XHUwMDEwgVx1MDAwMy05iVM88ib5YDXAXHUwMDFiXCKo9vNkfqkvXHUwMDFjXHI0IVx1MDAwNvbguUdrIZ1cdTAwMDVU5Fx1MDAxM3JMvEI5RZrgQYZMXHUwMDFiksO7yE5m0ZBrjqw4TfC5XHUwMDBi/lx1MDAxY81RXHUwMDFmjeA4kERcdTAwMWK9zsKl1LdJxU3gIVx1MDAwNZsncMFcdTAwMWJPyJxke7Y7muVcbim46ixcdTAwMWPu1emUyLDagFwiwatSRGhnmVx1MDAxN6xcdTAwMThGXHUwMDBiV2tcdTAwMDWpxDyBw1Wt9eCxcz5cIm/TLFx1MDAxZYtFYCNGXHUwMDA2jpwoTJhCYCVcdTAwMDIr5LVPQkn/o6pE1KHQ08BxsjyBw1GMnMZcXMJ90fGzxlx1MDAxMZNcdTAwMDFcdTAwMDHgPcRcdTAwMDFcdTAwMTOLlanvxERcdTAwMTCFXHUwMDA10VxiKMyzRVx1MDAwNamKKpCswDiUeLSPczz0XGZkWCRcdTAwMWNcdTAwMTRQV2Q+K1x1MDAxY6pcdTAwMDCqXHUwMDBmKZhcdTAwMDVr4iRcdTAwMTZ9iVx1MDAxOK1z81x1MDAxZOOl/nd1sWtZZm33tr67Kzo05r/6pnrZgNsua7prXGZcIkW1uZTl1fpcdTAwMDXJsOu3pqnvt3n2bKzBvlx1MDAxN2W7ujxshpGka/b5sPp4dTR5me12XHUwMDFmO8xcdTAwMTCnwWf5rcjvr5+Pflx1MDAxOFx1MDAwZvtneXWcg/qxL1x1MDAxZualx6vH/1x1MDAwMIt/SH0ifQ==

Cancellation

POST-BOOKING

CRUISING

Remediation

breaks logic in

Feature Change

Architectural Tension

Frequent
Breaking Changes

All model evolutions of a business domain

break the domains that collaborate with it.

Architectural Tension

Frequent
Breaking Changes

Investigation

Architectural Tensions

Business Logic Leaks

Fragmented Lifecycle

Distributed States

Frequent
Breaking Changes

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

Extrinsic Coupling

Model fragmentation (extrinsic coupling):
the insidious builder of distributed BBOMs

Text

offloads

Cruising

Post-Booking

Spaghetti
Model

New
Model

Text

works around

Cruising

Post-Booking

Spaghetti

Model

Model

Outgrowth

Cruising

Post-Booking

works around

becomes a fragment of

Fragmented
Model

is a fragment of

Spaghetti
Model

Outgrowth
Model

causes

Extrinsic
Coupling

Business Logic
Leak

Fragmented
Model

induces

Outgrowth
Model

favorises

exacerbates

is a form of

Extrinsic
Coupling

Synchronized

Evolutions

Extrinsic
Coupling

forces
the system into

Synchronized
Failures

causes

Distributed

Monolith

signal

signal

Synchronized Evolutions

Structuring Constraint

Compensations
System

Our processes and our organization are forced to compensate for the synchronized evolutions of our model that has become fragmented

Pursued Lead

Investigation

POST-BOOKING

CRUISING

Booking

Release 464

Release 52

Insurance
Policy

Insurance
Policy

POST-BOOKING

CRUISING

ignores

Release 464

Release 52

Booking

Insurance
Policy

Insurance
Policy

Cancellation

POST-BOOKING

CRUISING

ignores

Release 464

Release 52

Booking

Insurance
Policy

Insurance
Policy

Incompatible

Cancellation

POST-BOOKING

CRUISING

Insurance
Policy

Release 464

Release 53

Booking

Insurance
Policy

Insurance
Policy

Cancellation

Deploy Together

Process Tension

Synchronized Releases

Organizational Tension

Inter-Team

Work Coupling

Investigation

Synchronized

Evolutions

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

Fragmented Model

Process Tension

Synchronized
Releases

Org. Tension

Structuring
Constraint

InterTeam
Work
Coupling

POST-BOOKING

CRUISING

Release 465

Release 57

Incompatible

Meal

POST-BOOKING

CRUISING

Release 465

Release 57

Compatible

Meal

Toggle: OFF

POST-BOOKING

CRUISING

Release 465

Release 58

Compatible

Toggle: OFF

Toggle: OFF

Meal

Meal

POST-BOOKING

CRUISING

Release 465

Release 58

Toggle: ON

Toggle: ON

Meal

Meal

Compatible

Process Tension

Band-aid Processes

 Unresolved design problems are compensated by processes such as multi-versioning, double run and feature flags, in order to limit the impact on other teams

Process Tension

Band-aid Process

POST-BOOKING

CRUISING

Meal

Meal

Interface

Toggle: OFF

Toggle: OFF

R

T

E

POST-BOOKING

CRUISING

Meal

Meal

Interface

Toggle: OFF

Toggle: OFF

R

T

E

ready?

ready?

POST-BOOKING

CRUISING

Meal

Meal

Interface

Toggle: OFF

Toggle: OFF

R

T

E

ready?

ready?

POST-BOOKING

CRUISING

Meal

ready?

Meal

Interface

ready?

Toggle: OFF

Toggle: OFF

Readiness

Toggle

Engineer

Organizational Tension

Palliative Roles

When the growing complexity of band-aid processes and ceremonies requires a full-time position

Organizational Tension

Palliative Roles

Extrinsic
Coupling

leads to

Synchronized
Releases

InterTeam
Work Coupling

leads to

InterTeam
Work Coupling

Synchronized
Releases

buffered by

buffered by

handled by

Extrinsic
Coupling

leads to

leads to

Band-aid Processes

Palliative Roles

Extrinsic
Coupling

leads to

leads to

Synchronized
Releases

buffered by

buffered by

InterTeam
Work Coupling

Patch
Processes

Palliative Roles

Compensatory
Counter-Measures

Palliative Roles

handled by

Band-aid processes

Process Tension

Org. Tension

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Extrinsic
Coupling

leads to

leads to

Synchronized
Releases

Compensatory
Counter-Measures

offset

offset

buffered by

buffered by

InterTeam
Work Coupling

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Extrinsic
Coupling

leads to

leads to

never addresses

Synchronized
Releases

offset

offset

buffered by

buffered by

InterTeam
Work Coupling

Compensatory
Counter-Measures

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Extrinsic
Coupling

leads to

leads to

never addresses

Synchronized
Releases

Tension Crystallization

Tension Crystallization

offset

offset

buffered by

buffered by

InterTeam
Work Coupling

Compensatory
Counter-Measures

Compensations System

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Extrinsic
Coupling

leads to

leads to

never addresses

Synchronized
Releases

offset

offset

buffered by

buffered by

InterTeam
Work Coupling

Compensatory
Counter-Measures

Investigation

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Extrinsic
Coupling

Process Tension

Compensatory Countermeasures

Compensations
System

Org. Tension

Band-aid
Processes

Roles

Palliatives

Synced

Evolutions

Structuring
Constraint

Crystallization

Model Tensions

Socio-Technical
Entropy

Our extrinsic coupling manifests itself through organizational dysfunctions

Pursued Lead

Investigation

Booking

Exchange

POST-BOOKING

CRUISING

Cancellation

Seat Preferences

Seat Preferences

Update Booking?

Create Exchange?

Organizational Tension

Unclear

Ownership

Organizational Tension

Unclear Ownership

 When a debug or development need arises, debates often break out to determine which team should handle it

Bug

Ships departing in the past are bookable

ToDo

Bug

ToDo

Cruising BackLog

Past ships are bookable

Past ships are bookable

Post-Booking BackLog

Cruising BackLog

Bug

In Progress

Bug

ToDo

Past ships are bookable

Past ships are bookable

Organizational Tension

Backlog Takeover

When the work of one product team systematically ends up on the critical path of another team

Organizational Tension

Backlog Takeover

Investigation

Model Fragmentation

GoverningConstraint

Synced

Evolutions

Synchronized
Releases

InterTeam
Work Coupling

Crystallized Model Tensions

Compensatory
Countermeasures

Compensations
Systems

Band-Aid
Processes & ORg

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Organizational
Fragmentation

Unclear
Ownership

Org. Tension

Backlog
TakeOver

Org. Tension

Catalyst

Interpretation

Spaghetti Model

Outgrowth
Model

Spaghetti Model

works around

Outgrowth Model

Historical
Team

New Team

offloads the
 


work of 

New Team

Spaghetti Model

Outgrowth Model

works around

offloads the
 


work of 

Historical
Team

Historical
Team

New Team

Outgrowth Model

Spaghetti Model

works around

Organizational
Fragmentation

Historical
Team

New Team

Model Fragmentation

Outgrowth Model

bypasses

Spaghetti Model

Conway's Law

Organizational
Fragmentation

Conway's Law

Organizations produce systems that mirror their communication structure.

Management designs the system architecture unconsciously through organizational decisions

Manager as Shadow Designer

Organizational Tension

Historical
Team

New Team

Model Fragmentation

Outgrowth Model

bypasses

Spaghetti Model

Organizational
Fragmentation

New Team

Spaghetti Model

Outgrowth Model

works around

offloads the
 


work of 

Historical
Team

The organization will make you pay interest on your design debt !!!

Conclusion

You thought technical debt was the worst?

Here is design debt!

And your best practices won't save you...

as a signal of accidental design debt

Model Tension

The Fearsome

to prevent design debt

Model Tension Heuristics

The Heuristics

Cart

SHOPPING

Order

ORDER

Parcel

DELIVERY

...don't always indicate tensions.

This is not a fragmented lifecycle!

µOutline the Design Debt

Why?

How?

Detect frictions

across the layers of the system

Highlight

the couplings

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

noDepartureInThePast()

noScheduleOverlap()

noDepartureInThePast()

noScheduleOverlap()

Build up a body of evidence to find correlations

Assess their location, depth & scope

Identify possible causes with the heuristics

POST-BOOKING

CRUISING

Exchange

Selection

Booking

Search

Cancellation

Search

Booking

POST-BOOKING

CRUISING

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Booking

Exchange

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

Extrinsic Coupling

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WTW/bRlx1MDAxML37V1xi6jXd7M7sx0xuddKiuVx1MDAwNC2SXCKHXCJcdTAwMDdGoiXCNCmQVGwh8H/vI62Iolx1MDAxY4PlQVwid2bfzs68+fh+tVgsu8MuX75ZLPOHVVZcdTAwMTbrJrtfvurXv+VNW9RcdTAwMTVENHy39b5ZXHKa267btW9ev1x1MDAxZXeYVX33tCsv87u86lro/YvvxeL78Fx1MDAwYkmx7veG61x1MDAwZvff2j/efb752316+Och/HnY2GHroPTDmLKo8nH1XHUwMDAxS55scMY6XCJOITlcdTAwMTfDSXyA2EUvyTgrXHUwMDFhyHtcdEwn8X2x7ra9irXRXHUwMDA0ZVx1MDAxN5SSXHUwMDA0SnxS2ebFZttBh1mMXHUwMDE3JatCUayMKlm1KXvT7Gml7Zr6Nn9bl3XTm/zLzc1aY1x1MDAxY63+mq1uN029r9Ynna7JqnaXNfDQqHdTlOXH7lA++TZbbffN2d2fTvl8vIO/WD/ta2tEYtyFYzfbKm/bicX1LltcdTAwMTXd4clcdTAwMTen1d7G3fv1XHUwMDEwsi+jVU12l7/vY1bty/K0XFxU67xcdTAwMGbH8mtrJ8dV6+NxP1x1MDAwMj5Gk44rj6Pxed4jO++sXHUwMDBilml088g65vBs+UNdXHJcdTAwMTQki3h7XHUwMDA0UUfD2nfgXjfg3mRlm49x6I37/YyX4yX3u3X2tMUlL15EQVx1MDAwMDcyXHUwMDBiNLy99EBZr25/csquLs5p3z/j22JcZsLwcXr/8uqn2qyG1FF0njVEq+58969cdTAwMWFNhLlcdTAwMTZcdTAwMTKI4Ig5OC/GeVx1MDAxYlx1MDAwM1x1MDAwNVx1MDAwZkhNXHUwMDFhJnguOSPqI1tkiCRcdTAwMTKeXHUwMDAzRNhcZnFUVSchsnqeXHUwMDAyijc24jRKSfDj5vDIsWFHgrSLXHUwMDAyU3Vcblx1MDAxN8WosGWnkkBcdTAwMTlJs/6zbGKMQlx1MDAxNn5KLHRxYVx1MDAxN4xPmqJLluBcdTAwMTidxVx1MDAxMzXqhcVbTkphel3vXGbH6PCIT4l49ro+qnFsI+pcdTAwMGI452DGXHUwMDE0L5mA69rQXHUwMDE3s6Czt1xyPlx1MDAxOOGg3jqxzFx1MDAxN2xJYlxiLmVcIlx1MDAwZt+iMs7BRW/Br1x1MDAxZVx1MDAwN1x1MDAwZVJYMfVdXGIos1x0skDMqCNhXHUwMDBlXHUwMDBmjjYsnPDPgtJ9yVx1MDAxNYRcdTAwMWWhwEGeXGLVIM7hwSlcdTAwMDY8XHUwMDEwgVx1MDAwMy05iVM88ib5YDXAXHUwMDFiXCKo9vNkfqkvXHUwMDFjXHI0IVx1MDAwNvbguUdrIZ1cdTAwMDVU5Fx1MDAxM3JMvEI5RZrgQYZMXHUwMDFiksO7yE5m0ZBrjqw4TfC5XHUwMDBi/lx1MDAxY81RXHUwMDFmjeA4kERcdTAwMWK9zsKl1LdJxU3gIVx1MDAwNZsncMFcdTAwMWJPyJxke7Y7muVcbim46ixcdTAwMWPu1emUyLDagFwiwatSRGhnmVx1MDAxN6xcdTAwMThGXHUwMDBiV2tcdTAwMDWpxDyBw1Wt9eCxcz5cIm/TLFx1MDAxZYtFYCNGXHUwMDA2jpwoTJhCYCVcdTAwMDIr5LVPQkn/o6pE1KHQ08BxsjyBw1GMnMZcXMJ90fGzxlx1MDAxMZNcdTAwMDFcdTAwMDHgPcRcdTAwMDFcdTAwMTOLlanvxERcdTAwMTCFXHUwMDA10VxiKMyzRVx1MDAwNamKKpCswDiUeLSPczz0XGZkWCRcdTAwMWNcdTAwMTRQV2Q+K1x1MDAxY6pcdTAwMDCqXHUwMDBmKZhcdTAwMDVr4iRcdTAwMTZ9iVx1MDAxOK1z81x1MDAxZOOl/nd1sWtZZm33tr67Kzo05r/6pnrZgNsua7prXGZcIkW1uZTl1fpcdTAwMDXJsOu3pqnvt3n2bKzBvlx1MDAxN2W7ujxshpGka/b5sPp4dTR5me12XHUwMDFmO8xcdTAwMTCnwWf5rcjvr5+Pflx1MDAxOFx1MDAwZvtneXWcg/qxL1x1MDAxZualx6vH/1x1MDAwMIt/SH0ifQ==

Cancellation

Investigation

Model Fragmentation

Synchronized
Releases

InterTeam
Work Coupling

Synced

Evolutions

Compensatory
Countermeasures

Compensations
Systems

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nI1WwXLbNlx1MDAxML37KzTqNUWw2Fx1MDAwNbDIrU56yKXTiafTznRyoCVaYkyTXHUwMDFhkorjZvzvfaRcdTAwMTRRVO1hdbAlLPbh7e7bXHUwMDA1vl8tXHUwMDE2y+5ply/fLZb5t1VWXHUwMDE26yZ7XFy+6de/5k1b1Fx1MDAxNUxu+N3W+2Y17Nx23a599/bt6GFW9cPBKy/zh7zqWuz7XHUwMDFiv1x1MDAxN4vvw19YinXv++U6v/3rhp++fGhcdTAwMWWLrdebT9lcdTAwMWafXHUwMDA212HTXHUwMDBmMmVR5ePqNyxcdKlcdTAwMDajkb2N1obAJ+tcdTAwMTOs5JWcIbXsOJKLdLI+XHUwMDE2627b74CT8YnJJ1x1MDAxN9W7OFx1MDAwMmzzYrPtsIdZjWhyNqlcdTAwMGJqddySVZuyJ2ZPK23X1Pf5+7qsm57wT7llYlx1MDAxYTnfZqv7TVPvq/Xre+6KsrzpnspDVrPVdt+cRX044c8jf3exfvJra9Rg9MKRm22Vt+2Ebb3LVkX3dMjDabXnt/u4XHUwMDFlivV5ZNVkXHUwMDBm+ce+WtW+LE/LRbXO+0Isb5t/JsdV6+NxP0o91tFcdTAwMWRXnkfyed4jqziHMvrT+qg2ZuHL5d/qapBcdTAwMWVFXHUwMDE3nNiY4kir/Vx1MDAwMM11XHUwMDAz6l1WtvlYgZ7ar2d6XHUwMDFjQ9zv1tnBhaKoaFRmXHUwMDEyPdkhv/vL+Mt6df/CKbu6OJd7/1x1MDAxOb8txlx1MDAxMlxmP07fP795cTcn41x1MDAxMrlAwslcdTAwMDeb6Nz751x1MDAxNExcdTAwMDBdXHUwMDBiXHUwMDBiTEFkXHUwMDBlTtSQ2OCdXHUwMDE3QKaY/Fx1MDAwNI9cIlx1MDAxOU1cdTAwMTLYojc0OuU5QLJkXHUwMDFjh5RcdTAwMTKpXHUwMDBmnMZKXHUwMDFkXHUwMDAwVYxccjjNxYhcbkeaw3PEhskpXHUwMDFhLiiopilcXFCTlNE0SaOQ1TibP8smhKDOXCJPkdVdXHUwMDA0TN5cYsRcdTAwMTMoWsgopFk8TSaJsorlmJyfhitkOFx1MDAwNMJHJUbHs+FKSIbYXHUwMDA2TFx1MDAxNlEl0JjiReNcdTAwMTGu9ZpQsjRcdTAwMWKtXHUwMDE3b5R9XHUwMDEy21x1MDAwZj6+UEtU45BSdk6QW/WzxVxyYqGvXHUwMDFlXHUwMDA3XHRKYDHNnfeGbITNOzRcdTAwMGJYzuEh0YaVI/6z+kiXWkHpUVxuXHUwMDFjhFlA3oY5PCRcdTAwMDXzXHUwMDFmiUNcdTAwMDKtI1xyUzwnJoq3ySNcdTAwMWKqmPPzYn7tRjhcdTAwMTI0PnhcdTAwMTboXFyciEuzgFx0/YRcdTAwMWVTSdhcdTAwMWODm+DBhk5cdTAwMWKaQygw6SxcdTAwMWF6jZxVSlx1MDAxMTknL+do5PpqeGLvNNggaVx1MDAxNi7GXGKPhEiQoVx1MDAwNDVP4LxcdTAwMThx6Jxoe7WTm9WKS9AqWSRcXFx1MDAxMqWpkMHaQFwiXlLCuKZ55Xmrhq2mZK2ilZgncFxi1VqBjokkoG/jLFx1MDAxZatFYYODUFx1MDAwM0fnJ0pxUCVcbqtOUt+EXHUwMDFh/8dUXHSYQ76XXHUwMDAxcbQ8gcNRuNQtQSr90JFZco7xUFx0jOyhXHUwMDBlooh9mjs1XHUwMDAxQmFFNTxcdTAwMDbz7FBBq2JcbkSrIIdcdTAwMTGP6+NcdTAwMWNcdTAwMGZ3XHUwMDA2Olxml6Z6j7mi811BmFx1MDAwMpg+LkFZYFx1MDAxMya16EfEyI7mb4zX7r+rXHUwMDBir2WZtd37+uGh6HAx/95fqpdcdTAwMTdw22VNd41nSFFtLm15tX7FMnj90jT14zbP/vOogd+rtl1dPm2GJ0nX7PNh9fnqSHmZ7XY3XHUwMDFk3lx1MDAxMKdnz/JrkT9ev/Dou1x1MDAxYj7Lq+MrqH/05cNr6fnq+V/8q0SQIn0=

noDepartureInThePast()

noDepartureInThePast()

noScheduleOverlap()

noScheduleOverlap()

Organizational
Fragmentation

Unclear
Ownership

Org. Tension

Backlog
TakeOver

Org. Tension

Catalyst

GoverningConstraint

Crystallized Model Tensions

Band-Aid
Processes & ORg

SHODO

Julien Topçu

Josian Chevalier

Tech Coach

CTO / Coach

@julientopcu.com

‪@josianchevalier.bsky.social‬

You thought technical debt was the worst?

Meet design debt!

You thought technical debt was bad? Meet design debt!

By Julien Topçu

You thought technical debt was bad? Meet design debt!

In our job, technical debt is probably the most frustrating, draining and tenacious thing we have to fight against. Of course, there are best practices: refactor, aim for simplicity with KISS, avoid over-engineering with YAGNI in order to keep this debt as low as possible. And yet, we never really manage to get rid of it. Worse, it keeps piling up even when we apply those principles, as if it were inevitable. But what if those very best practices sometimes made the problem worse instead of solving it? Technical debt may be only the visible part of something deeper: accidental design debt. A far more complex problem that leads to spaghetti software and microservices that are really just a distributed monolith, and that we often create ourselves without even realizing it. In this talk, we will explore the mechanisms of design debt and its impact on our architecture, our processes, our organization, and even our business. Through concrete examples, we will see how to detect it, assess how deep it goes, and act before it becomes entrenched for good

  • 9