Vous pensiez que la dette technique était le pire ?

Voici la dette de conception !

@julientopcu.com

‪@josianchevalier.bsky.social‬

CHAPTER I

When model exploration
   Whirlpool 
      turns into
 model sinking

TODo

Current Quest

Done

Croisières chevauchantes sélectionnables

Bug

[Ancillary]
Connection Pigeon Voyager sans fil

Feature

JIRA

Bateaux du passé affichés dans la Recherche

Bug

Ajouter l'assurance annulation

Feature

TODo

Current Quest

Done

Croisières chevauchantes sélectionnables

Bug

[Ancillary]

Connection Pigeon Voyager sans fil

Feature

JIRA

Bug

Ajouter l'assurance annulation

Feature

Bateaux du passé affichés dans la Recherche

{
  "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

          }
        ]
      }
    ]
  }
}

Recherche

(Search)

Réservation

(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 regression historique de réservation #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 "Croisières des jours précédents" #2099

Josian merged 57 commits into

cruising:main

+ 1278

- 843

Le Vaillant

Code Spaghetti

a.k.a Big Ball of Mud

Besoin Métier

Recherche de Croisière

guide

Exploration

&

Expérimentation

Besoin Métier

Recherche de Croisière

Concepts

Relations

Comportements

Croisière

Réserver

Destination

Tarif

Définir

sélectionner

guide

Exploration

&

Expérimentation

Besoin Métier

façonne

Modèle Métier

Recherche de Croisière

Concepts

Relations

Comportements

Croisière

Réserver

Destination

Tarif

Définir

sélectionner

doit prendre en compte un nouveau

Sélection d'une classe tarifaire

guide

Exploration

&

Expérimentation

Besoin Métier

façonne

Modèle Métier

guide

Exploration

&

Expérimentation

Besoin Métier

façonne

Itérative

doit prendre en compte un nouveau

Sélection d'une classe tarifaire

Modèle Métier

Modélisation

guide

Exploration

&

Expérimentation

Besoin Métier

étend

doit prendre en compte un nouveau

Modèle Métier

Itérative

Modélisation

guide

Besoin Métier

Exploration

&

Expérimentation

Itératif

Sabordage

Modèle Métier

étend

doit prendre en compte un nouveau

guide

Exploration

&

Expérimentation

Besoin Métier

Modèle Métier

doit prendre en compte un nouveau

étend

guide

Exploration

&

Expérimentation

Besoin Métier

Obsolète

Modèle Métier

étend

doit prendre en compte un nouveau

$$$

guide

Exploration

&

Expérimentation

Besoin Métier

Modèle Métier

doit prendre en compte un nouveau

façonne

Aucun Modèle (code métier) n'est extensible en soi !

guide

Exploration

&

Expérimentation

Besoin Métier

Modèle Métier

façonne

de Modèles

Exploration

doit prendre en compte un nouveau

challengé par un nouveau

Pas un biais de confirmation 

de Modèles

Exploration

guide

Exploration

&

Expérimentation

Besoin Métier

Modèle Métier

doit prendre en compte un nouveau

façonne

Besoin Métier

en façonnant

Modèle Métier

Nouveau Modèle

peut

déprécier

Exploration

&

Expérimentation

challengé par un nouveau

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€",
          }]
      }]
}

Recherche

(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€",
}

Recherche

Selection

(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,
            "booked" : true, 
          }]
    }],
    "selectionComplete" : true,
    "totalPrice" : "230€",
    "paymentMean": {
      "type": "CREDIT_CARD",
      "number": "***********"
    },
    "travelInsurance" : "40€",
  }

Réservation

Recherche

Selection

(Search)

(Booking)

Dette de Conception

L'accidentelle

Dette Technique

- Ward Cunningham

Choix délibéré de livrer un code partiellement inadapté, reflet d'une compréhension encore incomplète du problème, afin d'avancer plus rapidement

de Conception

Dette Technique

Choix délibéré de livrer un code partiellement inadapté, reflet d'une compréhension encore incomplète du problème, afin d'avancer plus rapidement

de Conception

Dette Technique

concevoir un modèle

Choix délibéré de livrer un code partiellement inadapté, reflet d'une compréhension encore incomplète du problème, afin d'avancer plus rapidement

Dette de Conception

Accidentelle

Modèle

génère via des décisions inadéquates

se manifeste en complexité dans

Dette de Conception

sabote la cohésion

augmente la complexité

& érode la fiabilité des modèles !

introduit du couplage

Des bugs qui apparaissent dans
des endroits inattendus ?

Un changement simple qui oblige à modifier le modèle partout ?

Des bugs qui apparaissent dans des endroits inattendus ?

 Des fonctionnalités qui prennent 
de plus en plus de temps ? 

Des bugs qui apparaissent dans des endroits inattendus ?

Un changement simple qui oblige à modifier le modèle partout ?

Features taking longer to develop?

More bugs in unrelated parts of the model?

Simple change causing widespread model updates?

L'implacable

Entropie de Modèle

Features taking longer to develop?

More bugs in unrelated parts of the model?

Simple change causing widespread model updates?

Le niveau de Zbeul

dans le design

a.k.a

Entropie de Modèle

 L'énergie se dissipe à force de lutter contre la complexité accidentelle

a.k.a le niveau de Zbeul

Haute Entropie

moins de cohérence, consistence & de cohésion

résultats imprévisibles

régressions inattendues

Entropie de Modèle

génère par accumulation

Dette de Conception

dissipe la structure et la clarté de

Modèle

génère via des


décisions inadéquates

Code

Spaghetti

dissout le modèle en

Entropie de Modèle

génère par accumulation

Dette de Conception

dissipe la structure et la clarté de

Modèle

génère via des


décisions inadéquates

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

Pression des Deadlines

Biais des coûts irrécupérables

{}

Couplage intrinsèque

favorisent

favorisent

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

Couplage intrinsèque

effet  cuichette

{}

se traduit par

Dette de Conception

Couplage de Responsabilité

Couplage intrinsèque

peut causer

"Effet Cuichette"

"Effet Cuichette"

cause

Fragilité de Modèle

Couplage intrinsèque

se traduit par

peut causer

entraine

Rigidité de Modèle

Entropie de Modèle

augmente

produit par

accumulation

{}

Dette de Conception

Couplage de Responsabilité

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

Modèles Distincts !

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

Tension de Modèle

La Redoutable

est le résultat de

Dette de Conception
Accidentelle

Couplage Intrinsèque

provoque

est un smell de design qui signale que l'on tord le modèle au delà de son intégrité conceptuelle

Tension de Modèle

Tension

de Modèle

intégrité conceptuelle

Intégrité Conceptuelle

Chaque concept métier reste fidèle à ce qu'il représente, sans être tordu pour faire autre chose ni surchargé de responsabilités.

Intégrité
Conceptuelle

érode

évite

Intégrité Conceptuelle

Tension

de Modèle

est le résultat de

Dette de Conception
Accidentelle

{
  "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

Tension

de Modèle

{
  "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

Tension

de Modèle

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

Tension

de Modèle

Tension Cristallisée

L'inflexible

compromet

"fibrose"

non résolue


mène à

Intégrité

Conceptuelle

érode

Entropie
Modèle

augmente

Tension
de Modèle

Tension
Cristallisée

Obsolescence

Signale

non résolue


mène à

Tension
de Modèle

Tension
Cristallisée

comme signal de dette de conception accidentelle

Tension de Modèle

La Redoutable

invisible

comme signal de dette de conception accidentelle

Tension de Modèle

La Redoutable

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

Tension Linguistique

Biais de Saillance

Un biais cognitif qui prédispose à se concentrer sur les informations les plus proéminentes ou visibles.

Tension Linguistique

Biais de Saillance

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

Tension de relation de concepts

Effet de liaison cognitive

Selected
Fares +

Ancillaries

L'association de concepts apparemment indépendants masque un concept qui les contient

Selected
Fares +

Ancillaries

Tension de relation de concepts

Effet de liaison cognitive

 

 

Selection

 

 

L'association de concepts apparemment indépendants masque un concept qui les contient

Tension de relation de concepts

Effet de liaison cognitive

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

Tension de cycle de vie

Cycle de vie Implicite

Le cycle de vie d'un concept est dérivé des états d'autres concepts

Tension de cycle de vie

Cycle de vie Implicite

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

décharge

Modèle Spaghetti

Nouveau
Modèle

Cruising

Post-Booking

Piste Explorée

Investigation

Nos Systèmes respectifs forment un monolithe distribué

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

Tension d'Architecture

Fuite de Logique Métier

Les logiques métier, cycles de vie, etc. sont éparpillés entre le code de plusieurs domaines métier voire de services

Tension d'Architecture

Fuite de Logique Métier

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

Panier

SHOPPING

Commande

ORDER

Colis

DELIVERY

Cycle de vie du Booking

Created

Completed

Exchanged

Cancelled

POST-BOOKING

CRUISING

Exchanged

Cancelled

POST-BOOKING

CRUISING

correction des croisières qui partent dans le passé

Created

Completed

Cycle de vie du Booking

Tension d'Architecture

Cycle de Vie Fragmenté

Quand des domaines métiers différents gèrent les états d'un même concept, tout en partageant plusieurs concepts, personae et règles.

Tension d'Architecture

Cycle de Vie Fragmenté

POST-BOOKING

CRUISING

APPLICATION MOBILE

Booking

Exchange

Cancellation

Déterminer le statut actuel d'un booking

vérifie si le booking existe

vérifie si l'échange ou l'annulation existe

Completed

Booking

Created

Completed

Exchanged

Cancelled

POST-BOOKING

CRUISING

vérifie si l'échange ou l'annulation existe

vérifie si le booking existe

BOOKING

potentiellement les deux

APPLICATION MOBILE

Déterminer le statut actuel d'un booking

Tension d'Architecture

États Distribués

Connaitre l'état d'un concept demande de consolider de la donnée provenant de plusieurs domaines métier voire des services

Tension d'Architecture

États Distribués

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

Modèle Fragmenté

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=

Couplage Extrinsèque

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

Changement Fonctionnel

Remédiation

casse de la logique dans

Tension d'Architecture

Changements Cassants Fréquents

Toutes les évolutions de modèles d'un domaine métier

cassent les domaines qui collaborent avec lui.

Tension d'Architecture

Changements Cassants Fréquents

Investigation

Tensions d'Architecture

Fuites de Logique Métier

Cycle de Vie Fragmenté

États Distribués

Changements Cassants Fréquents

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=

Couplage Extrinsèque

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

Text

décharge

Cruising

Post-Booking

Modèle Spaghetti

Nouveau
Modèle

Text

contourne

Cruising

Post-Booking

Modèle Spaghetti

Modèle

Excroissant

Cruising

Post-Booking

contourne

devient un fragment de

Modèle
Fragmenté

est un fragment de

Modèle Spaghetti

Modèle
Excroissant

engendre

Couplage
Extrinsèque

Fuite de
Logique Métier

Modèle
Fragmenté

induit

Modèle
Excroissant

favorise

aggrave

est une forme de

Couplage
Extrinsèque

Evolutions

Synchronisées

Couplage
Extrinsèque

contraint le système à des

Échecs

Synchronisés

engendre

Monolithe

Distribué

signalent

signalent

Synced
Evolution

results in

Synced
Failures

leads to

System
Entropy

raises

binds the fragments into

Distributed
BBOM

entangles


into

crystallizes


into

Fragmented
Model
Rigidity

causes

Fragmented
Model
Fragility

Évolutions Synchronisées

Contrainte Structurante

Compensations
System

Nos process et notre organisation sont contraints de compenser les évolutions synchronisées de notre modèle qui s'est fragmenté

Piste Explorée

Investigation

POST-BOOKING

CRUISING

Booking

Release 464

Release 52

Insurance
Policy

Insurance
Policy

POST-BOOKING

CRUISING

ignore

Release 464

Release 52

Booking

Insurance
Policy

Insurance
Policy

Cancellation

POST-BOOKING

CRUISING

ignore

Release 464

Release 52

Booking

Insurance
Policy

Insurance
Policy

Incompatibles

Cancellation

POST-BOOKING

CRUISING

Insurance
Policy

Release 464

Release 53

Déploiements simultanés

Booking

Insurance
Policy

Insurance
Policy

Cancellation

Tension de Processus

Livraisons Synchronisées

Nécessité de se synchroniser fortement autour des releases et des évolutions de modèles entre les différents systèmes

Tension de Processus

Livraisons Synchronisées

Tension Organisationnelle

Équipes

Interdépendantes

Les équipes doivent constamment synchroniser leurs plannings et priorités, malgré leur périmètre d'autonomie

Organizational Tension

Inter-Team Work Coupling

Investigation

Évolutions

Synchronisées

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=

Modèle Fragmenté

Tension Process

Livraisons
Synchronisées

Tension Org.

Équipes

Interdépendantes

Constrainte
Structurante

POST-BOOKING

CRUISING

Release 465

Release 57

Incompatibles

Meal

POST-BOOKING

CRUISING

Release 465

Release 57

Compatibles

Meal

Toggle: OFF

POST-BOOKING

CRUISING

Release 465

Release 58

Compatibles

Toggle: OFF

Toggle: OFF

Meal

Meal

POST-BOOKING

CRUISING

Release 465

Release 58

Toggle: ON

Toggle: ON

Meal

Meal

Compatibles

Tension de Processus

Processus Rustine

 Les problèmes de conception non résolus sont compensés par des processus tels que le multi-versionning, le double run et les feature flags, afin de limiter l'impact sur les autres équipes

Tension de Processus

Processus Rustine

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

prêt ?

prêt ?

POST-BOOKING

CRUISING

Meal

Meal

Interface

Toggle: OFF

Toggle: OFF

R

T

E

prêt ?

prêt ?

POST-BOOKING

CRUISING

Meal

prêt ?

Meal

Interface

prêt ?

Toggle: OFF

Toggle: OFF

Readiness

Toggle

Engineer

Tension Organisationnelle

Rôles Palliatifs

Quand la complexité croissante des processus et des cérémonies rustines nécessite un poste à temps plein

Tension Organisationnelle

Rôles Palliatifs

Couplage
Extrinsèque

mène à

Livraisons
Synchronisées

Équipes
Interdépendantes

mène à

Équipes
Interdépendantes

Livraisons
Synchronisées

compensées par

compensées par

gérés par

Couplage
Extrinsèque

mène à

mène à

Processus
Rustines

Rôles Palliatifs

Couplage
Extrinsèque

mène à

mène à

Livraisons
Synchronisées

compensées par

compensées par

Équipes
Interdépendantes

Processus
Rustines

Rôles Palliatifs

Contre-Mesures
Compensatoires

Palliative Roles

handled by

Band-aid processes

Tension Process

Tension Org.

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Couplage
Extrinsèque

mène à

mène à

Livraisons
Synchronisées

compensées par

Contre-Mesures
Compensatoires

compensées par

Équipes
Interdépendantes

repousse le problème de

repousse le problème de

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Couplage
Extrinsèque

mène à

mène à

n'adresse jamais

Livraisons
Synchronisées

repousse le problème de

repousse le problème de

compensées par

Contre-Mesures
Compensatoires

compensées par

Équipes
Interdépendantes

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Couplage
Extrinsèque

mène à

mène à

n'adresse jamais

Livraisons
Synchronisées

compensées par

Contre-Mesures
Compensatoires

compensées par

Équipes
Interdépendantes

Cristallisation de Tension

Cristallisation de Tension

repousse le problème de

repousse le problème de

Système de Compensations

Shared & Distributed
DataSets

Tests Envs Proliferations

Feature Flags
Overuse

Multi
Versionning

Synced
plannings
& backlogs

Couplage
Extrinsèque

mène à

mène à

n'adresse jamais

Livraisons
Synchronisées

compensées par

Contre-Mesures
Compensatoires

compensées par

Équipes
Interdépendantes

repousse le problème de

repousse le problème de

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()

Couplage
Extrinsèque

Tension Process

Contre-Mesures
Compensatoires

Système de
Compensations

Tension Org.

Processus
Rustines

Rôles

Palliatifs

Évolutions
Synchrones

Contrainte
Structurante

Cristallisation

Tensions de Modèle

Socio-Technical
Entropy

Notre couplage extrinsèque se manifeste par des dysfonctionnements organisationnels

Piste Explorée

Investigation

Booking

Exchange

POST-BOOKING

CRUISING

Cancellation

Seat Preferences

Seat Preferences

Update Booking?

Create Exchange?

Tension Organisationnelle

Ownership Flou

Tension Organisationnelle

Ownership Flou

 Lorsqu'un besoin de debug ou de développement se présente, des débats éclatent souvent pour déterminer quelle équipe doit s'en charger

Bug

Ships departing in the past are bookable

ToDo

Bug

ToDo

Cruising BackLog

Bateaux du passé sont réservables

Post-Booking BackLog

Cruising BackLog

Bug

In Progress

Bug

ToDo

Bateaux du passé sont réservables

Bateaux du passé sont réservables

Tension Organisationnelle

Détournement

de Backlog

Quand le travail d'une équipe produit se retrouve systématiquement sur le chemin critique d'une autre équipe

Tension Organisationnelle

Détournement de Backlog

Investigation

Modèle Fragmenté

Contrainte Structurante

Évolutions Synchrones

Synchronized
Releases

InterTeam
Work Coupling

Tensions de Modèle Cristallisées

Contre-mesures
Compensatoires

Système de
 Compensations

Processus Rustines & Rôles Palliatifs

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()

Fragmentation Organisationnelle

Ownership
Flou

Tension Org.

Détournement de Backlog

Tension Org.

Catalyseur

Model
Fragmentation

Organizational
Fragmentation

Synced
Evolution

Process
overhead

Socio-technical system entropy

Results

???

Tension Business

Désalignement Fonctionnel

Tension Business

Désalignement Fonctionnel

Une fonctionnalité varie en scope, maturité ou comportement selon les parties du système, provoquant des écarts et des incohérences

Business
Impact

Socio-technical system entropy

Model
Fragmentation

Organizational
Fragmentation

Synced
Evolution

Process
overhead

Interpretation

Modèle Spaghetti

Outgrowth
Model

Modèle Spaghetti

contourne

Modèle Excroissant

Historical
Team

New Team

offloads the
 


work of 

Équipe Historique

décharge

Nouvelle Équipe

Modèle Spaghetti

Modèle Excroissant

contourne

Fragmentation

Organisationnelle

Historical
Team

New Team

Modèle Excroissant

contourne

Modèle Spaghetti

Historical
Team

New Team

Loi de    Conway

Fragmentation

Organisationnelle

Fragmentation de Modèle

Modèle Excroissant

contourne

Modèle Spaghetti

Loi de Conway

Les organisations produisent des systèmes qui reflètent leurs structures de communication

Le management conçoit l'architecture du système inconsciemment via des décisions organisationnelles

Manager as Shadow Designer

Tension Organisationnelle

Historical
Team

New Team

Fragmentation

Organisationnelle

Loi de    Conway

Fragmentation de Modèle

Modèle Excroissant

contourne

Modèle Spaghetti

Équipe Historique

décharge

Nouvelle Équipe

Modèle Spaghetti

Modèle Excroissant

contourne

L'organisation vous fera payer les intérêts de votre dette de conception !!!

Extrinsic coupling signals are mainly socio-technical

Structure eats Strategy

Jan Bosch - 2017

B.A.P.O Model

Organizational Tensions

produce

Architectural
Tensions

structure

Process
Tensions

compensate

Business

Tensions

reflects as

Les symptômes du couplage extrinsèque sont principalement socio-techniques

Conclusion

Vous pensiez que la dette technique était le pire ?

Voici la dette de conception !

Et vos bonnes pratiques ne vous sauveront pas...

comme signal de dette de conception accidentelle

Tension de Modèle

La Redoutable

pour prévenir la dette de conception

Heuristiques de Tension de Modèle

Les Heuristiques

Panier

SHOPPING

Commande

ORDER

Colis

DELIVERY

...n'indiquent pas toujours des tensions.

Ce n'est pas un cycle de vie fragmenté !

µDétourer la Dette de Conception

Pourquoi ?

Comment ?

Détecter les frictions

à travers les strates du système

Mettre en évidence

les couplages

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()

Constituer un faisceau d'indices pour trouver des corrélations

Évaluer leur localisation, profondeur & étendue

Identifier les causes possibles avec les heuristiques

Expérimentez sur le système

Une fois un faisceau d'indices constitué, agissez sur les signaux en menant des petites expériences réversibles pour tester vos hypothèses et vos solutions potentielles

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=

Couplage Extrinsèque

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

Modèle Fragmenté

Contrainte Structurante

Évolutions Synchrones

Synchronized
Releases

InterTeam
Work Coupling

Tensions de Modèle Cristallisées

Contre-mesures
Compensatoires

Système de
 Compensations

Processus Rustines & Rôles Palliatifs

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()

Fragmentation Organisationnelle

Ownership
Flou

Tension Org.

Détournement de Backlog

Tension Org.

Catalyseur

Couplage Extrinsèque

Heuristiques

détectent

Tensions de Modèle

préviennent

Entropie Organisationnelle

SHODO

Julien Topçu

Josian Chevalier

Tech Coach

CTO / Coach

@julientopcu.com

‪@josianchevalier.bsky.social‬

Vous pensiez que la dette technique était le pire ?

Voici la dette de conception !

Vous pensiez que la dette technique était le pire? Voici la dette de conception!

By Julien Topçu

Vous pensiez que la dette technique était le pire? Voici la dette de conception!

Dans nos métiers, la dette technique est sans doute la chose la plus frustrante, éprouvante et coriace contre laquelle nous devons lutter. Bien sûr, il existe des bonnes pratiques : refactoriser, viser la simplicité avec KISS, éviter de trop anticiper avec YAGNI afin de limiter cette dette au maximum. Et pourtant, on n'y vient jamais vraiment à bout. Pire encore, elle continue de s'accumuler même lorsque nous les appliquons, comme une fatalité. Et si ces mêmes bonnes pratiques ne faisaient parfois qu'empirer le problème au lieu de le résoudre? La dette technique peut n'être que la partie visible de quelque chose de plus profond : la dette de design accidentelle (dette de conception). Un problème bien plus complexe, donnant lieu à des logiciels spaghettis et à des microservices en monolithe distribué, dont nous sommes souvent à l'origine sans même nous en rendre compte. Dans cette conférence, nous explorerons les mécanismes de la dette de design et ses impacts sur notre architecture, nos processus, notre organisation, et même notre business. À travers des exemples concrets, nous verrons comment la détecter, analyser sa profondeur et agir avant qu'elle ne s'ancre durablement.

  • 224