[{"data":1,"prerenderedAt":25452},["ShallowReactive",2],{"search-api":-1,"listing-tag-architecture-page-1":3},[4,5783,7228,9885,10678,16279,18048,20921,22776],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"id":11,"date":12,"listed":13,"nocomments":7,"hidden":7,"categories":14,"tags":15,"cover":19,"readingTime":20,"body":25,"_type":5777,"_id":5778,"_source":5779,"_file":5780,"_stem":5781,"_extension":5782},"\u002Ffr\u002Farchitecture-craft\u002Fdependency-inversion-pratique","architecture-craft",false,"","Dependency Inversion Principle : 3 exemples concrets","Le DIP est le principe SOLID le plus mal compris. Pas un pattern de conception, mais une règle sur la direction des dépendances. Trois implémentations Java concrètes.",30,"2026-03-13",true,[6],[16,17,18],"solid","architecture","clean-code","covers\u002Farticles\u002Fdependency-inversion-principe.jpg",{"text":21,"minutes":22,"time":23,"words":24},"9 min read",8.44,506400,1688,{"type":26,"children":27,"toc":5768},"root",[28,36,41,46,50,57,71,76,443,452,500,503,509,553,561,566,569,575,1617,1625,2287,2300,2303,2309,4590,4623,4626,4632,5527,5545,5548,5554,5562,5580,5588,5606,5624,5627,5639,5642,5648,5663,5676,5689,5710,5747,5750,5762],{"type":29,"tag":30,"props":31,"children":32},"element","p",{},[33],{"type":34,"value":35},"text","Chez un client dans le secteur de l'assurance que j'accompagnais (20 développeurs, 8 services backend), la suite de tests prenait 18 minutes à s'exécuter. Pas parce que les tests étaient lents. Parce que chaque test unitaire démarrait une vraie base de données PostgreSQL, un vrai serveur Redis, et appelait le vrai Sendgrid.",{"type":29,"tag":30,"props":37,"children":38},{},[39],{"type":34,"value":40},"Ce n'était pas un problème de tests. C'était un problème d'architecture : les modules métier dépendaient directement des implémentations concrètes d'infrastructure.",{"type":29,"tag":30,"props":42,"children":43},{},[44],{"type":34,"value":45},"Après avoir introduit le Dependency Inversion Principle sur les 8 services les plus critiques, la suite de tests est passée à 3 minutes. La couverture de tests a augmenté de 35% à 72% en 3 mois. Pas parce que les développeurs avaient soudain envie d'écrire des tests, mais parce que les tests étaient devenus faciles à écrire.",{"type":29,"tag":47,"props":48,"children":49},"hr",{},[],{"type":29,"tag":51,"props":52,"children":54},"h2",{"id":53},"le-problème-la-dépendance-directe",[55],{"type":34,"value":56},"Le problème : la dépendance directe",{"type":29,"tag":30,"props":58,"children":59},{},[60,62,69],{"type":34,"value":61},"Robert C. Martin (Uncle Bob) a formulé le DIP en 1996 dans ses travaux sur les principes SOLID : \"Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d'abstractions.\" C'est la règle de dépendance au cœur de la ",{"type":29,"tag":63,"props":64,"children":66},"a",{"href":65},"\u002Ffr\u002Farchitecture-craft\u002Fclean-architecture-3-regles",[67],{"type":34,"value":68},"Clean Architecture",{"type":34,"value":70}," : les flèches de dépendance doivent toujours pointer vers l'intérieur, vers le domaine métier.",{"type":29,"tag":30,"props":72,"children":73},{},[74],{"type":34,"value":75},"En pratique, la quasi-totalité des codebases sans discipline architecturale viole ce principe :",{"type":29,"tag":77,"props":78,"children":82},"pre",{"code":79,"language":80,"meta":8,"className":81,"style":8},"\u002F\u002F Violation du DIP : le module de haut niveau dépend des implémentations concrètes\npublic class OrderService {\n\n    private final PostgresDatabase db = new PostgresDatabase(\"localhost\", 5432); \u002F\u002F dépendance directe\n    private final SendgridEmailClient email = new SendgridEmailClient(\"api-key\"); \u002F\u002F dépendance directe\n\n    public String createOrder(OrderData orderData) {\n        String orderId = db.save(orderData);\n        email.sendConfirmation(orderData.getEmail(), orderId);\n        return orderId;\n    }\n}\n","java","language-java shiki shiki-themes catppuccin-frappe github-dark",[83],{"type":29,"tag":84,"props":85,"children":86},"code",{"__ignoreMap":8},[87,99,126,135,209,260,268,311,358,407,425,434],{"type":29,"tag":88,"props":89,"children":92},"span",{"class":90,"line":91},"line",1,[93],{"type":29,"tag":88,"props":94,"children":96},{"style":95},"--shiki-default:#737994;--shiki-default-font-style:italic;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit",[97],{"type":34,"value":98},"\u002F\u002F Violation du DIP : le module de haut niveau dépend des implémentations concrètes\n",{"type":29,"tag":88,"props":100,"children":102},{"class":90,"line":101},2,[103,109,114,120],{"type":29,"tag":88,"props":104,"children":106},{"style":105},"--shiki-default:#CA9EE6;--shiki-dark:#F97583",[107],{"type":34,"value":108},"public",{"type":29,"tag":88,"props":110,"children":111},{"style":105},[112],{"type":34,"value":113}," class",{"type":29,"tag":88,"props":115,"children":117},{"style":116},"--shiki-default:#E5C890;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[118],{"type":34,"value":119}," OrderService",{"type":29,"tag":88,"props":121,"children":123},{"style":122},"--shiki-default:#949CBB;--shiki-dark:#E1E4E8",[124],{"type":34,"value":125}," {\n",{"type":29,"tag":88,"props":127,"children":129},{"class":90,"line":128},3,[130],{"type":29,"tag":88,"props":131,"children":132},{"emptyLinePlaceholder":13},[133],{"type":34,"value":134},"\n",{"type":29,"tag":88,"props":136,"children":138},{"class":90,"line":137},4,[139,144,149,155,161,167,172,177,182,188,193,199,204],{"type":29,"tag":88,"props":140,"children":141},{"style":105},[142],{"type":34,"value":143},"    private",{"type":29,"tag":88,"props":145,"children":146},{"style":105},[147],{"type":34,"value":148}," final",{"type":29,"tag":88,"props":150,"children":152},{"style":151},"--shiki-default:#CA9EE6;--shiki-dark:#E1E4E8",[153],{"type":34,"value":154}," PostgresDatabase",{"type":29,"tag":88,"props":156,"children":158},{"style":157},"--shiki-default:#C6D0F5;--shiki-dark:#E1E4E8",[159],{"type":34,"value":160}," db ",{"type":29,"tag":88,"props":162,"children":164},{"style":163},"--shiki-default:#81C8BE;--shiki-dark:#F97583",[165],{"type":34,"value":166},"=",{"type":29,"tag":88,"props":168,"children":169},{"style":105},[170],{"type":34,"value":171}," new",{"type":29,"tag":88,"props":173,"children":175},{"style":174},"--shiki-default:#8CAAEE;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[176],{"type":34,"value":154},{"type":29,"tag":88,"props":178,"children":179},{"style":122},[180],{"type":34,"value":181},"(",{"type":29,"tag":88,"props":183,"children":185},{"style":184},"--shiki-default:#A6D189;--shiki-dark:#9ECBFF",[186],{"type":34,"value":187},"\"localhost\"",{"type":29,"tag":88,"props":189,"children":190},{"style":122},[191],{"type":34,"value":192},",",{"type":29,"tag":88,"props":194,"children":196},{"style":195},"--shiki-default:#EF9F76;--shiki-dark:#79B8FF",[197],{"type":34,"value":198}," 5432",{"type":29,"tag":88,"props":200,"children":201},{"style":122},[202],{"type":34,"value":203},");",{"type":29,"tag":88,"props":205,"children":206},{"style":95},[207],{"type":34,"value":208}," \u002F\u002F dépendance directe\n",{"type":29,"tag":88,"props":210,"children":212},{"class":90,"line":211},5,[213,217,221,226,231,235,239,243,247,252,256],{"type":29,"tag":88,"props":214,"children":215},{"style":105},[216],{"type":34,"value":143},{"type":29,"tag":88,"props":218,"children":219},{"style":105},[220],{"type":34,"value":148},{"type":29,"tag":88,"props":222,"children":223},{"style":151},[224],{"type":34,"value":225}," SendgridEmailClient",{"type":29,"tag":88,"props":227,"children":228},{"style":157},[229],{"type":34,"value":230}," email ",{"type":29,"tag":88,"props":232,"children":233},{"style":163},[234],{"type":34,"value":166},{"type":29,"tag":88,"props":236,"children":237},{"style":105},[238],{"type":34,"value":171},{"type":29,"tag":88,"props":240,"children":241},{"style":174},[242],{"type":34,"value":225},{"type":29,"tag":88,"props":244,"children":245},{"style":122},[246],{"type":34,"value":181},{"type":29,"tag":88,"props":248,"children":249},{"style":184},[250],{"type":34,"value":251},"\"api-key\"",{"type":29,"tag":88,"props":253,"children":254},{"style":122},[255],{"type":34,"value":203},{"type":29,"tag":88,"props":257,"children":258},{"style":95},[259],{"type":34,"value":208},{"type":29,"tag":88,"props":261,"children":263},{"class":90,"line":262},6,[264],{"type":29,"tag":88,"props":265,"children":266},{"emptyLinePlaceholder":13},[267],{"type":34,"value":134},{"type":29,"tag":88,"props":269,"children":271},{"class":90,"line":270},7,[272,277,282,287,291,296,302,307],{"type":29,"tag":88,"props":273,"children":274},{"style":105},[275],{"type":34,"value":276},"    public",{"type":29,"tag":88,"props":278,"children":279},{"style":151},[280],{"type":34,"value":281}," String",{"type":29,"tag":88,"props":283,"children":284},{"style":174},[285],{"type":34,"value":286}," createOrder",{"type":29,"tag":88,"props":288,"children":289},{"style":122},[290],{"type":34,"value":181},{"type":29,"tag":88,"props":292,"children":293},{"style":151},[294],{"type":34,"value":295},"OrderData",{"type":29,"tag":88,"props":297,"children":299},{"style":298},"--shiki-default:#EA999C;--shiki-default-font-style:italic;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit",[300],{"type":34,"value":301}," orderData",{"type":29,"tag":88,"props":303,"children":304},{"style":122},[305],{"type":34,"value":306},")",{"type":29,"tag":88,"props":308,"children":309},{"style":122},[310],{"type":34,"value":125},{"type":29,"tag":88,"props":312,"children":314},{"class":90,"line":313},8,[315,320,325,329,334,339,344,348,353],{"type":29,"tag":88,"props":316,"children":317},{"style":151},[318],{"type":34,"value":319},"        String",{"type":29,"tag":88,"props":321,"children":322},{"style":157},[323],{"type":34,"value":324}," orderId ",{"type":29,"tag":88,"props":326,"children":327},{"style":163},[328],{"type":34,"value":166},{"type":29,"tag":88,"props":330,"children":331},{"style":157},[332],{"type":34,"value":333}," db",{"type":29,"tag":88,"props":335,"children":336},{"style":122},[337],{"type":34,"value":338},".",{"type":29,"tag":88,"props":340,"children":341},{"style":174},[342],{"type":34,"value":343},"save",{"type":29,"tag":88,"props":345,"children":346},{"style":122},[347],{"type":34,"value":181},{"type":29,"tag":88,"props":349,"children":350},{"style":157},[351],{"type":34,"value":352},"orderData",{"type":29,"tag":88,"props":354,"children":355},{"style":122},[356],{"type":34,"value":357},");\n",{"type":29,"tag":88,"props":359,"children":361},{"class":90,"line":360},9,[362,367,371,376,380,384,388,393,398,403],{"type":29,"tag":88,"props":363,"children":364},{"style":157},[365],{"type":34,"value":366},"        email",{"type":29,"tag":88,"props":368,"children":369},{"style":122},[370],{"type":34,"value":338},{"type":29,"tag":88,"props":372,"children":373},{"style":174},[374],{"type":34,"value":375},"sendConfirmation",{"type":29,"tag":88,"props":377,"children":378},{"style":122},[379],{"type":34,"value":181},{"type":29,"tag":88,"props":381,"children":382},{"style":157},[383],{"type":34,"value":352},{"type":29,"tag":88,"props":385,"children":386},{"style":122},[387],{"type":34,"value":338},{"type":29,"tag":88,"props":389,"children":390},{"style":174},[391],{"type":34,"value":392},"getEmail",{"type":29,"tag":88,"props":394,"children":395},{"style":122},[396],{"type":34,"value":397},"(),",{"type":29,"tag":88,"props":399,"children":400},{"style":157},[401],{"type":34,"value":402}," orderId",{"type":29,"tag":88,"props":404,"children":405},{"style":122},[406],{"type":34,"value":357},{"type":29,"tag":88,"props":408,"children":410},{"class":90,"line":409},10,[411,416,420],{"type":29,"tag":88,"props":412,"children":413},{"style":105},[414],{"type":34,"value":415},"        return",{"type":29,"tag":88,"props":417,"children":418},{"style":157},[419],{"type":34,"value":402},{"type":29,"tag":88,"props":421,"children":422},{"style":122},[423],{"type":34,"value":424},";\n",{"type":29,"tag":88,"props":426,"children":428},{"class":90,"line":427},11,[429],{"type":29,"tag":88,"props":430,"children":431},{"style":122},[432],{"type":34,"value":433},"    }\n",{"type":29,"tag":88,"props":435,"children":437},{"class":90,"line":436},12,[438],{"type":29,"tag":88,"props":439,"children":440},{"style":122},[441],{"type":34,"value":442},"}\n",{"type":29,"tag":30,"props":444,"children":445},{},[446],{"type":29,"tag":447,"props":448,"children":449},"strong",{},[450],{"type":34,"value":451},"Ce que ça coûte concrètement :",{"type":29,"tag":453,"props":454,"children":455},"ul",{},[456,470,480,490],{"type":29,"tag":457,"props":458,"children":459},"li",{},[460,462,468],{"type":34,"value":461},"Impossible de tester ",{"type":29,"tag":84,"props":463,"children":465},{"className":464},[],[466],{"type":34,"value":467},"OrderService",{"type":34,"value":469}," sans une vraie base de données PostgreSQL et un compte Sendgrid",{"type":29,"tag":457,"props":471,"children":472},{},[473,475],{"type":34,"value":474},"Changer de base de données oblige à modifier ",{"type":29,"tag":84,"props":476,"children":478},{"className":477},[],[479],{"type":34,"value":467},{"type":29,"tag":457,"props":481,"children":482},{},[483,485],{"type":34,"value":484},"Changer d'email provider oblige à modifier ",{"type":29,"tag":84,"props":486,"children":488},{"className":487},[],[489],{"type":34,"value":467},{"type":29,"tag":457,"props":491,"children":492},{},[493,498],{"type":29,"tag":84,"props":494,"children":496},{"className":495},[],[497],{"type":34,"value":467},{"type":34,"value":499}," connaît des détails d'implémentation (host, port, api_key) qui n'ont rien à voir avec la logique métier de commande",{"type":29,"tag":47,"props":501,"children":502},{},[],{"type":29,"tag":51,"props":504,"children":506},{"id":505},"le-principe-inverser-la-direction-des-dépendances",[507],{"type":34,"value":508},"Le principe : inverser la direction des dépendances",{"type":29,"tag":30,"props":510,"children":511},{},[512,514,519,521,527,529,535,537,543,545,551],{"type":34,"value":513},"La solution DIP : ",{"type":29,"tag":84,"props":515,"children":517},{"className":516},[],[518],{"type":34,"value":467},{"type":34,"value":520}," ne dépend pas de ",{"type":29,"tag":84,"props":522,"children":524},{"className":523},[],[525],{"type":34,"value":526},"PostgreSQLDatabase",{"type":34,"value":528}," ni de ",{"type":29,"tag":84,"props":530,"children":532},{"className":531},[],[533],{"type":34,"value":534},"SendgridEmailClient",{"type":34,"value":536},". Il dépend d'abstractions (",{"type":29,"tag":84,"props":538,"children":540},{"className":539},[],[541],{"type":34,"value":542},"OrderRepository",{"type":34,"value":544},", ",{"type":29,"tag":84,"props":546,"children":548},{"className":547},[],[549],{"type":34,"value":550},"EmailNotifier",{"type":34,"value":552},") que les implémentations concrètes respectent.",{"type":29,"tag":77,"props":554,"children":556},{"code":555},"Sans DIP :\nOrderService → PostgreSQLDatabase\nOrderService → SendgridEmailClient\n\nAvec DIP :\nOrderService → OrderRepository (abstraction) ← PostgreSQLOrderRepository (implémentation)\nOrderService → EmailNotifier (abstraction)   ← SendgridEmailNotifier (implémentation)\n",[557],{"type":29,"tag":84,"props":558,"children":559},{"__ignoreMap":8},[560],{"type":34,"value":555},{"type":29,"tag":30,"props":562,"children":563},{},[564],{"type":34,"value":565},"La flèche s'inverse : l'implémentation concrète dépend de l'abstraction, pas l'inverse.",{"type":29,"tag":47,"props":567,"children":568},{},[],{"type":29,"tag":51,"props":570,"children":572},{"id":571},"exemple-1-java-injection-par-constructeur",[573],{"type":34,"value":574},"Exemple 1 : Java, injection par constructeur",{"type":29,"tag":77,"props":576,"children":578},{"code":577,"language":80,"meta":8,"className":81,"style":8},"\u002F\u002F Les abstractions\npublic interface OrderRepository {\n    String save(OrderData orderData);\n}\n\npublic interface EmailNotifier {\n    void sendConfirmation(String email, String orderId);\n}\n\n\u002F\u002F Le module de haut niveau : dépend uniquement des abstractions\npublic class OrderService {\n\n    private final OrderRepository repository;\n    private final EmailNotifier notifier;\n\n    public OrderService(OrderRepository repository, EmailNotifier notifier) {\n        this.repository = repository;\n        this.notifier = notifier;\n    }\n\n    public String createOrder(OrderData orderData) {\n        String orderId = repository.save(orderData);\n        notifier.sendConfirmation(orderData.getEmail(), orderId);\n        return orderId;\n    }\n}\n\n\u002F\u002F Les implémentations concrètes\npublic class PostgresOrderRepository implements OrderRepository {\n    public String save(OrderData orderData) {\n        return jdbcTemplate.queryForObject(\"INSERT INTO orders ... RETURNING id\", String.class, orderData);\n    }\n}\n\npublic class SendgridEmailNotifier implements EmailNotifier {\n    public void sendConfirmation(String email, String orderId) {\n        client.send(email, \"order_confirmation\", Map.of(\"orderId\", orderId));\n    }\n}\n\n\u002F\u002F Composition à la racine de l'application\npublic OrderService createOrderService() {\n    OrderRepository repository = new PostgresOrderRepository(dataSource);\n    EmailNotifier notifier = new SendgridEmailNotifier(System.getenv(\"SENDGRID_KEY\"));\n    return new OrderService(repository, notifier);\n}\n",[579],{"type":29,"tag":84,"props":580,"children":581},{"__ignoreMap":8},[582,590,611,640,647,654,674,717,724,731,739,758,765,790,815,823,867,898,927,935,943,979,1019,1064,1080,1088,1096,1104,1113,1143,1178,1238,1246,1254,1262,1291,1340,1416,1424,1432,1440,1449,1475,1514,1571,1609],{"type":29,"tag":88,"props":583,"children":584},{"class":90,"line":91},[585],{"type":29,"tag":88,"props":586,"children":587},{"style":95},[588],{"type":34,"value":589},"\u002F\u002F Les abstractions\n",{"type":29,"tag":88,"props":591,"children":592},{"class":90,"line":101},[593,597,602,607],{"type":29,"tag":88,"props":594,"children":595},{"style":105},[596],{"type":34,"value":108},{"type":29,"tag":88,"props":598,"children":599},{"style":105},[600],{"type":34,"value":601}," interface",{"type":29,"tag":88,"props":603,"children":604},{"style":116},[605],{"type":34,"value":606}," OrderRepository",{"type":29,"tag":88,"props":608,"children":609},{"style":122},[610],{"type":34,"value":125},{"type":29,"tag":88,"props":612,"children":613},{"class":90,"line":128},[614,619,624,628,632,636],{"type":29,"tag":88,"props":615,"children":616},{"style":151},[617],{"type":34,"value":618},"    String",{"type":29,"tag":88,"props":620,"children":621},{"style":174},[622],{"type":34,"value":623}," save",{"type":29,"tag":88,"props":625,"children":626},{"style":122},[627],{"type":34,"value":181},{"type":29,"tag":88,"props":629,"children":630},{"style":151},[631],{"type":34,"value":295},{"type":29,"tag":88,"props":633,"children":634},{"style":298},[635],{"type":34,"value":301},{"type":29,"tag":88,"props":637,"children":638},{"style":122},[639],{"type":34,"value":357},{"type":29,"tag":88,"props":641,"children":642},{"class":90,"line":137},[643],{"type":29,"tag":88,"props":644,"children":645},{"style":122},[646],{"type":34,"value":442},{"type":29,"tag":88,"props":648,"children":649},{"class":90,"line":211},[650],{"type":29,"tag":88,"props":651,"children":652},{"emptyLinePlaceholder":13},[653],{"type":34,"value":134},{"type":29,"tag":88,"props":655,"children":656},{"class":90,"line":262},[657,661,665,670],{"type":29,"tag":88,"props":658,"children":659},{"style":105},[660],{"type":34,"value":108},{"type":29,"tag":88,"props":662,"children":663},{"style":105},[664],{"type":34,"value":601},{"type":29,"tag":88,"props":666,"children":667},{"style":116},[668],{"type":34,"value":669}," EmailNotifier",{"type":29,"tag":88,"props":671,"children":672},{"style":122},[673],{"type":34,"value":125},{"type":29,"tag":88,"props":675,"children":676},{"class":90,"line":270},[677,682,687,691,696,701,705,709,713],{"type":29,"tag":88,"props":678,"children":679},{"style":105},[680],{"type":34,"value":681},"    void",{"type":29,"tag":88,"props":683,"children":684},{"style":174},[685],{"type":34,"value":686}," sendConfirmation",{"type":29,"tag":88,"props":688,"children":689},{"style":122},[690],{"type":34,"value":181},{"type":29,"tag":88,"props":692,"children":693},{"style":151},[694],{"type":34,"value":695},"String",{"type":29,"tag":88,"props":697,"children":698},{"style":298},[699],{"type":34,"value":700}," email",{"type":29,"tag":88,"props":702,"children":703},{"style":122},[704],{"type":34,"value":192},{"type":29,"tag":88,"props":706,"children":707},{"style":151},[708],{"type":34,"value":281},{"type":29,"tag":88,"props":710,"children":711},{"style":298},[712],{"type":34,"value":402},{"type":29,"tag":88,"props":714,"children":715},{"style":122},[716],{"type":34,"value":357},{"type":29,"tag":88,"props":718,"children":719},{"class":90,"line":313},[720],{"type":29,"tag":88,"props":721,"children":722},{"style":122},[723],{"type":34,"value":442},{"type":29,"tag":88,"props":725,"children":726},{"class":90,"line":360},[727],{"type":29,"tag":88,"props":728,"children":729},{"emptyLinePlaceholder":13},[730],{"type":34,"value":134},{"type":29,"tag":88,"props":732,"children":733},{"class":90,"line":409},[734],{"type":29,"tag":88,"props":735,"children":736},{"style":95},[737],{"type":34,"value":738},"\u002F\u002F Le module de haut niveau : dépend uniquement des abstractions\n",{"type":29,"tag":88,"props":740,"children":741},{"class":90,"line":427},[742,746,750,754],{"type":29,"tag":88,"props":743,"children":744},{"style":105},[745],{"type":34,"value":108},{"type":29,"tag":88,"props":747,"children":748},{"style":105},[749],{"type":34,"value":113},{"type":29,"tag":88,"props":751,"children":752},{"style":116},[753],{"type":34,"value":119},{"type":29,"tag":88,"props":755,"children":756},{"style":122},[757],{"type":34,"value":125},{"type":29,"tag":88,"props":759,"children":760},{"class":90,"line":436},[761],{"type":29,"tag":88,"props":762,"children":763},{"emptyLinePlaceholder":13},[764],{"type":34,"value":134},{"type":29,"tag":88,"props":766,"children":768},{"class":90,"line":767},13,[769,773,777,781,786],{"type":29,"tag":88,"props":770,"children":771},{"style":105},[772],{"type":34,"value":143},{"type":29,"tag":88,"props":774,"children":775},{"style":105},[776],{"type":34,"value":148},{"type":29,"tag":88,"props":778,"children":779},{"style":151},[780],{"type":34,"value":606},{"type":29,"tag":88,"props":782,"children":783},{"style":157},[784],{"type":34,"value":785}," repository",{"type":29,"tag":88,"props":787,"children":788},{"style":122},[789],{"type":34,"value":424},{"type":29,"tag":88,"props":791,"children":793},{"class":90,"line":792},14,[794,798,802,806,811],{"type":29,"tag":88,"props":795,"children":796},{"style":105},[797],{"type":34,"value":143},{"type":29,"tag":88,"props":799,"children":800},{"style":105},[801],{"type":34,"value":148},{"type":29,"tag":88,"props":803,"children":804},{"style":151},[805],{"type":34,"value":669},{"type":29,"tag":88,"props":807,"children":808},{"style":157},[809],{"type":34,"value":810}," notifier",{"type":29,"tag":88,"props":812,"children":813},{"style":122},[814],{"type":34,"value":424},{"type":29,"tag":88,"props":816,"children":818},{"class":90,"line":817},15,[819],{"type":29,"tag":88,"props":820,"children":821},{"emptyLinePlaceholder":13},[822],{"type":34,"value":134},{"type":29,"tag":88,"props":824,"children":826},{"class":90,"line":825},16,[827,831,835,839,843,847,851,855,859,863],{"type":29,"tag":88,"props":828,"children":829},{"style":105},[830],{"type":34,"value":276},{"type":29,"tag":88,"props":832,"children":833},{"style":174},[834],{"type":34,"value":119},{"type":29,"tag":88,"props":836,"children":837},{"style":122},[838],{"type":34,"value":181},{"type":29,"tag":88,"props":840,"children":841},{"style":151},[842],{"type":34,"value":542},{"type":29,"tag":88,"props":844,"children":845},{"style":298},[846],{"type":34,"value":785},{"type":29,"tag":88,"props":848,"children":849},{"style":122},[850],{"type":34,"value":192},{"type":29,"tag":88,"props":852,"children":853},{"style":151},[854],{"type":34,"value":669},{"type":29,"tag":88,"props":856,"children":857},{"style":298},[858],{"type":34,"value":810},{"type":29,"tag":88,"props":860,"children":861},{"style":122},[862],{"type":34,"value":306},{"type":29,"tag":88,"props":864,"children":865},{"style":122},[866],{"type":34,"value":125},{"type":29,"tag":88,"props":868,"children":870},{"class":90,"line":869},17,[871,877,881,886,890,894],{"type":29,"tag":88,"props":872,"children":874},{"style":873},"--shiki-default:#E78284;--shiki-dark:#79B8FF",[875],{"type":34,"value":876},"        this",{"type":29,"tag":88,"props":878,"children":879},{"style":122},[880],{"type":34,"value":338},{"type":29,"tag":88,"props":882,"children":883},{"style":157},[884],{"type":34,"value":885},"repository ",{"type":29,"tag":88,"props":887,"children":888},{"style":163},[889],{"type":34,"value":166},{"type":29,"tag":88,"props":891,"children":892},{"style":157},[893],{"type":34,"value":785},{"type":29,"tag":88,"props":895,"children":896},{"style":122},[897],{"type":34,"value":424},{"type":29,"tag":88,"props":899,"children":901},{"class":90,"line":900},18,[902,906,910,915,919,923],{"type":29,"tag":88,"props":903,"children":904},{"style":873},[905],{"type":34,"value":876},{"type":29,"tag":88,"props":907,"children":908},{"style":122},[909],{"type":34,"value":338},{"type":29,"tag":88,"props":911,"children":912},{"style":157},[913],{"type":34,"value":914},"notifier ",{"type":29,"tag":88,"props":916,"children":917},{"style":163},[918],{"type":34,"value":166},{"type":29,"tag":88,"props":920,"children":921},{"style":157},[922],{"type":34,"value":810},{"type":29,"tag":88,"props":924,"children":925},{"style":122},[926],{"type":34,"value":424},{"type":29,"tag":88,"props":928,"children":930},{"class":90,"line":929},19,[931],{"type":29,"tag":88,"props":932,"children":933},{"style":122},[934],{"type":34,"value":433},{"type":29,"tag":88,"props":936,"children":938},{"class":90,"line":937},20,[939],{"type":29,"tag":88,"props":940,"children":941},{"emptyLinePlaceholder":13},[942],{"type":34,"value":134},{"type":29,"tag":88,"props":944,"children":946},{"class":90,"line":945},21,[947,951,955,959,963,967,971,975],{"type":29,"tag":88,"props":948,"children":949},{"style":105},[950],{"type":34,"value":276},{"type":29,"tag":88,"props":952,"children":953},{"style":151},[954],{"type":34,"value":281},{"type":29,"tag":88,"props":956,"children":957},{"style":174},[958],{"type":34,"value":286},{"type":29,"tag":88,"props":960,"children":961},{"style":122},[962],{"type":34,"value":181},{"type":29,"tag":88,"props":964,"children":965},{"style":151},[966],{"type":34,"value":295},{"type":29,"tag":88,"props":968,"children":969},{"style":298},[970],{"type":34,"value":301},{"type":29,"tag":88,"props":972,"children":973},{"style":122},[974],{"type":34,"value":306},{"type":29,"tag":88,"props":976,"children":977},{"style":122},[978],{"type":34,"value":125},{"type":29,"tag":88,"props":980,"children":982},{"class":90,"line":981},22,[983,987,991,995,999,1003,1007,1011,1015],{"type":29,"tag":88,"props":984,"children":985},{"style":151},[986],{"type":34,"value":319},{"type":29,"tag":88,"props":988,"children":989},{"style":157},[990],{"type":34,"value":324},{"type":29,"tag":88,"props":992,"children":993},{"style":163},[994],{"type":34,"value":166},{"type":29,"tag":88,"props":996,"children":997},{"style":157},[998],{"type":34,"value":785},{"type":29,"tag":88,"props":1000,"children":1001},{"style":122},[1002],{"type":34,"value":338},{"type":29,"tag":88,"props":1004,"children":1005},{"style":174},[1006],{"type":34,"value":343},{"type":29,"tag":88,"props":1008,"children":1009},{"style":122},[1010],{"type":34,"value":181},{"type":29,"tag":88,"props":1012,"children":1013},{"style":157},[1014],{"type":34,"value":352},{"type":29,"tag":88,"props":1016,"children":1017},{"style":122},[1018],{"type":34,"value":357},{"type":29,"tag":88,"props":1020,"children":1022},{"class":90,"line":1021},23,[1023,1028,1032,1036,1040,1044,1048,1052,1056,1060],{"type":29,"tag":88,"props":1024,"children":1025},{"style":157},[1026],{"type":34,"value":1027},"        notifier",{"type":29,"tag":88,"props":1029,"children":1030},{"style":122},[1031],{"type":34,"value":338},{"type":29,"tag":88,"props":1033,"children":1034},{"style":174},[1035],{"type":34,"value":375},{"type":29,"tag":88,"props":1037,"children":1038},{"style":122},[1039],{"type":34,"value":181},{"type":29,"tag":88,"props":1041,"children":1042},{"style":157},[1043],{"type":34,"value":352},{"type":29,"tag":88,"props":1045,"children":1046},{"style":122},[1047],{"type":34,"value":338},{"type":29,"tag":88,"props":1049,"children":1050},{"style":174},[1051],{"type":34,"value":392},{"type":29,"tag":88,"props":1053,"children":1054},{"style":122},[1055],{"type":34,"value":397},{"type":29,"tag":88,"props":1057,"children":1058},{"style":157},[1059],{"type":34,"value":402},{"type":29,"tag":88,"props":1061,"children":1062},{"style":122},[1063],{"type":34,"value":357},{"type":29,"tag":88,"props":1065,"children":1067},{"class":90,"line":1066},24,[1068,1072,1076],{"type":29,"tag":88,"props":1069,"children":1070},{"style":105},[1071],{"type":34,"value":415},{"type":29,"tag":88,"props":1073,"children":1074},{"style":157},[1075],{"type":34,"value":402},{"type":29,"tag":88,"props":1077,"children":1078},{"style":122},[1079],{"type":34,"value":424},{"type":29,"tag":88,"props":1081,"children":1083},{"class":90,"line":1082},25,[1084],{"type":29,"tag":88,"props":1085,"children":1086},{"style":122},[1087],{"type":34,"value":433},{"type":29,"tag":88,"props":1089,"children":1091},{"class":90,"line":1090},26,[1092],{"type":29,"tag":88,"props":1093,"children":1094},{"style":122},[1095],{"type":34,"value":442},{"type":29,"tag":88,"props":1097,"children":1099},{"class":90,"line":1098},27,[1100],{"type":29,"tag":88,"props":1101,"children":1102},{"emptyLinePlaceholder":13},[1103],{"type":34,"value":134},{"type":29,"tag":88,"props":1105,"children":1107},{"class":90,"line":1106},28,[1108],{"type":29,"tag":88,"props":1109,"children":1110},{"style":95},[1111],{"type":34,"value":1112},"\u002F\u002F Les implémentations concrètes\n",{"type":29,"tag":88,"props":1114,"children":1116},{"class":90,"line":1115},29,[1117,1121,1125,1130,1135,1139],{"type":29,"tag":88,"props":1118,"children":1119},{"style":105},[1120],{"type":34,"value":108},{"type":29,"tag":88,"props":1122,"children":1123},{"style":105},[1124],{"type":34,"value":113},{"type":29,"tag":88,"props":1126,"children":1127},{"style":116},[1128],{"type":34,"value":1129}," PostgresOrderRepository",{"type":29,"tag":88,"props":1131,"children":1132},{"style":105},[1133],{"type":34,"value":1134}," implements",{"type":29,"tag":88,"props":1136,"children":1137},{"style":116},[1138],{"type":34,"value":606},{"type":29,"tag":88,"props":1140,"children":1141},{"style":122},[1142],{"type":34,"value":125},{"type":29,"tag":88,"props":1144,"children":1145},{"class":90,"line":11},[1146,1150,1154,1158,1162,1166,1170,1174],{"type":29,"tag":88,"props":1147,"children":1148},{"style":105},[1149],{"type":34,"value":276},{"type":29,"tag":88,"props":1151,"children":1152},{"style":151},[1153],{"type":34,"value":281},{"type":29,"tag":88,"props":1155,"children":1156},{"style":174},[1157],{"type":34,"value":623},{"type":29,"tag":88,"props":1159,"children":1160},{"style":122},[1161],{"type":34,"value":181},{"type":29,"tag":88,"props":1163,"children":1164},{"style":151},[1165],{"type":34,"value":295},{"type":29,"tag":88,"props":1167,"children":1168},{"style":298},[1169],{"type":34,"value":301},{"type":29,"tag":88,"props":1171,"children":1172},{"style":122},[1173],{"type":34,"value":306},{"type":29,"tag":88,"props":1175,"children":1176},{"style":122},[1177],{"type":34,"value":125},{"type":29,"tag":88,"props":1179,"children":1181},{"class":90,"line":1180},31,[1182,1186,1191,1195,1200,1204,1209,1213,1217,1221,1226,1230,1234],{"type":29,"tag":88,"props":1183,"children":1184},{"style":105},[1185],{"type":34,"value":415},{"type":29,"tag":88,"props":1187,"children":1188},{"style":157},[1189],{"type":34,"value":1190}," jdbcTemplate",{"type":29,"tag":88,"props":1192,"children":1193},{"style":122},[1194],{"type":34,"value":338},{"type":29,"tag":88,"props":1196,"children":1197},{"style":174},[1198],{"type":34,"value":1199},"queryForObject",{"type":29,"tag":88,"props":1201,"children":1202},{"style":122},[1203],{"type":34,"value":181},{"type":29,"tag":88,"props":1205,"children":1206},{"style":184},[1207],{"type":34,"value":1208},"\"INSERT INTO orders ... RETURNING id\"",{"type":29,"tag":88,"props":1210,"children":1211},{"style":122},[1212],{"type":34,"value":192},{"type":29,"tag":88,"props":1214,"children":1215},{"style":157},[1216],{"type":34,"value":281},{"type":29,"tag":88,"props":1218,"children":1219},{"style":122},[1220],{"type":34,"value":338},{"type":29,"tag":88,"props":1222,"children":1223},{"style":157},[1224],{"type":34,"value":1225},"class",{"type":29,"tag":88,"props":1227,"children":1228},{"style":122},[1229],{"type":34,"value":192},{"type":29,"tag":88,"props":1231,"children":1232},{"style":157},[1233],{"type":34,"value":301},{"type":29,"tag":88,"props":1235,"children":1236},{"style":122},[1237],{"type":34,"value":357},{"type":29,"tag":88,"props":1239,"children":1241},{"class":90,"line":1240},32,[1242],{"type":29,"tag":88,"props":1243,"children":1244},{"style":122},[1245],{"type":34,"value":433},{"type":29,"tag":88,"props":1247,"children":1249},{"class":90,"line":1248},33,[1250],{"type":29,"tag":88,"props":1251,"children":1252},{"style":122},[1253],{"type":34,"value":442},{"type":29,"tag":88,"props":1255,"children":1257},{"class":90,"line":1256},34,[1258],{"type":29,"tag":88,"props":1259,"children":1260},{"emptyLinePlaceholder":13},[1261],{"type":34,"value":134},{"type":29,"tag":88,"props":1263,"children":1265},{"class":90,"line":1264},35,[1266,1270,1274,1279,1283,1287],{"type":29,"tag":88,"props":1267,"children":1268},{"style":105},[1269],{"type":34,"value":108},{"type":29,"tag":88,"props":1271,"children":1272},{"style":105},[1273],{"type":34,"value":113},{"type":29,"tag":88,"props":1275,"children":1276},{"style":116},[1277],{"type":34,"value":1278}," SendgridEmailNotifier",{"type":29,"tag":88,"props":1280,"children":1281},{"style":105},[1282],{"type":34,"value":1134},{"type":29,"tag":88,"props":1284,"children":1285},{"style":116},[1286],{"type":34,"value":669},{"type":29,"tag":88,"props":1288,"children":1289},{"style":122},[1290],{"type":34,"value":125},{"type":29,"tag":88,"props":1292,"children":1294},{"class":90,"line":1293},36,[1295,1299,1304,1308,1312,1316,1320,1324,1328,1332,1336],{"type":29,"tag":88,"props":1296,"children":1297},{"style":105},[1298],{"type":34,"value":276},{"type":29,"tag":88,"props":1300,"children":1301},{"style":105},[1302],{"type":34,"value":1303}," void",{"type":29,"tag":88,"props":1305,"children":1306},{"style":174},[1307],{"type":34,"value":686},{"type":29,"tag":88,"props":1309,"children":1310},{"style":122},[1311],{"type":34,"value":181},{"type":29,"tag":88,"props":1313,"children":1314},{"style":151},[1315],{"type":34,"value":695},{"type":29,"tag":88,"props":1317,"children":1318},{"style":298},[1319],{"type":34,"value":700},{"type":29,"tag":88,"props":1321,"children":1322},{"style":122},[1323],{"type":34,"value":192},{"type":29,"tag":88,"props":1325,"children":1326},{"style":151},[1327],{"type":34,"value":281},{"type":29,"tag":88,"props":1329,"children":1330},{"style":298},[1331],{"type":34,"value":402},{"type":29,"tag":88,"props":1333,"children":1334},{"style":122},[1335],{"type":34,"value":306},{"type":29,"tag":88,"props":1337,"children":1338},{"style":122},[1339],{"type":34,"value":125},{"type":29,"tag":88,"props":1341,"children":1343},{"class":90,"line":1342},37,[1344,1349,1353,1358,1362,1367,1371,1376,1380,1385,1389,1394,1398,1403,1407,1411],{"type":29,"tag":88,"props":1345,"children":1346},{"style":157},[1347],{"type":34,"value":1348},"        client",{"type":29,"tag":88,"props":1350,"children":1351},{"style":122},[1352],{"type":34,"value":338},{"type":29,"tag":88,"props":1354,"children":1355},{"style":174},[1356],{"type":34,"value":1357},"send",{"type":29,"tag":88,"props":1359,"children":1360},{"style":122},[1361],{"type":34,"value":181},{"type":29,"tag":88,"props":1363,"children":1364},{"style":157},[1365],{"type":34,"value":1366},"email",{"type":29,"tag":88,"props":1368,"children":1369},{"style":122},[1370],{"type":34,"value":192},{"type":29,"tag":88,"props":1372,"children":1373},{"style":184},[1374],{"type":34,"value":1375}," \"order_confirmation\"",{"type":29,"tag":88,"props":1377,"children":1378},{"style":122},[1379],{"type":34,"value":192},{"type":29,"tag":88,"props":1381,"children":1382},{"style":157},[1383],{"type":34,"value":1384}," Map",{"type":29,"tag":88,"props":1386,"children":1387},{"style":122},[1388],{"type":34,"value":338},{"type":29,"tag":88,"props":1390,"children":1391},{"style":174},[1392],{"type":34,"value":1393},"of",{"type":29,"tag":88,"props":1395,"children":1396},{"style":122},[1397],{"type":34,"value":181},{"type":29,"tag":88,"props":1399,"children":1400},{"style":184},[1401],{"type":34,"value":1402},"\"orderId\"",{"type":29,"tag":88,"props":1404,"children":1405},{"style":122},[1406],{"type":34,"value":192},{"type":29,"tag":88,"props":1408,"children":1409},{"style":157},[1410],{"type":34,"value":402},{"type":29,"tag":88,"props":1412,"children":1413},{"style":122},[1414],{"type":34,"value":1415},"));\n",{"type":29,"tag":88,"props":1417,"children":1419},{"class":90,"line":1418},38,[1420],{"type":29,"tag":88,"props":1421,"children":1422},{"style":122},[1423],{"type":34,"value":433},{"type":29,"tag":88,"props":1425,"children":1427},{"class":90,"line":1426},39,[1428],{"type":29,"tag":88,"props":1429,"children":1430},{"style":122},[1431],{"type":34,"value":442},{"type":29,"tag":88,"props":1433,"children":1435},{"class":90,"line":1434},40,[1436],{"type":29,"tag":88,"props":1437,"children":1438},{"emptyLinePlaceholder":13},[1439],{"type":34,"value":134},{"type":29,"tag":88,"props":1441,"children":1443},{"class":90,"line":1442},41,[1444],{"type":29,"tag":88,"props":1445,"children":1446},{"style":95},[1447],{"type":34,"value":1448},"\u002F\u002F Composition à la racine de l'application\n",{"type":29,"tag":88,"props":1450,"children":1452},{"class":90,"line":1451},42,[1453,1457,1461,1466,1471],{"type":29,"tag":88,"props":1454,"children":1455},{"style":105},[1456],{"type":34,"value":108},{"type":29,"tag":88,"props":1458,"children":1459},{"style":151},[1460],{"type":34,"value":119},{"type":29,"tag":88,"props":1462,"children":1463},{"style":174},[1464],{"type":34,"value":1465}," createOrderService",{"type":29,"tag":88,"props":1467,"children":1468},{"style":122},[1469],{"type":34,"value":1470},"()",{"type":29,"tag":88,"props":1472,"children":1473},{"style":122},[1474],{"type":34,"value":125},{"type":29,"tag":88,"props":1476,"children":1478},{"class":90,"line":1477},43,[1479,1484,1489,1493,1497,1501,1505,1510],{"type":29,"tag":88,"props":1480,"children":1481},{"style":151},[1482],{"type":34,"value":1483},"    OrderRepository",{"type":29,"tag":88,"props":1485,"children":1486},{"style":157},[1487],{"type":34,"value":1488}," repository ",{"type":29,"tag":88,"props":1490,"children":1491},{"style":163},[1492],{"type":34,"value":166},{"type":29,"tag":88,"props":1494,"children":1495},{"style":105},[1496],{"type":34,"value":171},{"type":29,"tag":88,"props":1498,"children":1499},{"style":174},[1500],{"type":34,"value":1129},{"type":29,"tag":88,"props":1502,"children":1503},{"style":122},[1504],{"type":34,"value":181},{"type":29,"tag":88,"props":1506,"children":1507},{"style":157},[1508],{"type":34,"value":1509},"dataSource",{"type":29,"tag":88,"props":1511,"children":1512},{"style":122},[1513],{"type":34,"value":357},{"type":29,"tag":88,"props":1515,"children":1517},{"class":90,"line":1516},44,[1518,1523,1528,1532,1536,1540,1544,1549,1553,1558,1562,1567],{"type":29,"tag":88,"props":1519,"children":1520},{"style":151},[1521],{"type":34,"value":1522},"    EmailNotifier",{"type":29,"tag":88,"props":1524,"children":1525},{"style":157},[1526],{"type":34,"value":1527}," notifier ",{"type":29,"tag":88,"props":1529,"children":1530},{"style":163},[1531],{"type":34,"value":166},{"type":29,"tag":88,"props":1533,"children":1534},{"style":105},[1535],{"type":34,"value":171},{"type":29,"tag":88,"props":1537,"children":1538},{"style":174},[1539],{"type":34,"value":1278},{"type":29,"tag":88,"props":1541,"children":1542},{"style":122},[1543],{"type":34,"value":181},{"type":29,"tag":88,"props":1545,"children":1546},{"style":157},[1547],{"type":34,"value":1548},"System",{"type":29,"tag":88,"props":1550,"children":1551},{"style":122},[1552],{"type":34,"value":338},{"type":29,"tag":88,"props":1554,"children":1555},{"style":174},[1556],{"type":34,"value":1557},"getenv",{"type":29,"tag":88,"props":1559,"children":1560},{"style":122},[1561],{"type":34,"value":181},{"type":29,"tag":88,"props":1563,"children":1564},{"style":184},[1565],{"type":34,"value":1566},"\"SENDGRID_KEY\"",{"type":29,"tag":88,"props":1568,"children":1569},{"style":122},[1570],{"type":34,"value":1415},{"type":29,"tag":88,"props":1572,"children":1574},{"class":90,"line":1573},45,[1575,1580,1584,1588,1592,1597,1601,1605],{"type":29,"tag":88,"props":1576,"children":1577},{"style":105},[1578],{"type":34,"value":1579},"    return",{"type":29,"tag":88,"props":1581,"children":1582},{"style":105},[1583],{"type":34,"value":171},{"type":29,"tag":88,"props":1585,"children":1586},{"style":174},[1587],{"type":34,"value":119},{"type":29,"tag":88,"props":1589,"children":1590},{"style":122},[1591],{"type":34,"value":181},{"type":29,"tag":88,"props":1593,"children":1594},{"style":157},[1595],{"type":34,"value":1596},"repository",{"type":29,"tag":88,"props":1598,"children":1599},{"style":122},[1600],{"type":34,"value":192},{"type":29,"tag":88,"props":1602,"children":1603},{"style":157},[1604],{"type":34,"value":810},{"type":29,"tag":88,"props":1606,"children":1607},{"style":122},[1608],{"type":34,"value":357},{"type":29,"tag":88,"props":1610,"children":1612},{"class":90,"line":1611},46,[1613],{"type":29,"tag":88,"props":1614,"children":1615},{"style":122},[1616],{"type":34,"value":442},{"type":29,"tag":30,"props":1618,"children":1619},{},[1620],{"type":29,"tag":447,"props":1621,"children":1622},{},[1623],{"type":34,"value":1624},"Le gain pour les tests :",{"type":29,"tag":77,"props":1626,"children":1628},{"code":1627,"language":80,"meta":8,"className":81,"style":8},"\u002F\u002F Test sans base de données ni Sendgrid : s'exécute en millisecondes\nclass InMemoryOrderRepository implements OrderRepository {\n    private final Map\u003CString, OrderData> orders = new HashMap\u003C>();\n\n    public String save(OrderData orderData) {\n        String orderId = UUID.randomUUID().toString();\n        orders.put(orderId, orderData);\n        return orderId;\n    }\n\n    public boolean contains(String orderId) {\n        return orders.containsKey(orderId);\n    }\n}\n\n@Test\nvoid createOrder_persiste_et_notifie() {\n    InMemoryOrderRepository repository = new InMemoryOrderRepository();\n    FakeEmailNotifier notifier = new FakeEmailNotifier();\n    OrderService service = new OrderService(repository, notifier);\n\n    String orderId = service.createOrder(new OrderData(\"user@example.com\", items));\n\n    assertThat(repository.contains(orderId)).isTrue();\n    assertThat(notifier.getSentConfirmations()).hasSize(1);\n}\n",[1629],{"type":29,"tag":84,"props":1630,"children":1631},{"__ignoreMap":8},[1632,1640,1664,1725,1732,1767,1811,1849,1864,1871,1878,1915,1948,1955,1962,1969,1984,2005,2033,2062,2107,2114,2178,2185,2232,2280],{"type":29,"tag":88,"props":1633,"children":1634},{"class":90,"line":91},[1635],{"type":29,"tag":88,"props":1636,"children":1637},{"style":95},[1638],{"type":34,"value":1639},"\u002F\u002F Test sans base de données ni Sendgrid : s'exécute en millisecondes\n",{"type":29,"tag":88,"props":1641,"children":1642},{"class":90,"line":101},[1643,1647,1652,1656,1660],{"type":29,"tag":88,"props":1644,"children":1645},{"style":105},[1646],{"type":34,"value":1225},{"type":29,"tag":88,"props":1648,"children":1649},{"style":116},[1650],{"type":34,"value":1651}," InMemoryOrderRepository",{"type":29,"tag":88,"props":1653,"children":1654},{"style":105},[1655],{"type":34,"value":1134},{"type":29,"tag":88,"props":1657,"children":1658},{"style":116},[1659],{"type":34,"value":606},{"type":29,"tag":88,"props":1661,"children":1662},{"style":122},[1663],{"type":34,"value":125},{"type":29,"tag":88,"props":1665,"children":1666},{"class":90,"line":128},[1667,1671,1675,1679,1684,1688,1692,1697,1702,1707,1711,1715,1720],{"type":29,"tag":88,"props":1668,"children":1669},{"style":105},[1670],{"type":34,"value":143},{"type":29,"tag":88,"props":1672,"children":1673},{"style":105},[1674],{"type":34,"value":148},{"type":29,"tag":88,"props":1676,"children":1677},{"style":151},[1678],{"type":34,"value":1384},{"type":29,"tag":88,"props":1680,"children":1681},{"style":122},[1682],{"type":34,"value":1683},"\u003C",{"type":29,"tag":88,"props":1685,"children":1686},{"style":105},[1687],{"type":34,"value":695},{"type":29,"tag":88,"props":1689,"children":1690},{"style":122},[1691],{"type":34,"value":192},{"type":29,"tag":88,"props":1693,"children":1694},{"style":105},[1695],{"type":34,"value":1696}," OrderData",{"type":29,"tag":88,"props":1698,"children":1699},{"style":122},[1700],{"type":34,"value":1701},">",{"type":29,"tag":88,"props":1703,"children":1704},{"style":157},[1705],{"type":34,"value":1706}," orders ",{"type":29,"tag":88,"props":1708,"children":1709},{"style":163},[1710],{"type":34,"value":166},{"type":29,"tag":88,"props":1712,"children":1713},{"style":105},[1714],{"type":34,"value":171},{"type":29,"tag":88,"props":1716,"children":1717},{"style":151},[1718],{"type":34,"value":1719}," HashMap",{"type":29,"tag":88,"props":1721,"children":1722},{"style":122},[1723],{"type":34,"value":1724},"\u003C>();\n",{"type":29,"tag":88,"props":1726,"children":1727},{"class":90,"line":137},[1728],{"type":29,"tag":88,"props":1729,"children":1730},{"emptyLinePlaceholder":13},[1731],{"type":34,"value":134},{"type":29,"tag":88,"props":1733,"children":1734},{"class":90,"line":211},[1735,1739,1743,1747,1751,1755,1759,1763],{"type":29,"tag":88,"props":1736,"children":1737},{"style":105},[1738],{"type":34,"value":276},{"type":29,"tag":88,"props":1740,"children":1741},{"style":151},[1742],{"type":34,"value":281},{"type":29,"tag":88,"props":1744,"children":1745},{"style":174},[1746],{"type":34,"value":623},{"type":29,"tag":88,"props":1748,"children":1749},{"style":122},[1750],{"type":34,"value":181},{"type":29,"tag":88,"props":1752,"children":1753},{"style":151},[1754],{"type":34,"value":295},{"type":29,"tag":88,"props":1756,"children":1757},{"style":298},[1758],{"type":34,"value":301},{"type":29,"tag":88,"props":1760,"children":1761},{"style":122},[1762],{"type":34,"value":306},{"type":29,"tag":88,"props":1764,"children":1765},{"style":122},[1766],{"type":34,"value":125},{"type":29,"tag":88,"props":1768,"children":1769},{"class":90,"line":262},[1770,1774,1778,1782,1787,1791,1796,1801,1806],{"type":29,"tag":88,"props":1771,"children":1772},{"style":151},[1773],{"type":34,"value":319},{"type":29,"tag":88,"props":1775,"children":1776},{"style":157},[1777],{"type":34,"value":324},{"type":29,"tag":88,"props":1779,"children":1780},{"style":163},[1781],{"type":34,"value":166},{"type":29,"tag":88,"props":1783,"children":1784},{"style":157},[1785],{"type":34,"value":1786}," UUID",{"type":29,"tag":88,"props":1788,"children":1789},{"style":122},[1790],{"type":34,"value":338},{"type":29,"tag":88,"props":1792,"children":1793},{"style":174},[1794],{"type":34,"value":1795},"randomUUID",{"type":29,"tag":88,"props":1797,"children":1798},{"style":122},[1799],{"type":34,"value":1800},"().",{"type":29,"tag":88,"props":1802,"children":1803},{"style":174},[1804],{"type":34,"value":1805},"toString",{"type":29,"tag":88,"props":1807,"children":1808},{"style":122},[1809],{"type":34,"value":1810},"();\n",{"type":29,"tag":88,"props":1812,"children":1813},{"class":90,"line":270},[1814,1819,1823,1828,1832,1837,1841,1845],{"type":29,"tag":88,"props":1815,"children":1816},{"style":157},[1817],{"type":34,"value":1818},"        orders",{"type":29,"tag":88,"props":1820,"children":1821},{"style":122},[1822],{"type":34,"value":338},{"type":29,"tag":88,"props":1824,"children":1825},{"style":174},[1826],{"type":34,"value":1827},"put",{"type":29,"tag":88,"props":1829,"children":1830},{"style":122},[1831],{"type":34,"value":181},{"type":29,"tag":88,"props":1833,"children":1834},{"style":157},[1835],{"type":34,"value":1836},"orderId",{"type":29,"tag":88,"props":1838,"children":1839},{"style":122},[1840],{"type":34,"value":192},{"type":29,"tag":88,"props":1842,"children":1843},{"style":157},[1844],{"type":34,"value":301},{"type":29,"tag":88,"props":1846,"children":1847},{"style":122},[1848],{"type":34,"value":357},{"type":29,"tag":88,"props":1850,"children":1851},{"class":90,"line":313},[1852,1856,1860],{"type":29,"tag":88,"props":1853,"children":1854},{"style":105},[1855],{"type":34,"value":415},{"type":29,"tag":88,"props":1857,"children":1858},{"style":157},[1859],{"type":34,"value":402},{"type":29,"tag":88,"props":1861,"children":1862},{"style":122},[1863],{"type":34,"value":424},{"type":29,"tag":88,"props":1865,"children":1866},{"class":90,"line":360},[1867],{"type":29,"tag":88,"props":1868,"children":1869},{"style":122},[1870],{"type":34,"value":433},{"type":29,"tag":88,"props":1872,"children":1873},{"class":90,"line":409},[1874],{"type":29,"tag":88,"props":1875,"children":1876},{"emptyLinePlaceholder":13},[1877],{"type":34,"value":134},{"type":29,"tag":88,"props":1879,"children":1880},{"class":90,"line":427},[1881,1885,1890,1895,1899,1903,1907,1911],{"type":29,"tag":88,"props":1882,"children":1883},{"style":105},[1884],{"type":34,"value":276},{"type":29,"tag":88,"props":1886,"children":1887},{"style":105},[1888],{"type":34,"value":1889}," boolean",{"type":29,"tag":88,"props":1891,"children":1892},{"style":174},[1893],{"type":34,"value":1894}," contains",{"type":29,"tag":88,"props":1896,"children":1897},{"style":122},[1898],{"type":34,"value":181},{"type":29,"tag":88,"props":1900,"children":1901},{"style":151},[1902],{"type":34,"value":695},{"type":29,"tag":88,"props":1904,"children":1905},{"style":298},[1906],{"type":34,"value":402},{"type":29,"tag":88,"props":1908,"children":1909},{"style":122},[1910],{"type":34,"value":306},{"type":29,"tag":88,"props":1912,"children":1913},{"style":122},[1914],{"type":34,"value":125},{"type":29,"tag":88,"props":1916,"children":1917},{"class":90,"line":436},[1918,1922,1927,1931,1936,1940,1944],{"type":29,"tag":88,"props":1919,"children":1920},{"style":105},[1921],{"type":34,"value":415},{"type":29,"tag":88,"props":1923,"children":1924},{"style":157},[1925],{"type":34,"value":1926}," orders",{"type":29,"tag":88,"props":1928,"children":1929},{"style":122},[1930],{"type":34,"value":338},{"type":29,"tag":88,"props":1932,"children":1933},{"style":174},[1934],{"type":34,"value":1935},"containsKey",{"type":29,"tag":88,"props":1937,"children":1938},{"style":122},[1939],{"type":34,"value":181},{"type":29,"tag":88,"props":1941,"children":1942},{"style":157},[1943],{"type":34,"value":1836},{"type":29,"tag":88,"props":1945,"children":1946},{"style":122},[1947],{"type":34,"value":357},{"type":29,"tag":88,"props":1949,"children":1950},{"class":90,"line":767},[1951],{"type":29,"tag":88,"props":1952,"children":1953},{"style":122},[1954],{"type":34,"value":433},{"type":29,"tag":88,"props":1956,"children":1957},{"class":90,"line":792},[1958],{"type":29,"tag":88,"props":1959,"children":1960},{"style":122},[1961],{"type":34,"value":442},{"type":29,"tag":88,"props":1963,"children":1964},{"class":90,"line":817},[1965],{"type":29,"tag":88,"props":1966,"children":1967},{"emptyLinePlaceholder":13},[1968],{"type":34,"value":134},{"type":29,"tag":88,"props":1970,"children":1971},{"class":90,"line":825},[1972,1978],{"type":29,"tag":88,"props":1973,"children":1975},{"style":1974},"--shiki-default:#EF9F76;--shiki-dark:#E1E4E8",[1976],{"type":34,"value":1977},"@",{"type":29,"tag":88,"props":1979,"children":1981},{"style":1980},"--shiki-default:#EF9F76;--shiki-dark:#F97583",[1982],{"type":34,"value":1983},"Test\n",{"type":29,"tag":88,"props":1985,"children":1986},{"class":90,"line":869},[1987,1992,1997,2001],{"type":29,"tag":88,"props":1988,"children":1989},{"style":105},[1990],{"type":34,"value":1991},"void",{"type":29,"tag":88,"props":1993,"children":1994},{"style":174},[1995],{"type":34,"value":1996}," createOrder_persiste_et_notifie",{"type":29,"tag":88,"props":1998,"children":1999},{"style":122},[2000],{"type":34,"value":1470},{"type":29,"tag":88,"props":2002,"children":2003},{"style":122},[2004],{"type":34,"value":125},{"type":29,"tag":88,"props":2006,"children":2007},{"class":90,"line":900},[2008,2013,2017,2021,2025,2029],{"type":29,"tag":88,"props":2009,"children":2010},{"style":151},[2011],{"type":34,"value":2012},"    InMemoryOrderRepository",{"type":29,"tag":88,"props":2014,"children":2015},{"style":157},[2016],{"type":34,"value":1488},{"type":29,"tag":88,"props":2018,"children":2019},{"style":163},[2020],{"type":34,"value":166},{"type":29,"tag":88,"props":2022,"children":2023},{"style":105},[2024],{"type":34,"value":171},{"type":29,"tag":88,"props":2026,"children":2027},{"style":174},[2028],{"type":34,"value":1651},{"type":29,"tag":88,"props":2030,"children":2031},{"style":122},[2032],{"type":34,"value":1810},{"type":29,"tag":88,"props":2034,"children":2035},{"class":90,"line":929},[2036,2041,2045,2049,2053,2058],{"type":29,"tag":88,"props":2037,"children":2038},{"style":151},[2039],{"type":34,"value":2040},"    FakeEmailNotifier",{"type":29,"tag":88,"props":2042,"children":2043},{"style":157},[2044],{"type":34,"value":1527},{"type":29,"tag":88,"props":2046,"children":2047},{"style":163},[2048],{"type":34,"value":166},{"type":29,"tag":88,"props":2050,"children":2051},{"style":105},[2052],{"type":34,"value":171},{"type":29,"tag":88,"props":2054,"children":2055},{"style":174},[2056],{"type":34,"value":2057}," FakeEmailNotifier",{"type":29,"tag":88,"props":2059,"children":2060},{"style":122},[2061],{"type":34,"value":1810},{"type":29,"tag":88,"props":2063,"children":2064},{"class":90,"line":937},[2065,2070,2075,2079,2083,2087,2091,2095,2099,2103],{"type":29,"tag":88,"props":2066,"children":2067},{"style":151},[2068],{"type":34,"value":2069},"    OrderService",{"type":29,"tag":88,"props":2071,"children":2072},{"style":157},[2073],{"type":34,"value":2074}," service ",{"type":29,"tag":88,"props":2076,"children":2077},{"style":163},[2078],{"type":34,"value":166},{"type":29,"tag":88,"props":2080,"children":2081},{"style":105},[2082],{"type":34,"value":171},{"type":29,"tag":88,"props":2084,"children":2085},{"style":174},[2086],{"type":34,"value":119},{"type":29,"tag":88,"props":2088,"children":2089},{"style":122},[2090],{"type":34,"value":181},{"type":29,"tag":88,"props":2092,"children":2093},{"style":157},[2094],{"type":34,"value":1596},{"type":29,"tag":88,"props":2096,"children":2097},{"style":122},[2098],{"type":34,"value":192},{"type":29,"tag":88,"props":2100,"children":2101},{"style":157},[2102],{"type":34,"value":810},{"type":29,"tag":88,"props":2104,"children":2105},{"style":122},[2106],{"type":34,"value":357},{"type":29,"tag":88,"props":2108,"children":2109},{"class":90,"line":945},[2110],{"type":29,"tag":88,"props":2111,"children":2112},{"emptyLinePlaceholder":13},[2113],{"type":34,"value":134},{"type":29,"tag":88,"props":2115,"children":2116},{"class":90,"line":981},[2117,2121,2125,2129,2134,2138,2143,2147,2152,2156,2160,2165,2169,2174],{"type":29,"tag":88,"props":2118,"children":2119},{"style":151},[2120],{"type":34,"value":618},{"type":29,"tag":88,"props":2122,"children":2123},{"style":157},[2124],{"type":34,"value":324},{"type":29,"tag":88,"props":2126,"children":2127},{"style":163},[2128],{"type":34,"value":166},{"type":29,"tag":88,"props":2130,"children":2131},{"style":157},[2132],{"type":34,"value":2133}," service",{"type":29,"tag":88,"props":2135,"children":2136},{"style":122},[2137],{"type":34,"value":338},{"type":29,"tag":88,"props":2139,"children":2140},{"style":174},[2141],{"type":34,"value":2142},"createOrder",{"type":29,"tag":88,"props":2144,"children":2145},{"style":122},[2146],{"type":34,"value":181},{"type":29,"tag":88,"props":2148,"children":2149},{"style":105},[2150],{"type":34,"value":2151},"new",{"type":29,"tag":88,"props":2153,"children":2154},{"style":174},[2155],{"type":34,"value":1696},{"type":29,"tag":88,"props":2157,"children":2158},{"style":122},[2159],{"type":34,"value":181},{"type":29,"tag":88,"props":2161,"children":2162},{"style":184},[2163],{"type":34,"value":2164},"\"user@example.com\"",{"type":29,"tag":88,"props":2166,"children":2167},{"style":122},[2168],{"type":34,"value":192},{"type":29,"tag":88,"props":2170,"children":2171},{"style":157},[2172],{"type":34,"value":2173}," items",{"type":29,"tag":88,"props":2175,"children":2176},{"style":122},[2177],{"type":34,"value":1415},{"type":29,"tag":88,"props":2179,"children":2180},{"class":90,"line":1021},[2181],{"type":29,"tag":88,"props":2182,"children":2183},{"emptyLinePlaceholder":13},[2184],{"type":34,"value":134},{"type":29,"tag":88,"props":2186,"children":2187},{"class":90,"line":1066},[2188,2193,2197,2201,2205,2210,2214,2218,2223,2228],{"type":29,"tag":88,"props":2189,"children":2190},{"style":174},[2191],{"type":34,"value":2192},"    assertThat",{"type":29,"tag":88,"props":2194,"children":2195},{"style":122},[2196],{"type":34,"value":181},{"type":29,"tag":88,"props":2198,"children":2199},{"style":157},[2200],{"type":34,"value":1596},{"type":29,"tag":88,"props":2202,"children":2203},{"style":122},[2204],{"type":34,"value":338},{"type":29,"tag":88,"props":2206,"children":2207},{"style":174},[2208],{"type":34,"value":2209},"contains",{"type":29,"tag":88,"props":2211,"children":2212},{"style":122},[2213],{"type":34,"value":181},{"type":29,"tag":88,"props":2215,"children":2216},{"style":157},[2217],{"type":34,"value":1836},{"type":29,"tag":88,"props":2219,"children":2220},{"style":122},[2221],{"type":34,"value":2222},")).",{"type":29,"tag":88,"props":2224,"children":2225},{"style":174},[2226],{"type":34,"value":2227},"isTrue",{"type":29,"tag":88,"props":2229,"children":2230},{"style":122},[2231],{"type":34,"value":1810},{"type":29,"tag":88,"props":2233,"children":2234},{"class":90,"line":1082},[2235,2239,2243,2248,2252,2257,2262,2267,2271,2276],{"type":29,"tag":88,"props":2236,"children":2237},{"style":174},[2238],{"type":34,"value":2192},{"type":29,"tag":88,"props":2240,"children":2241},{"style":122},[2242],{"type":34,"value":181},{"type":29,"tag":88,"props":2244,"children":2245},{"style":157},[2246],{"type":34,"value":2247},"notifier",{"type":29,"tag":88,"props":2249,"children":2250},{"style":122},[2251],{"type":34,"value":338},{"type":29,"tag":88,"props":2253,"children":2254},{"style":174},[2255],{"type":34,"value":2256},"getSentConfirmations",{"type":29,"tag":88,"props":2258,"children":2259},{"style":122},[2260],{"type":34,"value":2261},"()).",{"type":29,"tag":88,"props":2263,"children":2264},{"style":174},[2265],{"type":34,"value":2266},"hasSize",{"type":29,"tag":88,"props":2268,"children":2269},{"style":122},[2270],{"type":34,"value":181},{"type":29,"tag":88,"props":2272,"children":2273},{"style":195},[2274],{"type":34,"value":2275},"1",{"type":29,"tag":88,"props":2277,"children":2278},{"style":122},[2279],{"type":34,"value":357},{"type":29,"tag":88,"props":2281,"children":2282},{"class":90,"line":1090},[2283],{"type":29,"tag":88,"props":2284,"children":2285},{"style":122},[2286],{"type":34,"value":442},{"type":29,"tag":2288,"props":2289,"children":2294},"cta",{"cta":2290,"href":2291,"title":2292,"type":2293},"Coder comme un senior →","https:\u002F\u002Fapp.kamanga.fr\u002Fforms\u002Fmentoring","Vous voulez savoir où placer l'abstraction et où vous arrêter ?","call",[2295],{"type":29,"tag":30,"props":2296,"children":2297},{},[2298],{"type":34,"value":2299},"Inverser une dépendance au bon endroit (et résister à l'envie d'abstraire le reste) ne s'apprend pas en lisant un exemple, ça se travaille sur votre propre code. En mentoring 1:1, je relis vos services avec vous, on extrait les ports ensemble et vous repartez avec le réflexe de sentir quand une dépendance mérite une interface. C'est du 1:1 pour monter en niveau, pas un audit d'équipe.",{"type":29,"tag":47,"props":2301,"children":2302},{},[],{"type":29,"tag":51,"props":2304,"children":2306},{"id":2305},"exemple-2-java-ports-hexagonaux-et-fakes-en-mémoire",[2307],{"type":34,"value":2308},"Exemple 2 : Java, ports hexagonaux et fakes en mémoire",{"type":29,"tag":77,"props":2310,"children":2312},{"code":2311,"language":80,"meta":8,"className":81,"style":8},"\u002F\u002F Les ports (abstractions hexagonales)\npublic interface OrderRepository {\n    String save(OrderData orderData);\n    Optional\u003COrder> findById(String orderId);\n}\n\npublic interface PaymentGateway {\n    PaymentResult charge(BigDecimal amount, String currency, String paymentMethodId);\n}\n\n\u002F\u002F Le module de haut niveau - dépend uniquement des ports\n@Service\npublic class OrderService {\n\n    private final OrderRepository repository;\n    private final PaymentGateway payment;\n\n    public OrderService(OrderRepository repository, PaymentGateway payment) {\n        this.repository = repository;\n        this.payment = payment;\n    }\n\n    public Order createPaidOrder(OrderData orderData) {\n        PaymentResult result = payment.charge(\n            orderData.getTotal(),\n            orderData.getCurrency(),\n            orderData.getPaymentMethodId()\n        );\n\n        if (!result.isSuccess()) {\n            throw new PaymentFailedException(result.getErrorCode());\n        }\n\n        String orderId = repository.save(\n            orderData.withPaymentId(result.getTransactionId())\n                     .withStatus(OrderStatus.PAID)\n        );\n\n        return repository.findById(orderId)\n            .orElseThrow(() -> new IllegalStateException(\"Order not found after save\"));\n    }\n}\n\n\u002F\u002F Fake en mémoire pour les tests - sans Stripe, sans base de données\nclass InMemoryOrderRepository implements OrderRepository {\n\n    private final Map\u003CString, OrderData> store = new HashMap\u003C>();\n\n    @Override\n    public String save(OrderData orderData) {\n        String id = UUID.randomUUID().toString();\n        store.put(id, orderData);\n        return id;\n    }\n\n    @Override\n    public Optional\u003COrder> findById(String orderId) {\n        return Optional.ofNullable(store.get(orderId))\n            .map(data -> new Order(orderId, data.getStatus()));\n    }\n}\n\nclass StubPaymentGateway implements PaymentGateway {\n\n    private final boolean shouldSucceed;\n\n    StubPaymentGateway(boolean shouldSucceed) {\n        this.shouldSucceed = shouldSucceed;\n    }\n\n    @Override\n    public PaymentResult charge(BigDecimal amount, String currency, String paymentMethodId) {\n        return shouldSucceed\n            ? PaymentResult.success(\"txn-456\")\n            : PaymentResult.failure(\"CARD_DECLINED\");\n    }\n}\n\n\u002F\u002F Test JUnit 5 - s'exécute en millisecondes, sans infra\nclass OrderServiceTest {\n\n    @Test\n    void shouldCreateOrderWithSuccessfulPayment() {\n        OrderRepository repository = new InMemoryOrderRepository();\n        PaymentGateway payment = new StubPaymentGateway(true);\n        OrderService service = new OrderService(repository, payment);\n\n        Order order = service.createPaidOrder(\n            new OrderData(new BigDecimal(\"1000\"), \"EUR\", \"pm-123\")\n        );\n\n        assertEquals(OrderStatus.PAID, order.getStatus());\n    }\n\n    @Test\n    void shouldThrowWhenPaymentFails() {\n        OrderService service = new OrderService(\n            new InMemoryOrderRepository(),\n            new StubPaymentGateway(false)\n        );\n\n        assertThrows(PaymentFailedException.class, () ->\n            service.createPaidOrder(new OrderData(new BigDecimal(\"1000\"), \"EUR\", \"pm-123\"))\n        );\n    }\n}\n",[2313],{"type":29,"tag":84,"props":2314,"children":2315},{"__ignoreMap":8},[2316,2324,2343,2370,2412,2419,2426,2446,2503,2510,2517,2525,2537,2556,2563,2586,2610,2617,2660,2687,2715,2722,2729,2766,2801,2823,2843,2864,2872,2879,2920,2959,2967,2974,3005,3043,3079,3086,3093,3125,3170,3177,3184,3191,3199,3222,3229,3286,3294,3308,3344,3385,3423,3440,3448,3456,3468,3517,3569,3635,3643,3651,3659,3684,3692,3717,3725,3755,3784,3792,3800,3812,3873,3886,3921,3956,3964,3972,3980,3989,4006,4014,4026,4047,4076,4115,4160,4168,4203,4261,4269,4277,4323,4331,4339,4351,4372,4400,4416,4441,4449,4457,4497,4566,4574,4582],{"type":29,"tag":88,"props":2317,"children":2318},{"class":90,"line":91},[2319],{"type":29,"tag":88,"props":2320,"children":2321},{"style":95},[2322],{"type":34,"value":2323},"\u002F\u002F Les ports (abstractions hexagonales)\n",{"type":29,"tag":88,"props":2325,"children":2326},{"class":90,"line":101},[2327,2331,2335,2339],{"type":29,"tag":88,"props":2328,"children":2329},{"style":105},[2330],{"type":34,"value":108},{"type":29,"tag":88,"props":2332,"children":2333},{"style":105},[2334],{"type":34,"value":601},{"type":29,"tag":88,"props":2336,"children":2337},{"style":116},[2338],{"type":34,"value":606},{"type":29,"tag":88,"props":2340,"children":2341},{"style":122},[2342],{"type":34,"value":125},{"type":29,"tag":88,"props":2344,"children":2345},{"class":90,"line":128},[2346,2350,2354,2358,2362,2366],{"type":29,"tag":88,"props":2347,"children":2348},{"style":151},[2349],{"type":34,"value":618},{"type":29,"tag":88,"props":2351,"children":2352},{"style":174},[2353],{"type":34,"value":623},{"type":29,"tag":88,"props":2355,"children":2356},{"style":122},[2357],{"type":34,"value":181},{"type":29,"tag":88,"props":2359,"children":2360},{"style":151},[2361],{"type":34,"value":295},{"type":29,"tag":88,"props":2363,"children":2364},{"style":298},[2365],{"type":34,"value":301},{"type":29,"tag":88,"props":2367,"children":2368},{"style":122},[2369],{"type":34,"value":357},{"type":29,"tag":88,"props":2371,"children":2372},{"class":90,"line":137},[2373,2378,2382,2387,2391,2396,2400,2404,2408],{"type":29,"tag":88,"props":2374,"children":2375},{"style":151},[2376],{"type":34,"value":2377},"    Optional",{"type":29,"tag":88,"props":2379,"children":2380},{"style":122},[2381],{"type":34,"value":1683},{"type":29,"tag":88,"props":2383,"children":2384},{"style":105},[2385],{"type":34,"value":2386},"Order",{"type":29,"tag":88,"props":2388,"children":2389},{"style":122},[2390],{"type":34,"value":1701},{"type":29,"tag":88,"props":2392,"children":2393},{"style":174},[2394],{"type":34,"value":2395}," findById",{"type":29,"tag":88,"props":2397,"children":2398},{"style":122},[2399],{"type":34,"value":181},{"type":29,"tag":88,"props":2401,"children":2402},{"style":151},[2403],{"type":34,"value":695},{"type":29,"tag":88,"props":2405,"children":2406},{"style":298},[2407],{"type":34,"value":402},{"type":29,"tag":88,"props":2409,"children":2410},{"style":122},[2411],{"type":34,"value":357},{"type":29,"tag":88,"props":2413,"children":2414},{"class":90,"line":211},[2415],{"type":29,"tag":88,"props":2416,"children":2417},{"style":122},[2418],{"type":34,"value":442},{"type":29,"tag":88,"props":2420,"children":2421},{"class":90,"line":262},[2422],{"type":29,"tag":88,"props":2423,"children":2424},{"emptyLinePlaceholder":13},[2425],{"type":34,"value":134},{"type":29,"tag":88,"props":2427,"children":2428},{"class":90,"line":270},[2429,2433,2437,2442],{"type":29,"tag":88,"props":2430,"children":2431},{"style":105},[2432],{"type":34,"value":108},{"type":29,"tag":88,"props":2434,"children":2435},{"style":105},[2436],{"type":34,"value":601},{"type":29,"tag":88,"props":2438,"children":2439},{"style":116},[2440],{"type":34,"value":2441}," PaymentGateway",{"type":29,"tag":88,"props":2443,"children":2444},{"style":122},[2445],{"type":34,"value":125},{"type":29,"tag":88,"props":2447,"children":2448},{"class":90,"line":313},[2449,2454,2459,2463,2468,2473,2477,2481,2486,2490,2494,2499],{"type":29,"tag":88,"props":2450,"children":2451},{"style":151},[2452],{"type":34,"value":2453},"    PaymentResult",{"type":29,"tag":88,"props":2455,"children":2456},{"style":174},[2457],{"type":34,"value":2458}," charge",{"type":29,"tag":88,"props":2460,"children":2461},{"style":122},[2462],{"type":34,"value":181},{"type":29,"tag":88,"props":2464,"children":2465},{"style":151},[2466],{"type":34,"value":2467},"BigDecimal",{"type":29,"tag":88,"props":2469,"children":2470},{"style":298},[2471],{"type":34,"value":2472}," amount",{"type":29,"tag":88,"props":2474,"children":2475},{"style":122},[2476],{"type":34,"value":192},{"type":29,"tag":88,"props":2478,"children":2479},{"style":151},[2480],{"type":34,"value":281},{"type":29,"tag":88,"props":2482,"children":2483},{"style":298},[2484],{"type":34,"value":2485}," currency",{"type":29,"tag":88,"props":2487,"children":2488},{"style":122},[2489],{"type":34,"value":192},{"type":29,"tag":88,"props":2491,"children":2492},{"style":151},[2493],{"type":34,"value":281},{"type":29,"tag":88,"props":2495,"children":2496},{"style":298},[2497],{"type":34,"value":2498}," paymentMethodId",{"type":29,"tag":88,"props":2500,"children":2501},{"style":122},[2502],{"type":34,"value":357},{"type":29,"tag":88,"props":2504,"children":2505},{"class":90,"line":360},[2506],{"type":29,"tag":88,"props":2507,"children":2508},{"style":122},[2509],{"type":34,"value":442},{"type":29,"tag":88,"props":2511,"children":2512},{"class":90,"line":409},[2513],{"type":29,"tag":88,"props":2514,"children":2515},{"emptyLinePlaceholder":13},[2516],{"type":34,"value":134},{"type":29,"tag":88,"props":2518,"children":2519},{"class":90,"line":427},[2520],{"type":29,"tag":88,"props":2521,"children":2522},{"style":95},[2523],{"type":34,"value":2524},"\u002F\u002F Le module de haut niveau - dépend uniquement des ports\n",{"type":29,"tag":88,"props":2526,"children":2527},{"class":90,"line":436},[2528,2532],{"type":29,"tag":88,"props":2529,"children":2530},{"style":1974},[2531],{"type":34,"value":1977},{"type":29,"tag":88,"props":2533,"children":2534},{"style":1980},[2535],{"type":34,"value":2536},"Service\n",{"type":29,"tag":88,"props":2538,"children":2539},{"class":90,"line":767},[2540,2544,2548,2552],{"type":29,"tag":88,"props":2541,"children":2542},{"style":105},[2543],{"type":34,"value":108},{"type":29,"tag":88,"props":2545,"children":2546},{"style":105},[2547],{"type":34,"value":113},{"type":29,"tag":88,"props":2549,"children":2550},{"style":116},[2551],{"type":34,"value":119},{"type":29,"tag":88,"props":2553,"children":2554},{"style":122},[2555],{"type":34,"value":125},{"type":29,"tag":88,"props":2557,"children":2558},{"class":90,"line":792},[2559],{"type":29,"tag":88,"props":2560,"children":2561},{"emptyLinePlaceholder":13},[2562],{"type":34,"value":134},{"type":29,"tag":88,"props":2564,"children":2565},{"class":90,"line":817},[2566,2570,2574,2578,2582],{"type":29,"tag":88,"props":2567,"children":2568},{"style":105},[2569],{"type":34,"value":143},{"type":29,"tag":88,"props":2571,"children":2572},{"style":105},[2573],{"type":34,"value":148},{"type":29,"tag":88,"props":2575,"children":2576},{"style":151},[2577],{"type":34,"value":606},{"type":29,"tag":88,"props":2579,"children":2580},{"style":157},[2581],{"type":34,"value":785},{"type":29,"tag":88,"props":2583,"children":2584},{"style":122},[2585],{"type":34,"value":424},{"type":29,"tag":88,"props":2587,"children":2588},{"class":90,"line":825},[2589,2593,2597,2601,2606],{"type":29,"tag":88,"props":2590,"children":2591},{"style":105},[2592],{"type":34,"value":143},{"type":29,"tag":88,"props":2594,"children":2595},{"style":105},[2596],{"type":34,"value":148},{"type":29,"tag":88,"props":2598,"children":2599},{"style":151},[2600],{"type":34,"value":2441},{"type":29,"tag":88,"props":2602,"children":2603},{"style":157},[2604],{"type":34,"value":2605}," payment",{"type":29,"tag":88,"props":2607,"children":2608},{"style":122},[2609],{"type":34,"value":424},{"type":29,"tag":88,"props":2611,"children":2612},{"class":90,"line":869},[2613],{"type":29,"tag":88,"props":2614,"children":2615},{"emptyLinePlaceholder":13},[2616],{"type":34,"value":134},{"type":29,"tag":88,"props":2618,"children":2619},{"class":90,"line":900},[2620,2624,2628,2632,2636,2640,2644,2648,2652,2656],{"type":29,"tag":88,"props":2621,"children":2622},{"style":105},[2623],{"type":34,"value":276},{"type":29,"tag":88,"props":2625,"children":2626},{"style":174},[2627],{"type":34,"value":119},{"type":29,"tag":88,"props":2629,"children":2630},{"style":122},[2631],{"type":34,"value":181},{"type":29,"tag":88,"props":2633,"children":2634},{"style":151},[2635],{"type":34,"value":542},{"type":29,"tag":88,"props":2637,"children":2638},{"style":298},[2639],{"type":34,"value":785},{"type":29,"tag":88,"props":2641,"children":2642},{"style":122},[2643],{"type":34,"value":192},{"type":29,"tag":88,"props":2645,"children":2646},{"style":151},[2647],{"type":34,"value":2441},{"type":29,"tag":88,"props":2649,"children":2650},{"style":298},[2651],{"type":34,"value":2605},{"type":29,"tag":88,"props":2653,"children":2654},{"style":122},[2655],{"type":34,"value":306},{"type":29,"tag":88,"props":2657,"children":2658},{"style":122},[2659],{"type":34,"value":125},{"type":29,"tag":88,"props":2661,"children":2662},{"class":90,"line":929},[2663,2667,2671,2675,2679,2683],{"type":29,"tag":88,"props":2664,"children":2665},{"style":873},[2666],{"type":34,"value":876},{"type":29,"tag":88,"props":2668,"children":2669},{"style":122},[2670],{"type":34,"value":338},{"type":29,"tag":88,"props":2672,"children":2673},{"style":157},[2674],{"type":34,"value":885},{"type":29,"tag":88,"props":2676,"children":2677},{"style":163},[2678],{"type":34,"value":166},{"type":29,"tag":88,"props":2680,"children":2681},{"style":157},[2682],{"type":34,"value":785},{"type":29,"tag":88,"props":2684,"children":2685},{"style":122},[2686],{"type":34,"value":424},{"type":29,"tag":88,"props":2688,"children":2689},{"class":90,"line":937},[2690,2694,2698,2703,2707,2711],{"type":29,"tag":88,"props":2691,"children":2692},{"style":873},[2693],{"type":34,"value":876},{"type":29,"tag":88,"props":2695,"children":2696},{"style":122},[2697],{"type":34,"value":338},{"type":29,"tag":88,"props":2699,"children":2700},{"style":157},[2701],{"type":34,"value":2702},"payment ",{"type":29,"tag":88,"props":2704,"children":2705},{"style":163},[2706],{"type":34,"value":166},{"type":29,"tag":88,"props":2708,"children":2709},{"style":157},[2710],{"type":34,"value":2605},{"type":29,"tag":88,"props":2712,"children":2713},{"style":122},[2714],{"type":34,"value":424},{"type":29,"tag":88,"props":2716,"children":2717},{"class":90,"line":945},[2718],{"type":29,"tag":88,"props":2719,"children":2720},{"style":122},[2721],{"type":34,"value":433},{"type":29,"tag":88,"props":2723,"children":2724},{"class":90,"line":981},[2725],{"type":29,"tag":88,"props":2726,"children":2727},{"emptyLinePlaceholder":13},[2728],{"type":34,"value":134},{"type":29,"tag":88,"props":2730,"children":2731},{"class":90,"line":1021},[2732,2736,2741,2746,2750,2754,2758,2762],{"type":29,"tag":88,"props":2733,"children":2734},{"style":105},[2735],{"type":34,"value":276},{"type":29,"tag":88,"props":2737,"children":2738},{"style":151},[2739],{"type":34,"value":2740}," Order",{"type":29,"tag":88,"props":2742,"children":2743},{"style":174},[2744],{"type":34,"value":2745}," createPaidOrder",{"type":29,"tag":88,"props":2747,"children":2748},{"style":122},[2749],{"type":34,"value":181},{"type":29,"tag":88,"props":2751,"children":2752},{"style":151},[2753],{"type":34,"value":295},{"type":29,"tag":88,"props":2755,"children":2756},{"style":298},[2757],{"type":34,"value":301},{"type":29,"tag":88,"props":2759,"children":2760},{"style":122},[2761],{"type":34,"value":306},{"type":29,"tag":88,"props":2763,"children":2764},{"style":122},[2765],{"type":34,"value":125},{"type":29,"tag":88,"props":2767,"children":2768},{"class":90,"line":1066},[2769,2774,2779,2783,2787,2791,2796],{"type":29,"tag":88,"props":2770,"children":2771},{"style":151},[2772],{"type":34,"value":2773},"        PaymentResult",{"type":29,"tag":88,"props":2775,"children":2776},{"style":157},[2777],{"type":34,"value":2778}," result ",{"type":29,"tag":88,"props":2780,"children":2781},{"style":163},[2782],{"type":34,"value":166},{"type":29,"tag":88,"props":2784,"children":2785},{"style":157},[2786],{"type":34,"value":2605},{"type":29,"tag":88,"props":2788,"children":2789},{"style":122},[2790],{"type":34,"value":338},{"type":29,"tag":88,"props":2792,"children":2793},{"style":174},[2794],{"type":34,"value":2795},"charge",{"type":29,"tag":88,"props":2797,"children":2798},{"style":122},[2799],{"type":34,"value":2800},"(\n",{"type":29,"tag":88,"props":2802,"children":2803},{"class":90,"line":1082},[2804,2809,2813,2818],{"type":29,"tag":88,"props":2805,"children":2806},{"style":157},[2807],{"type":34,"value":2808},"            orderData",{"type":29,"tag":88,"props":2810,"children":2811},{"style":122},[2812],{"type":34,"value":338},{"type":29,"tag":88,"props":2814,"children":2815},{"style":174},[2816],{"type":34,"value":2817},"getTotal",{"type":29,"tag":88,"props":2819,"children":2820},{"style":122},[2821],{"type":34,"value":2822},"(),\n",{"type":29,"tag":88,"props":2824,"children":2825},{"class":90,"line":1090},[2826,2830,2834,2839],{"type":29,"tag":88,"props":2827,"children":2828},{"style":157},[2829],{"type":34,"value":2808},{"type":29,"tag":88,"props":2831,"children":2832},{"style":122},[2833],{"type":34,"value":338},{"type":29,"tag":88,"props":2835,"children":2836},{"style":174},[2837],{"type":34,"value":2838},"getCurrency",{"type":29,"tag":88,"props":2840,"children":2841},{"style":122},[2842],{"type":34,"value":2822},{"type":29,"tag":88,"props":2844,"children":2845},{"class":90,"line":1098},[2846,2850,2854,2859],{"type":29,"tag":88,"props":2847,"children":2848},{"style":157},[2849],{"type":34,"value":2808},{"type":29,"tag":88,"props":2851,"children":2852},{"style":122},[2853],{"type":34,"value":338},{"type":29,"tag":88,"props":2855,"children":2856},{"style":174},[2857],{"type":34,"value":2858},"getPaymentMethodId",{"type":29,"tag":88,"props":2860,"children":2861},{"style":122},[2862],{"type":34,"value":2863},"()\n",{"type":29,"tag":88,"props":2865,"children":2866},{"class":90,"line":1106},[2867],{"type":29,"tag":88,"props":2868,"children":2869},{"style":122},[2870],{"type":34,"value":2871},"        );\n",{"type":29,"tag":88,"props":2873,"children":2874},{"class":90,"line":1115},[2875],{"type":29,"tag":88,"props":2876,"children":2877},{"emptyLinePlaceholder":13},[2878],{"type":34,"value":134},{"type":29,"tag":88,"props":2880,"children":2881},{"class":90,"line":11},[2882,2887,2892,2897,2902,2906,2911,2916],{"type":29,"tag":88,"props":2883,"children":2884},{"style":105},[2885],{"type":34,"value":2886},"        if",{"type":29,"tag":88,"props":2888,"children":2889},{"style":122},[2890],{"type":34,"value":2891}," (",{"type":29,"tag":88,"props":2893,"children":2894},{"style":163},[2895],{"type":34,"value":2896},"!",{"type":29,"tag":88,"props":2898,"children":2899},{"style":157},[2900],{"type":34,"value":2901},"result",{"type":29,"tag":88,"props":2903,"children":2904},{"style":122},[2905],{"type":34,"value":338},{"type":29,"tag":88,"props":2907,"children":2908},{"style":174},[2909],{"type":34,"value":2910},"isSuccess",{"type":29,"tag":88,"props":2912,"children":2913},{"style":122},[2914],{"type":34,"value":2915},"())",{"type":29,"tag":88,"props":2917,"children":2918},{"style":122},[2919],{"type":34,"value":125},{"type":29,"tag":88,"props":2921,"children":2922},{"class":90,"line":1180},[2923,2928,2932,2937,2941,2945,2949,2954],{"type":29,"tag":88,"props":2924,"children":2925},{"style":105},[2926],{"type":34,"value":2927},"            throw",{"type":29,"tag":88,"props":2929,"children":2930},{"style":105},[2931],{"type":34,"value":171},{"type":29,"tag":88,"props":2933,"children":2934},{"style":174},[2935],{"type":34,"value":2936}," PaymentFailedException",{"type":29,"tag":88,"props":2938,"children":2939},{"style":122},[2940],{"type":34,"value":181},{"type":29,"tag":88,"props":2942,"children":2943},{"style":157},[2944],{"type":34,"value":2901},{"type":29,"tag":88,"props":2946,"children":2947},{"style":122},[2948],{"type":34,"value":338},{"type":29,"tag":88,"props":2950,"children":2951},{"style":174},[2952],{"type":34,"value":2953},"getErrorCode",{"type":29,"tag":88,"props":2955,"children":2956},{"style":122},[2957],{"type":34,"value":2958},"());\n",{"type":29,"tag":88,"props":2960,"children":2961},{"class":90,"line":1240},[2962],{"type":29,"tag":88,"props":2963,"children":2964},{"style":122},[2965],{"type":34,"value":2966},"        }\n",{"type":29,"tag":88,"props":2968,"children":2969},{"class":90,"line":1248},[2970],{"type":29,"tag":88,"props":2971,"children":2972},{"emptyLinePlaceholder":13},[2973],{"type":34,"value":134},{"type":29,"tag":88,"props":2975,"children":2976},{"class":90,"line":1256},[2977,2981,2985,2989,2993,2997,3001],{"type":29,"tag":88,"props":2978,"children":2979},{"style":151},[2980],{"type":34,"value":319},{"type":29,"tag":88,"props":2982,"children":2983},{"style":157},[2984],{"type":34,"value":324},{"type":29,"tag":88,"props":2986,"children":2987},{"style":163},[2988],{"type":34,"value":166},{"type":29,"tag":88,"props":2990,"children":2991},{"style":157},[2992],{"type":34,"value":785},{"type":29,"tag":88,"props":2994,"children":2995},{"style":122},[2996],{"type":34,"value":338},{"type":29,"tag":88,"props":2998,"children":2999},{"style":174},[3000],{"type":34,"value":343},{"type":29,"tag":88,"props":3002,"children":3003},{"style":122},[3004],{"type":34,"value":2800},{"type":29,"tag":88,"props":3006,"children":3007},{"class":90,"line":1264},[3008,3012,3016,3021,3025,3029,3033,3038],{"type":29,"tag":88,"props":3009,"children":3010},{"style":157},[3011],{"type":34,"value":2808},{"type":29,"tag":88,"props":3013,"children":3014},{"style":122},[3015],{"type":34,"value":338},{"type":29,"tag":88,"props":3017,"children":3018},{"style":174},[3019],{"type":34,"value":3020},"withPaymentId",{"type":29,"tag":88,"props":3022,"children":3023},{"style":122},[3024],{"type":34,"value":181},{"type":29,"tag":88,"props":3026,"children":3027},{"style":157},[3028],{"type":34,"value":2901},{"type":29,"tag":88,"props":3030,"children":3031},{"style":122},[3032],{"type":34,"value":338},{"type":29,"tag":88,"props":3034,"children":3035},{"style":174},[3036],{"type":34,"value":3037},"getTransactionId",{"type":29,"tag":88,"props":3039,"children":3040},{"style":122},[3041],{"type":34,"value":3042},"())\n",{"type":29,"tag":88,"props":3044,"children":3045},{"class":90,"line":1293},[3046,3051,3056,3060,3065,3069,3074],{"type":29,"tag":88,"props":3047,"children":3048},{"style":122},[3049],{"type":34,"value":3050},"                     .",{"type":29,"tag":88,"props":3052,"children":3053},{"style":174},[3054],{"type":34,"value":3055},"withStatus",{"type":29,"tag":88,"props":3057,"children":3058},{"style":122},[3059],{"type":34,"value":181},{"type":29,"tag":88,"props":3061,"children":3062},{"style":157},[3063],{"type":34,"value":3064},"OrderStatus",{"type":29,"tag":88,"props":3066,"children":3067},{"style":122},[3068],{"type":34,"value":338},{"type":29,"tag":88,"props":3070,"children":3071},{"style":157},[3072],{"type":34,"value":3073},"PAID",{"type":29,"tag":88,"props":3075,"children":3076},{"style":122},[3077],{"type":34,"value":3078},")\n",{"type":29,"tag":88,"props":3080,"children":3081},{"class":90,"line":1342},[3082],{"type":29,"tag":88,"props":3083,"children":3084},{"style":122},[3085],{"type":34,"value":2871},{"type":29,"tag":88,"props":3087,"children":3088},{"class":90,"line":1418},[3089],{"type":29,"tag":88,"props":3090,"children":3091},{"emptyLinePlaceholder":13},[3092],{"type":34,"value":134},{"type":29,"tag":88,"props":3094,"children":3095},{"class":90,"line":1426},[3096,3100,3104,3108,3113,3117,3121],{"type":29,"tag":88,"props":3097,"children":3098},{"style":105},[3099],{"type":34,"value":415},{"type":29,"tag":88,"props":3101,"children":3102},{"style":157},[3103],{"type":34,"value":785},{"type":29,"tag":88,"props":3105,"children":3106},{"style":122},[3107],{"type":34,"value":338},{"type":29,"tag":88,"props":3109,"children":3110},{"style":174},[3111],{"type":34,"value":3112},"findById",{"type":29,"tag":88,"props":3114,"children":3115},{"style":122},[3116],{"type":34,"value":181},{"type":29,"tag":88,"props":3118,"children":3119},{"style":157},[3120],{"type":34,"value":1836},{"type":29,"tag":88,"props":3122,"children":3123},{"style":122},[3124],{"type":34,"value":3078},{"type":29,"tag":88,"props":3126,"children":3127},{"class":90,"line":1434},[3128,3133,3138,3143,3148,3152,3157,3161,3166],{"type":29,"tag":88,"props":3129,"children":3130},{"style":122},[3131],{"type":34,"value":3132},"            .",{"type":29,"tag":88,"props":3134,"children":3135},{"style":174},[3136],{"type":34,"value":3137},"orElseThrow",{"type":29,"tag":88,"props":3139,"children":3140},{"style":122},[3141],{"type":34,"value":3142},"(()",{"type":29,"tag":88,"props":3144,"children":3145},{"style":105},[3146],{"type":34,"value":3147}," ->",{"type":29,"tag":88,"props":3149,"children":3150},{"style":105},[3151],{"type":34,"value":171},{"type":29,"tag":88,"props":3153,"children":3154},{"style":174},[3155],{"type":34,"value":3156}," IllegalStateException",{"type":29,"tag":88,"props":3158,"children":3159},{"style":122},[3160],{"type":34,"value":181},{"type":29,"tag":88,"props":3162,"children":3163},{"style":184},[3164],{"type":34,"value":3165},"\"Order not found after save\"",{"type":29,"tag":88,"props":3167,"children":3168},{"style":122},[3169],{"type":34,"value":1415},{"type":29,"tag":88,"props":3171,"children":3172},{"class":90,"line":1442},[3173],{"type":29,"tag":88,"props":3174,"children":3175},{"style":122},[3176],{"type":34,"value":433},{"type":29,"tag":88,"props":3178,"children":3179},{"class":90,"line":1451},[3180],{"type":29,"tag":88,"props":3181,"children":3182},{"style":122},[3183],{"type":34,"value":442},{"type":29,"tag":88,"props":3185,"children":3186},{"class":90,"line":1477},[3187],{"type":29,"tag":88,"props":3188,"children":3189},{"emptyLinePlaceholder":13},[3190],{"type":34,"value":134},{"type":29,"tag":88,"props":3192,"children":3193},{"class":90,"line":1516},[3194],{"type":29,"tag":88,"props":3195,"children":3196},{"style":95},[3197],{"type":34,"value":3198},"\u002F\u002F Fake en mémoire pour les tests - sans Stripe, sans base de données\n",{"type":29,"tag":88,"props":3200,"children":3201},{"class":90,"line":1573},[3202,3206,3210,3214,3218],{"type":29,"tag":88,"props":3203,"children":3204},{"style":105},[3205],{"type":34,"value":1225},{"type":29,"tag":88,"props":3207,"children":3208},{"style":116},[3209],{"type":34,"value":1651},{"type":29,"tag":88,"props":3211,"children":3212},{"style":105},[3213],{"type":34,"value":1134},{"type":29,"tag":88,"props":3215,"children":3216},{"style":116},[3217],{"type":34,"value":606},{"type":29,"tag":88,"props":3219,"children":3220},{"style":122},[3221],{"type":34,"value":125},{"type":29,"tag":88,"props":3223,"children":3224},{"class":90,"line":1611},[3225],{"type":29,"tag":88,"props":3226,"children":3227},{"emptyLinePlaceholder":13},[3228],{"type":34,"value":134},{"type":29,"tag":88,"props":3230,"children":3232},{"class":90,"line":3231},47,[3233,3237,3241,3245,3249,3253,3257,3261,3265,3270,3274,3278,3282],{"type":29,"tag":88,"props":3234,"children":3235},{"style":105},[3236],{"type":34,"value":143},{"type":29,"tag":88,"props":3238,"children":3239},{"style":105},[3240],{"type":34,"value":148},{"type":29,"tag":88,"props":3242,"children":3243},{"style":151},[3244],{"type":34,"value":1384},{"type":29,"tag":88,"props":3246,"children":3247},{"style":122},[3248],{"type":34,"value":1683},{"type":29,"tag":88,"props":3250,"children":3251},{"style":105},[3252],{"type":34,"value":695},{"type":29,"tag":88,"props":3254,"children":3255},{"style":122},[3256],{"type":34,"value":192},{"type":29,"tag":88,"props":3258,"children":3259},{"style":105},[3260],{"type":34,"value":1696},{"type":29,"tag":88,"props":3262,"children":3263},{"style":122},[3264],{"type":34,"value":1701},{"type":29,"tag":88,"props":3266,"children":3267},{"style":157},[3268],{"type":34,"value":3269}," store ",{"type":29,"tag":88,"props":3271,"children":3272},{"style":163},[3273],{"type":34,"value":166},{"type":29,"tag":88,"props":3275,"children":3276},{"style":105},[3277],{"type":34,"value":171},{"type":29,"tag":88,"props":3279,"children":3280},{"style":151},[3281],{"type":34,"value":1719},{"type":29,"tag":88,"props":3283,"children":3284},{"style":122},[3285],{"type":34,"value":1724},{"type":29,"tag":88,"props":3287,"children":3289},{"class":90,"line":3288},48,[3290],{"type":29,"tag":88,"props":3291,"children":3292},{"emptyLinePlaceholder":13},[3293],{"type":34,"value":134},{"type":29,"tag":88,"props":3295,"children":3297},{"class":90,"line":3296},49,[3298,3303],{"type":29,"tag":88,"props":3299,"children":3300},{"style":1974},[3301],{"type":34,"value":3302},"    @",{"type":29,"tag":88,"props":3304,"children":3305},{"style":1980},[3306],{"type":34,"value":3307},"Override\n",{"type":29,"tag":88,"props":3309,"children":3311},{"class":90,"line":3310},50,[3312,3316,3320,3324,3328,3332,3336,3340],{"type":29,"tag":88,"props":3313,"children":3314},{"style":105},[3315],{"type":34,"value":276},{"type":29,"tag":88,"props":3317,"children":3318},{"style":151},[3319],{"type":34,"value":281},{"type":29,"tag":88,"props":3321,"children":3322},{"style":174},[3323],{"type":34,"value":623},{"type":29,"tag":88,"props":3325,"children":3326},{"style":122},[3327],{"type":34,"value":181},{"type":29,"tag":88,"props":3329,"children":3330},{"style":151},[3331],{"type":34,"value":295},{"type":29,"tag":88,"props":3333,"children":3334},{"style":298},[3335],{"type":34,"value":301},{"type":29,"tag":88,"props":3337,"children":3338},{"style":122},[3339],{"type":34,"value":306},{"type":29,"tag":88,"props":3341,"children":3342},{"style":122},[3343],{"type":34,"value":125},{"type":29,"tag":88,"props":3345,"children":3347},{"class":90,"line":3346},51,[3348,3352,3357,3361,3365,3369,3373,3377,3381],{"type":29,"tag":88,"props":3349,"children":3350},{"style":151},[3351],{"type":34,"value":319},{"type":29,"tag":88,"props":3353,"children":3354},{"style":157},[3355],{"type":34,"value":3356}," id ",{"type":29,"tag":88,"props":3358,"children":3359},{"style":163},[3360],{"type":34,"value":166},{"type":29,"tag":88,"props":3362,"children":3363},{"style":157},[3364],{"type":34,"value":1786},{"type":29,"tag":88,"props":3366,"children":3367},{"style":122},[3368],{"type":34,"value":338},{"type":29,"tag":88,"props":3370,"children":3371},{"style":174},[3372],{"type":34,"value":1795},{"type":29,"tag":88,"props":3374,"children":3375},{"style":122},[3376],{"type":34,"value":1800},{"type":29,"tag":88,"props":3378,"children":3379},{"style":174},[3380],{"type":34,"value":1805},{"type":29,"tag":88,"props":3382,"children":3383},{"style":122},[3384],{"type":34,"value":1810},{"type":29,"tag":88,"props":3386,"children":3388},{"class":90,"line":3387},52,[3389,3394,3398,3402,3406,3411,3415,3419],{"type":29,"tag":88,"props":3390,"children":3391},{"style":157},[3392],{"type":34,"value":3393},"        store",{"type":29,"tag":88,"props":3395,"children":3396},{"style":122},[3397],{"type":34,"value":338},{"type":29,"tag":88,"props":3399,"children":3400},{"style":174},[3401],{"type":34,"value":1827},{"type":29,"tag":88,"props":3403,"children":3404},{"style":122},[3405],{"type":34,"value":181},{"type":29,"tag":88,"props":3407,"children":3408},{"style":157},[3409],{"type":34,"value":3410},"id",{"type":29,"tag":88,"props":3412,"children":3413},{"style":122},[3414],{"type":34,"value":192},{"type":29,"tag":88,"props":3416,"children":3417},{"style":157},[3418],{"type":34,"value":301},{"type":29,"tag":88,"props":3420,"children":3421},{"style":122},[3422],{"type":34,"value":357},{"type":29,"tag":88,"props":3424,"children":3426},{"class":90,"line":3425},53,[3427,3431,3436],{"type":29,"tag":88,"props":3428,"children":3429},{"style":105},[3430],{"type":34,"value":415},{"type":29,"tag":88,"props":3432,"children":3433},{"style":157},[3434],{"type":34,"value":3435}," id",{"type":29,"tag":88,"props":3437,"children":3438},{"style":122},[3439],{"type":34,"value":424},{"type":29,"tag":88,"props":3441,"children":3443},{"class":90,"line":3442},54,[3444],{"type":29,"tag":88,"props":3445,"children":3446},{"style":122},[3447],{"type":34,"value":433},{"type":29,"tag":88,"props":3449,"children":3451},{"class":90,"line":3450},55,[3452],{"type":29,"tag":88,"props":3453,"children":3454},{"emptyLinePlaceholder":13},[3455],{"type":34,"value":134},{"type":29,"tag":88,"props":3457,"children":3459},{"class":90,"line":3458},56,[3460,3464],{"type":29,"tag":88,"props":3461,"children":3462},{"style":1974},[3463],{"type":34,"value":3302},{"type":29,"tag":88,"props":3465,"children":3466},{"style":1980},[3467],{"type":34,"value":3307},{"type":29,"tag":88,"props":3469,"children":3471},{"class":90,"line":3470},57,[3472,3476,3481,3485,3489,3493,3497,3501,3505,3509,3513],{"type":29,"tag":88,"props":3473,"children":3474},{"style":105},[3475],{"type":34,"value":276},{"type":29,"tag":88,"props":3477,"children":3478},{"style":151},[3479],{"type":34,"value":3480}," Optional",{"type":29,"tag":88,"props":3482,"children":3483},{"style":122},[3484],{"type":34,"value":1683},{"type":29,"tag":88,"props":3486,"children":3487},{"style":105},[3488],{"type":34,"value":2386},{"type":29,"tag":88,"props":3490,"children":3491},{"style":122},[3492],{"type":34,"value":1701},{"type":29,"tag":88,"props":3494,"children":3495},{"style":174},[3496],{"type":34,"value":2395},{"type":29,"tag":88,"props":3498,"children":3499},{"style":122},[3500],{"type":34,"value":181},{"type":29,"tag":88,"props":3502,"children":3503},{"style":151},[3504],{"type":34,"value":695},{"type":29,"tag":88,"props":3506,"children":3507},{"style":298},[3508],{"type":34,"value":402},{"type":29,"tag":88,"props":3510,"children":3511},{"style":122},[3512],{"type":34,"value":306},{"type":29,"tag":88,"props":3514,"children":3515},{"style":122},[3516],{"type":34,"value":125},{"type":29,"tag":88,"props":3518,"children":3520},{"class":90,"line":3519},58,[3521,3525,3529,3533,3538,3542,3547,3551,3556,3560,3564],{"type":29,"tag":88,"props":3522,"children":3523},{"style":105},[3524],{"type":34,"value":415},{"type":29,"tag":88,"props":3526,"children":3527},{"style":157},[3528],{"type":34,"value":3480},{"type":29,"tag":88,"props":3530,"children":3531},{"style":122},[3532],{"type":34,"value":338},{"type":29,"tag":88,"props":3534,"children":3535},{"style":174},[3536],{"type":34,"value":3537},"ofNullable",{"type":29,"tag":88,"props":3539,"children":3540},{"style":122},[3541],{"type":34,"value":181},{"type":29,"tag":88,"props":3543,"children":3544},{"style":157},[3545],{"type":34,"value":3546},"store",{"type":29,"tag":88,"props":3548,"children":3549},{"style":122},[3550],{"type":34,"value":338},{"type":29,"tag":88,"props":3552,"children":3553},{"style":174},[3554],{"type":34,"value":3555},"get",{"type":29,"tag":88,"props":3557,"children":3558},{"style":122},[3559],{"type":34,"value":181},{"type":29,"tag":88,"props":3561,"children":3562},{"style":157},[3563],{"type":34,"value":1836},{"type":29,"tag":88,"props":3565,"children":3566},{"style":122},[3567],{"type":34,"value":3568},"))\n",{"type":29,"tag":88,"props":3570,"children":3572},{"class":90,"line":3571},59,[3573,3577,3582,3586,3591,3596,3600,3604,3608,3612,3616,3621,3625,3630],{"type":29,"tag":88,"props":3574,"children":3575},{"style":122},[3576],{"type":34,"value":3132},{"type":29,"tag":88,"props":3578,"children":3579},{"style":174},[3580],{"type":34,"value":3581},"map",{"type":29,"tag":88,"props":3583,"children":3584},{"style":122},[3585],{"type":34,"value":181},{"type":29,"tag":88,"props":3587,"children":3588},{"style":157},[3589],{"type":34,"value":3590},"data ",{"type":29,"tag":88,"props":3592,"children":3593},{"style":105},[3594],{"type":34,"value":3595},"->",{"type":29,"tag":88,"props":3597,"children":3598},{"style":105},[3599],{"type":34,"value":171},{"type":29,"tag":88,"props":3601,"children":3602},{"style":174},[3603],{"type":34,"value":2740},{"type":29,"tag":88,"props":3605,"children":3606},{"style":122},[3607],{"type":34,"value":181},{"type":29,"tag":88,"props":3609,"children":3610},{"style":157},[3611],{"type":34,"value":1836},{"type":29,"tag":88,"props":3613,"children":3614},{"style":122},[3615],{"type":34,"value":192},{"type":29,"tag":88,"props":3617,"children":3618},{"style":157},[3619],{"type":34,"value":3620}," data",{"type":29,"tag":88,"props":3622,"children":3623},{"style":122},[3624],{"type":34,"value":338},{"type":29,"tag":88,"props":3626,"children":3627},{"style":174},[3628],{"type":34,"value":3629},"getStatus",{"type":29,"tag":88,"props":3631,"children":3632},{"style":122},[3633],{"type":34,"value":3634},"()));\n",{"type":29,"tag":88,"props":3636,"children":3638},{"class":90,"line":3637},60,[3639],{"type":29,"tag":88,"props":3640,"children":3641},{"style":122},[3642],{"type":34,"value":433},{"type":29,"tag":88,"props":3644,"children":3646},{"class":90,"line":3645},61,[3647],{"type":29,"tag":88,"props":3648,"children":3649},{"style":122},[3650],{"type":34,"value":442},{"type":29,"tag":88,"props":3652,"children":3654},{"class":90,"line":3653},62,[3655],{"type":29,"tag":88,"props":3656,"children":3657},{"emptyLinePlaceholder":13},[3658],{"type":34,"value":134},{"type":29,"tag":88,"props":3660,"children":3662},{"class":90,"line":3661},63,[3663,3667,3672,3676,3680],{"type":29,"tag":88,"props":3664,"children":3665},{"style":105},[3666],{"type":34,"value":1225},{"type":29,"tag":88,"props":3668,"children":3669},{"style":116},[3670],{"type":34,"value":3671}," StubPaymentGateway",{"type":29,"tag":88,"props":3673,"children":3674},{"style":105},[3675],{"type":34,"value":1134},{"type":29,"tag":88,"props":3677,"children":3678},{"style":116},[3679],{"type":34,"value":2441},{"type":29,"tag":88,"props":3681,"children":3682},{"style":122},[3683],{"type":34,"value":125},{"type":29,"tag":88,"props":3685,"children":3687},{"class":90,"line":3686},64,[3688],{"type":29,"tag":88,"props":3689,"children":3690},{"emptyLinePlaceholder":13},[3691],{"type":34,"value":134},{"type":29,"tag":88,"props":3693,"children":3695},{"class":90,"line":3694},65,[3696,3700,3704,3708,3713],{"type":29,"tag":88,"props":3697,"children":3698},{"style":105},[3699],{"type":34,"value":143},{"type":29,"tag":88,"props":3701,"children":3702},{"style":105},[3703],{"type":34,"value":148},{"type":29,"tag":88,"props":3705,"children":3706},{"style":105},[3707],{"type":34,"value":1889},{"type":29,"tag":88,"props":3709,"children":3710},{"style":157},[3711],{"type":34,"value":3712}," shouldSucceed",{"type":29,"tag":88,"props":3714,"children":3715},{"style":122},[3716],{"type":34,"value":424},{"type":29,"tag":88,"props":3718,"children":3720},{"class":90,"line":3719},66,[3721],{"type":29,"tag":88,"props":3722,"children":3723},{"emptyLinePlaceholder":13},[3724],{"type":34,"value":134},{"type":29,"tag":88,"props":3726,"children":3728},{"class":90,"line":3727},67,[3729,3734,3738,3743,3747,3751],{"type":29,"tag":88,"props":3730,"children":3731},{"style":174},[3732],{"type":34,"value":3733},"    StubPaymentGateway",{"type":29,"tag":88,"props":3735,"children":3736},{"style":122},[3737],{"type":34,"value":181},{"type":29,"tag":88,"props":3739,"children":3740},{"style":105},[3741],{"type":34,"value":3742},"boolean",{"type":29,"tag":88,"props":3744,"children":3745},{"style":298},[3746],{"type":34,"value":3712},{"type":29,"tag":88,"props":3748,"children":3749},{"style":122},[3750],{"type":34,"value":306},{"type":29,"tag":88,"props":3752,"children":3753},{"style":122},[3754],{"type":34,"value":125},{"type":29,"tag":88,"props":3756,"children":3758},{"class":90,"line":3757},68,[3759,3763,3767,3772,3776,3780],{"type":29,"tag":88,"props":3760,"children":3761},{"style":873},[3762],{"type":34,"value":876},{"type":29,"tag":88,"props":3764,"children":3765},{"style":122},[3766],{"type":34,"value":338},{"type":29,"tag":88,"props":3768,"children":3769},{"style":157},[3770],{"type":34,"value":3771},"shouldSucceed ",{"type":29,"tag":88,"props":3773,"children":3774},{"style":163},[3775],{"type":34,"value":166},{"type":29,"tag":88,"props":3777,"children":3778},{"style":157},[3779],{"type":34,"value":3712},{"type":29,"tag":88,"props":3781,"children":3782},{"style":122},[3783],{"type":34,"value":424},{"type":29,"tag":88,"props":3785,"children":3787},{"class":90,"line":3786},69,[3788],{"type":29,"tag":88,"props":3789,"children":3790},{"style":122},[3791],{"type":34,"value":433},{"type":29,"tag":88,"props":3793,"children":3795},{"class":90,"line":3794},70,[3796],{"type":29,"tag":88,"props":3797,"children":3798},{"emptyLinePlaceholder":13},[3799],{"type":34,"value":134},{"type":29,"tag":88,"props":3801,"children":3803},{"class":90,"line":3802},71,[3804,3808],{"type":29,"tag":88,"props":3805,"children":3806},{"style":1974},[3807],{"type":34,"value":3302},{"type":29,"tag":88,"props":3809,"children":3810},{"style":1980},[3811],{"type":34,"value":3307},{"type":29,"tag":88,"props":3813,"children":3815},{"class":90,"line":3814},72,[3816,3820,3825,3829,3833,3837,3841,3845,3849,3853,3857,3861,3865,3869],{"type":29,"tag":88,"props":3817,"children":3818},{"style":105},[3819],{"type":34,"value":276},{"type":29,"tag":88,"props":3821,"children":3822},{"style":151},[3823],{"type":34,"value":3824}," PaymentResult",{"type":29,"tag":88,"props":3826,"children":3827},{"style":174},[3828],{"type":34,"value":2458},{"type":29,"tag":88,"props":3830,"children":3831},{"style":122},[3832],{"type":34,"value":181},{"type":29,"tag":88,"props":3834,"children":3835},{"style":151},[3836],{"type":34,"value":2467},{"type":29,"tag":88,"props":3838,"children":3839},{"style":298},[3840],{"type":34,"value":2472},{"type":29,"tag":88,"props":3842,"children":3843},{"style":122},[3844],{"type":34,"value":192},{"type":29,"tag":88,"props":3846,"children":3847},{"style":151},[3848],{"type":34,"value":281},{"type":29,"tag":88,"props":3850,"children":3851},{"style":298},[3852],{"type":34,"value":2485},{"type":29,"tag":88,"props":3854,"children":3855},{"style":122},[3856],{"type":34,"value":192},{"type":29,"tag":88,"props":3858,"children":3859},{"style":151},[3860],{"type":34,"value":281},{"type":29,"tag":88,"props":3862,"children":3863},{"style":298},[3864],{"type":34,"value":2498},{"type":29,"tag":88,"props":3866,"children":3867},{"style":122},[3868],{"type":34,"value":306},{"type":29,"tag":88,"props":3870,"children":3871},{"style":122},[3872],{"type":34,"value":125},{"type":29,"tag":88,"props":3874,"children":3876},{"class":90,"line":3875},73,[3877,3881],{"type":29,"tag":88,"props":3878,"children":3879},{"style":105},[3880],{"type":34,"value":415},{"type":29,"tag":88,"props":3882,"children":3883},{"style":157},[3884],{"type":34,"value":3885}," shouldSucceed\n",{"type":29,"tag":88,"props":3887,"children":3889},{"class":90,"line":3888},74,[3890,3895,3899,3903,3908,3912,3917],{"type":29,"tag":88,"props":3891,"children":3892},{"style":105},[3893],{"type":34,"value":3894},"            ?",{"type":29,"tag":88,"props":3896,"children":3897},{"style":157},[3898],{"type":34,"value":3824},{"type":29,"tag":88,"props":3900,"children":3901},{"style":122},[3902],{"type":34,"value":338},{"type":29,"tag":88,"props":3904,"children":3905},{"style":174},[3906],{"type":34,"value":3907},"success",{"type":29,"tag":88,"props":3909,"children":3910},{"style":122},[3911],{"type":34,"value":181},{"type":29,"tag":88,"props":3913,"children":3914},{"style":184},[3915],{"type":34,"value":3916},"\"txn-456\"",{"type":29,"tag":88,"props":3918,"children":3919},{"style":122},[3920],{"type":34,"value":3078},{"type":29,"tag":88,"props":3922,"children":3924},{"class":90,"line":3923},75,[3925,3930,3934,3938,3943,3947,3952],{"type":29,"tag":88,"props":3926,"children":3927},{"style":105},[3928],{"type":34,"value":3929},"            :",{"type":29,"tag":88,"props":3931,"children":3932},{"style":157},[3933],{"type":34,"value":3824},{"type":29,"tag":88,"props":3935,"children":3936},{"style":122},[3937],{"type":34,"value":338},{"type":29,"tag":88,"props":3939,"children":3940},{"style":174},[3941],{"type":34,"value":3942},"failure",{"type":29,"tag":88,"props":3944,"children":3945},{"style":122},[3946],{"type":34,"value":181},{"type":29,"tag":88,"props":3948,"children":3949},{"style":184},[3950],{"type":34,"value":3951},"\"CARD_DECLINED\"",{"type":29,"tag":88,"props":3953,"children":3954},{"style":122},[3955],{"type":34,"value":357},{"type":29,"tag":88,"props":3957,"children":3959},{"class":90,"line":3958},76,[3960],{"type":29,"tag":88,"props":3961,"children":3962},{"style":122},[3963],{"type":34,"value":433},{"type":29,"tag":88,"props":3965,"children":3967},{"class":90,"line":3966},77,[3968],{"type":29,"tag":88,"props":3969,"children":3970},{"style":122},[3971],{"type":34,"value":442},{"type":29,"tag":88,"props":3973,"children":3975},{"class":90,"line":3974},78,[3976],{"type":29,"tag":88,"props":3977,"children":3978},{"emptyLinePlaceholder":13},[3979],{"type":34,"value":134},{"type":29,"tag":88,"props":3981,"children":3983},{"class":90,"line":3982},79,[3984],{"type":29,"tag":88,"props":3985,"children":3986},{"style":95},[3987],{"type":34,"value":3988},"\u002F\u002F Test JUnit 5 - s'exécute en millisecondes, sans infra\n",{"type":29,"tag":88,"props":3990,"children":3992},{"class":90,"line":3991},80,[3993,3997,4002],{"type":29,"tag":88,"props":3994,"children":3995},{"style":105},[3996],{"type":34,"value":1225},{"type":29,"tag":88,"props":3998,"children":3999},{"style":116},[4000],{"type":34,"value":4001}," OrderServiceTest",{"type":29,"tag":88,"props":4003,"children":4004},{"style":122},[4005],{"type":34,"value":125},{"type":29,"tag":88,"props":4007,"children":4009},{"class":90,"line":4008},81,[4010],{"type":29,"tag":88,"props":4011,"children":4012},{"emptyLinePlaceholder":13},[4013],{"type":34,"value":134},{"type":29,"tag":88,"props":4015,"children":4017},{"class":90,"line":4016},82,[4018,4022],{"type":29,"tag":88,"props":4019,"children":4020},{"style":1974},[4021],{"type":34,"value":3302},{"type":29,"tag":88,"props":4023,"children":4024},{"style":1980},[4025],{"type":34,"value":1983},{"type":29,"tag":88,"props":4027,"children":4029},{"class":90,"line":4028},83,[4030,4034,4039,4043],{"type":29,"tag":88,"props":4031,"children":4032},{"style":105},[4033],{"type":34,"value":681},{"type":29,"tag":88,"props":4035,"children":4036},{"style":174},[4037],{"type":34,"value":4038}," shouldCreateOrderWithSuccessfulPayment",{"type":29,"tag":88,"props":4040,"children":4041},{"style":122},[4042],{"type":34,"value":1470},{"type":29,"tag":88,"props":4044,"children":4045},{"style":122},[4046],{"type":34,"value":125},{"type":29,"tag":88,"props":4048,"children":4050},{"class":90,"line":4049},84,[4051,4056,4060,4064,4068,4072],{"type":29,"tag":88,"props":4052,"children":4053},{"style":151},[4054],{"type":34,"value":4055},"        OrderRepository",{"type":29,"tag":88,"props":4057,"children":4058},{"style":157},[4059],{"type":34,"value":1488},{"type":29,"tag":88,"props":4061,"children":4062},{"style":163},[4063],{"type":34,"value":166},{"type":29,"tag":88,"props":4065,"children":4066},{"style":105},[4067],{"type":34,"value":171},{"type":29,"tag":88,"props":4069,"children":4070},{"style":174},[4071],{"type":34,"value":1651},{"type":29,"tag":88,"props":4073,"children":4074},{"style":122},[4075],{"type":34,"value":1810},{"type":29,"tag":88,"props":4077,"children":4079},{"class":90,"line":4078},85,[4080,4085,4090,4094,4098,4102,4106,4111],{"type":29,"tag":88,"props":4081,"children":4082},{"style":151},[4083],{"type":34,"value":4084},"        PaymentGateway",{"type":29,"tag":88,"props":4086,"children":4087},{"style":157},[4088],{"type":34,"value":4089}," payment ",{"type":29,"tag":88,"props":4091,"children":4092},{"style":163},[4093],{"type":34,"value":166},{"type":29,"tag":88,"props":4095,"children":4096},{"style":105},[4097],{"type":34,"value":171},{"type":29,"tag":88,"props":4099,"children":4100},{"style":174},[4101],{"type":34,"value":3671},{"type":29,"tag":88,"props":4103,"children":4104},{"style":122},[4105],{"type":34,"value":181},{"type":29,"tag":88,"props":4107,"children":4108},{"style":873},[4109],{"type":34,"value":4110},"true",{"type":29,"tag":88,"props":4112,"children":4113},{"style":122},[4114],{"type":34,"value":357},{"type":29,"tag":88,"props":4116,"children":4118},{"class":90,"line":4117},86,[4119,4124,4128,4132,4136,4140,4144,4148,4152,4156],{"type":29,"tag":88,"props":4120,"children":4121},{"style":151},[4122],{"type":34,"value":4123},"        OrderService",{"type":29,"tag":88,"props":4125,"children":4126},{"style":157},[4127],{"type":34,"value":2074},{"type":29,"tag":88,"props":4129,"children":4130},{"style":163},[4131],{"type":34,"value":166},{"type":29,"tag":88,"props":4133,"children":4134},{"style":105},[4135],{"type":34,"value":171},{"type":29,"tag":88,"props":4137,"children":4138},{"style":174},[4139],{"type":34,"value":119},{"type":29,"tag":88,"props":4141,"children":4142},{"style":122},[4143],{"type":34,"value":181},{"type":29,"tag":88,"props":4145,"children":4146},{"style":157},[4147],{"type":34,"value":1596},{"type":29,"tag":88,"props":4149,"children":4150},{"style":122},[4151],{"type":34,"value":192},{"type":29,"tag":88,"props":4153,"children":4154},{"style":157},[4155],{"type":34,"value":2605},{"type":29,"tag":88,"props":4157,"children":4158},{"style":122},[4159],{"type":34,"value":357},{"type":29,"tag":88,"props":4161,"children":4163},{"class":90,"line":4162},87,[4164],{"type":29,"tag":88,"props":4165,"children":4166},{"emptyLinePlaceholder":13},[4167],{"type":34,"value":134},{"type":29,"tag":88,"props":4169,"children":4171},{"class":90,"line":4170},88,[4172,4177,4182,4186,4190,4194,4199],{"type":29,"tag":88,"props":4173,"children":4174},{"style":151},[4175],{"type":34,"value":4176},"        Order",{"type":29,"tag":88,"props":4178,"children":4179},{"style":157},[4180],{"type":34,"value":4181}," order ",{"type":29,"tag":88,"props":4183,"children":4184},{"style":163},[4185],{"type":34,"value":166},{"type":29,"tag":88,"props":4187,"children":4188},{"style":157},[4189],{"type":34,"value":2133},{"type":29,"tag":88,"props":4191,"children":4192},{"style":122},[4193],{"type":34,"value":338},{"type":29,"tag":88,"props":4195,"children":4196},{"style":174},[4197],{"type":34,"value":4198},"createPaidOrder",{"type":29,"tag":88,"props":4200,"children":4201},{"style":122},[4202],{"type":34,"value":2800},{"type":29,"tag":88,"props":4204,"children":4206},{"class":90,"line":4205},89,[4207,4212,4216,4220,4224,4229,4233,4238,4243,4248,4252,4257],{"type":29,"tag":88,"props":4208,"children":4209},{"style":105},[4210],{"type":34,"value":4211},"            new",{"type":29,"tag":88,"props":4213,"children":4214},{"style":174},[4215],{"type":34,"value":1696},{"type":29,"tag":88,"props":4217,"children":4218},{"style":122},[4219],{"type":34,"value":181},{"type":29,"tag":88,"props":4221,"children":4222},{"style":105},[4223],{"type":34,"value":2151},{"type":29,"tag":88,"props":4225,"children":4226},{"style":174},[4227],{"type":34,"value":4228}," BigDecimal",{"type":29,"tag":88,"props":4230,"children":4231},{"style":122},[4232],{"type":34,"value":181},{"type":29,"tag":88,"props":4234,"children":4235},{"style":184},[4236],{"type":34,"value":4237},"\"1000\"",{"type":29,"tag":88,"props":4239,"children":4240},{"style":122},[4241],{"type":34,"value":4242},"),",{"type":29,"tag":88,"props":4244,"children":4245},{"style":184},[4246],{"type":34,"value":4247}," \"EUR\"",{"type":29,"tag":88,"props":4249,"children":4250},{"style":122},[4251],{"type":34,"value":192},{"type":29,"tag":88,"props":4253,"children":4254},{"style":184},[4255],{"type":34,"value":4256}," \"pm-123\"",{"type":29,"tag":88,"props":4258,"children":4259},{"style":122},[4260],{"type":34,"value":3078},{"type":29,"tag":88,"props":4262,"children":4264},{"class":90,"line":4263},90,[4265],{"type":29,"tag":88,"props":4266,"children":4267},{"style":122},[4268],{"type":34,"value":2871},{"type":29,"tag":88,"props":4270,"children":4272},{"class":90,"line":4271},91,[4273],{"type":29,"tag":88,"props":4274,"children":4275},{"emptyLinePlaceholder":13},[4276],{"type":34,"value":134},{"type":29,"tag":88,"props":4278,"children":4280},{"class":90,"line":4279},92,[4281,4286,4290,4294,4298,4302,4306,4311,4315,4319],{"type":29,"tag":88,"props":4282,"children":4283},{"style":174},[4284],{"type":34,"value":4285},"        assertEquals",{"type":29,"tag":88,"props":4287,"children":4288},{"style":122},[4289],{"type":34,"value":181},{"type":29,"tag":88,"props":4291,"children":4292},{"style":157},[4293],{"type":34,"value":3064},{"type":29,"tag":88,"props":4295,"children":4296},{"style":122},[4297],{"type":34,"value":338},{"type":29,"tag":88,"props":4299,"children":4300},{"style":157},[4301],{"type":34,"value":3073},{"type":29,"tag":88,"props":4303,"children":4304},{"style":122},[4305],{"type":34,"value":192},{"type":29,"tag":88,"props":4307,"children":4308},{"style":157},[4309],{"type":34,"value":4310}," order",{"type":29,"tag":88,"props":4312,"children":4313},{"style":122},[4314],{"type":34,"value":338},{"type":29,"tag":88,"props":4316,"children":4317},{"style":174},[4318],{"type":34,"value":3629},{"type":29,"tag":88,"props":4320,"children":4321},{"style":122},[4322],{"type":34,"value":2958},{"type":29,"tag":88,"props":4324,"children":4326},{"class":90,"line":4325},93,[4327],{"type":29,"tag":88,"props":4328,"children":4329},{"style":122},[4330],{"type":34,"value":433},{"type":29,"tag":88,"props":4332,"children":4334},{"class":90,"line":4333},94,[4335],{"type":29,"tag":88,"props":4336,"children":4337},{"emptyLinePlaceholder":13},[4338],{"type":34,"value":134},{"type":29,"tag":88,"props":4340,"children":4342},{"class":90,"line":4341},95,[4343,4347],{"type":29,"tag":88,"props":4344,"children":4345},{"style":1974},[4346],{"type":34,"value":3302},{"type":29,"tag":88,"props":4348,"children":4349},{"style":1980},[4350],{"type":34,"value":1983},{"type":29,"tag":88,"props":4352,"children":4354},{"class":90,"line":4353},96,[4355,4359,4364,4368],{"type":29,"tag":88,"props":4356,"children":4357},{"style":105},[4358],{"type":34,"value":681},{"type":29,"tag":88,"props":4360,"children":4361},{"style":174},[4362],{"type":34,"value":4363}," shouldThrowWhenPaymentFails",{"type":29,"tag":88,"props":4365,"children":4366},{"style":122},[4367],{"type":34,"value":1470},{"type":29,"tag":88,"props":4369,"children":4370},{"style":122},[4371],{"type":34,"value":125},{"type":29,"tag":88,"props":4373,"children":4375},{"class":90,"line":4374},97,[4376,4380,4384,4388,4392,4396],{"type":29,"tag":88,"props":4377,"children":4378},{"style":151},[4379],{"type":34,"value":4123},{"type":29,"tag":88,"props":4381,"children":4382},{"style":157},[4383],{"type":34,"value":2074},{"type":29,"tag":88,"props":4385,"children":4386},{"style":163},[4387],{"type":34,"value":166},{"type":29,"tag":88,"props":4389,"children":4390},{"style":105},[4391],{"type":34,"value":171},{"type":29,"tag":88,"props":4393,"children":4394},{"style":174},[4395],{"type":34,"value":119},{"type":29,"tag":88,"props":4397,"children":4398},{"style":122},[4399],{"type":34,"value":2800},{"type":29,"tag":88,"props":4401,"children":4403},{"class":90,"line":4402},98,[4404,4408,4412],{"type":29,"tag":88,"props":4405,"children":4406},{"style":105},[4407],{"type":34,"value":4211},{"type":29,"tag":88,"props":4409,"children":4410},{"style":174},[4411],{"type":34,"value":1651},{"type":29,"tag":88,"props":4413,"children":4414},{"style":122},[4415],{"type":34,"value":2822},{"type":29,"tag":88,"props":4417,"children":4419},{"class":90,"line":4418},99,[4420,4424,4428,4432,4437],{"type":29,"tag":88,"props":4421,"children":4422},{"style":105},[4423],{"type":34,"value":4211},{"type":29,"tag":88,"props":4425,"children":4426},{"style":174},[4427],{"type":34,"value":3671},{"type":29,"tag":88,"props":4429,"children":4430},{"style":122},[4431],{"type":34,"value":181},{"type":29,"tag":88,"props":4433,"children":4434},{"style":873},[4435],{"type":34,"value":4436},"false",{"type":29,"tag":88,"props":4438,"children":4439},{"style":122},[4440],{"type":34,"value":3078},{"type":29,"tag":88,"props":4442,"children":4444},{"class":90,"line":4443},100,[4445],{"type":29,"tag":88,"props":4446,"children":4447},{"style":122},[4448],{"type":34,"value":2871},{"type":29,"tag":88,"props":4450,"children":4452},{"class":90,"line":4451},101,[4453],{"type":29,"tag":88,"props":4454,"children":4455},{"emptyLinePlaceholder":13},[4456],{"type":34,"value":134},{"type":29,"tag":88,"props":4458,"children":4460},{"class":90,"line":4459},102,[4461,4466,4470,4475,4479,4483,4487,4492],{"type":29,"tag":88,"props":4462,"children":4463},{"style":174},[4464],{"type":34,"value":4465},"        assertThrows",{"type":29,"tag":88,"props":4467,"children":4468},{"style":122},[4469],{"type":34,"value":181},{"type":29,"tag":88,"props":4471,"children":4472},{"style":157},[4473],{"type":34,"value":4474},"PaymentFailedException",{"type":29,"tag":88,"props":4476,"children":4477},{"style":122},[4478],{"type":34,"value":338},{"type":29,"tag":88,"props":4480,"children":4481},{"style":157},[4482],{"type":34,"value":1225},{"type":29,"tag":88,"props":4484,"children":4485},{"style":122},[4486],{"type":34,"value":192},{"type":29,"tag":88,"props":4488,"children":4489},{"style":122},[4490],{"type":34,"value":4491}," ()",{"type":29,"tag":88,"props":4493,"children":4494},{"style":105},[4495],{"type":34,"value":4496}," ->\n",{"type":29,"tag":88,"props":4498,"children":4500},{"class":90,"line":4499},103,[4501,4506,4510,4514,4518,4522,4526,4530,4534,4538,4542,4546,4550,4554,4558,4562],{"type":29,"tag":88,"props":4502,"children":4503},{"style":157},[4504],{"type":34,"value":4505},"            service",{"type":29,"tag":88,"props":4507,"children":4508},{"style":122},[4509],{"type":34,"value":338},{"type":29,"tag":88,"props":4511,"children":4512},{"style":174},[4513],{"type":34,"value":4198},{"type":29,"tag":88,"props":4515,"children":4516},{"style":122},[4517],{"type":34,"value":181},{"type":29,"tag":88,"props":4519,"children":4520},{"style":105},[4521],{"type":34,"value":2151},{"type":29,"tag":88,"props":4523,"children":4524},{"style":174},[4525],{"type":34,"value":1696},{"type":29,"tag":88,"props":4527,"children":4528},{"style":122},[4529],{"type":34,"value":181},{"type":29,"tag":88,"props":4531,"children":4532},{"style":105},[4533],{"type":34,"value":2151},{"type":29,"tag":88,"props":4535,"children":4536},{"style":174},[4537],{"type":34,"value":4228},{"type":29,"tag":88,"props":4539,"children":4540},{"style":122},[4541],{"type":34,"value":181},{"type":29,"tag":88,"props":4543,"children":4544},{"style":184},[4545],{"type":34,"value":4237},{"type":29,"tag":88,"props":4547,"children":4548},{"style":122},[4549],{"type":34,"value":4242},{"type":29,"tag":88,"props":4551,"children":4552},{"style":184},[4553],{"type":34,"value":4247},{"type":29,"tag":88,"props":4555,"children":4556},{"style":122},[4557],{"type":34,"value":192},{"type":29,"tag":88,"props":4559,"children":4560},{"style":184},[4561],{"type":34,"value":4256},{"type":29,"tag":88,"props":4563,"children":4564},{"style":122},[4565],{"type":34,"value":3568},{"type":29,"tag":88,"props":4567,"children":4569},{"class":90,"line":4568},104,[4570],{"type":29,"tag":88,"props":4571,"children":4572},{"style":122},[4573],{"type":34,"value":2871},{"type":29,"tag":88,"props":4575,"children":4577},{"class":90,"line":4576},105,[4578],{"type":29,"tag":88,"props":4579,"children":4580},{"style":122},[4581],{"type":34,"value":433},{"type":29,"tag":88,"props":4583,"children":4585},{"class":90,"line":4584},106,[4586],{"type":29,"tag":88,"props":4587,"children":4588},{"style":122},[4589],{"type":34,"value":442},{"type":29,"tag":30,"props":4591,"children":4592},{},[4593,4598,4600,4606,4608,4614,4615,4621],{"type":29,"tag":447,"props":4594,"children":4595},{},[4596],{"type":34,"value":4597},"L'avantage Java\u002FSpring :",{"type":34,"value":4599}," les interfaces sont des contrats vérifiés à la compilation. Si un adapter ne respecte pas le port, ",{"type":29,"tag":84,"props":4601,"children":4603},{"className":4602},[],[4604],{"type":34,"value":4605},"javac",{"type":34,"value":4607}," rejette le code avant l'exécution. Spring injecte automatiquement l'adapter correct (",{"type":29,"tag":84,"props":4609,"children":4611},{"className":4610},[],[4612],{"type":34,"value":4613},"@Repository",{"type":34,"value":544},{"type":29,"tag":84,"props":4616,"children":4618},{"className":4617},[],[4619],{"type":34,"value":4620},"@Component",{"type":34,"value":4622},") en production : le service métier ne sait pas quelle implémentation tourne.",{"type":29,"tag":47,"props":4624,"children":4625},{},[],{"type":29,"tag":51,"props":4627,"children":4629},{"id":4628},"exemple-3-java-le-dip-avec-spring",[4630],{"type":34,"value":4631},"Exemple 3 : Java, le DIP avec Spring",{"type":29,"tag":77,"props":4633,"children":4635},{"code":4634,"language":80,"meta":8,"className":81,"style":8},"\u002F\u002F L'abstraction\npublic interface NotificationService {\n    void sendOrderConfirmation(String userId, String orderId);\n    void sendShippingUpdate(String userId, String orderId, String trackingCode);\n}\n\n\u002F\u002F Le module de haut niveau (service métier)\n@Service\npublic class OrderFulfillmentService {\n\n    private final OrderRepository orderRepository;\n    private final NotificationService notificationService;\n\n    public OrderFulfillmentService(\n            OrderRepository orderRepository,\n            NotificationService notificationService) {\n        this.orderRepository = orderRepository;\n        this.notificationService = notificationService;\n    }\n\n    public void fulfillOrder(String orderId) {\n        Order order = orderRepository.findById(orderId)\n            .orElseThrow(() -> new OrderNotFoundException(orderId));\n\n        order.setStatus(OrderStatus.FULFILLING);\n        orderRepository.save(order);\n\n        notificationService.sendOrderConfirmation(order.getUserId(), orderId);\n    }\n}\n\n\u002F\u002F Implémentation de test\n@Service\n@Profile(\"test\")\npublic class MockNotificationService implements NotificationService {\n\n    private final List\u003CString> sentNotifications = new ArrayList\u003C>();\n\n    @Override\n    public void sendOrderConfirmation(String userId, String orderId) {\n        sentNotifications.add(\"confirmation:\" + userId + \":\" + orderId);\n    }\n}\n",[4636],{"type":29,"tag":84,"props":4637,"children":4638},{"__ignoreMap":8},[4639,4647,4667,4708,4761,4768,4775,4783,4794,4814,4821,4845,4869,4876,4891,4908,4928,4956,4984,4991,4998,5034,5073,5113,5120,5158,5187,5194,5240,5247,5254,5261,5269,5280,5305,5333,5340,5390,5397,5408,5455,5513,5520],{"type":29,"tag":88,"props":4640,"children":4641},{"class":90,"line":91},[4642],{"type":29,"tag":88,"props":4643,"children":4644},{"style":95},[4645],{"type":34,"value":4646},"\u002F\u002F L'abstraction\n",{"type":29,"tag":88,"props":4648,"children":4649},{"class":90,"line":101},[4650,4654,4658,4663],{"type":29,"tag":88,"props":4651,"children":4652},{"style":105},[4653],{"type":34,"value":108},{"type":29,"tag":88,"props":4655,"children":4656},{"style":105},[4657],{"type":34,"value":601},{"type":29,"tag":88,"props":4659,"children":4660},{"style":116},[4661],{"type":34,"value":4662}," NotificationService",{"type":29,"tag":88,"props":4664,"children":4665},{"style":122},[4666],{"type":34,"value":125},{"type":29,"tag":88,"props":4668,"children":4669},{"class":90,"line":128},[4670,4674,4679,4683,4687,4692,4696,4700,4704],{"type":29,"tag":88,"props":4671,"children":4672},{"style":105},[4673],{"type":34,"value":681},{"type":29,"tag":88,"props":4675,"children":4676},{"style":174},[4677],{"type":34,"value":4678}," sendOrderConfirmation",{"type":29,"tag":88,"props":4680,"children":4681},{"style":122},[4682],{"type":34,"value":181},{"type":29,"tag":88,"props":4684,"children":4685},{"style":151},[4686],{"type":34,"value":695},{"type":29,"tag":88,"props":4688,"children":4689},{"style":298},[4690],{"type":34,"value":4691}," userId",{"type":29,"tag":88,"props":4693,"children":4694},{"style":122},[4695],{"type":34,"value":192},{"type":29,"tag":88,"props":4697,"children":4698},{"style":151},[4699],{"type":34,"value":281},{"type":29,"tag":88,"props":4701,"children":4702},{"style":298},[4703],{"type":34,"value":402},{"type":29,"tag":88,"props":4705,"children":4706},{"style":122},[4707],{"type":34,"value":357},{"type":29,"tag":88,"props":4709,"children":4710},{"class":90,"line":137},[4711,4715,4720,4724,4728,4732,4736,4740,4744,4748,4752,4757],{"type":29,"tag":88,"props":4712,"children":4713},{"style":105},[4714],{"type":34,"value":681},{"type":29,"tag":88,"props":4716,"children":4717},{"style":174},[4718],{"type":34,"value":4719}," sendShippingUpdate",{"type":29,"tag":88,"props":4721,"children":4722},{"style":122},[4723],{"type":34,"value":181},{"type":29,"tag":88,"props":4725,"children":4726},{"style":151},[4727],{"type":34,"value":695},{"type":29,"tag":88,"props":4729,"children":4730},{"style":298},[4731],{"type":34,"value":4691},{"type":29,"tag":88,"props":4733,"children":4734},{"style":122},[4735],{"type":34,"value":192},{"type":29,"tag":88,"props":4737,"children":4738},{"style":151},[4739],{"type":34,"value":281},{"type":29,"tag":88,"props":4741,"children":4742},{"style":298},[4743],{"type":34,"value":402},{"type":29,"tag":88,"props":4745,"children":4746},{"style":122},[4747],{"type":34,"value":192},{"type":29,"tag":88,"props":4749,"children":4750},{"style":151},[4751],{"type":34,"value":281},{"type":29,"tag":88,"props":4753,"children":4754},{"style":298},[4755],{"type":34,"value":4756}," trackingCode",{"type":29,"tag":88,"props":4758,"children":4759},{"style":122},[4760],{"type":34,"value":357},{"type":29,"tag":88,"props":4762,"children":4763},{"class":90,"line":211},[4764],{"type":29,"tag":88,"props":4765,"children":4766},{"style":122},[4767],{"type":34,"value":442},{"type":29,"tag":88,"props":4769,"children":4770},{"class":90,"line":262},[4771],{"type":29,"tag":88,"props":4772,"children":4773},{"emptyLinePlaceholder":13},[4774],{"type":34,"value":134},{"type":29,"tag":88,"props":4776,"children":4777},{"class":90,"line":270},[4778],{"type":29,"tag":88,"props":4779,"children":4780},{"style":95},[4781],{"type":34,"value":4782},"\u002F\u002F Le module de haut niveau (service métier)\n",{"type":29,"tag":88,"props":4784,"children":4785},{"class":90,"line":313},[4786,4790],{"type":29,"tag":88,"props":4787,"children":4788},{"style":1974},[4789],{"type":34,"value":1977},{"type":29,"tag":88,"props":4791,"children":4792},{"style":1980},[4793],{"type":34,"value":2536},{"type":29,"tag":88,"props":4795,"children":4796},{"class":90,"line":360},[4797,4801,4805,4810],{"type":29,"tag":88,"props":4798,"children":4799},{"style":105},[4800],{"type":34,"value":108},{"type":29,"tag":88,"props":4802,"children":4803},{"style":105},[4804],{"type":34,"value":113},{"type":29,"tag":88,"props":4806,"children":4807},{"style":116},[4808],{"type":34,"value":4809}," OrderFulfillmentService",{"type":29,"tag":88,"props":4811,"children":4812},{"style":122},[4813],{"type":34,"value":125},{"type":29,"tag":88,"props":4815,"children":4816},{"class":90,"line":409},[4817],{"type":29,"tag":88,"props":4818,"children":4819},{"emptyLinePlaceholder":13},[4820],{"type":34,"value":134},{"type":29,"tag":88,"props":4822,"children":4823},{"class":90,"line":427},[4824,4828,4832,4836,4841],{"type":29,"tag":88,"props":4825,"children":4826},{"style":105},[4827],{"type":34,"value":143},{"type":29,"tag":88,"props":4829,"children":4830},{"style":105},[4831],{"type":34,"value":148},{"type":29,"tag":88,"props":4833,"children":4834},{"style":151},[4835],{"type":34,"value":606},{"type":29,"tag":88,"props":4837,"children":4838},{"style":157},[4839],{"type":34,"value":4840}," orderRepository",{"type":29,"tag":88,"props":4842,"children":4843},{"style":122},[4844],{"type":34,"value":424},{"type":29,"tag":88,"props":4846,"children":4847},{"class":90,"line":436},[4848,4852,4856,4860,4865],{"type":29,"tag":88,"props":4849,"children":4850},{"style":105},[4851],{"type":34,"value":143},{"type":29,"tag":88,"props":4853,"children":4854},{"style":105},[4855],{"type":34,"value":148},{"type":29,"tag":88,"props":4857,"children":4858},{"style":151},[4859],{"type":34,"value":4662},{"type":29,"tag":88,"props":4861,"children":4862},{"style":157},[4863],{"type":34,"value":4864}," notificationService",{"type":29,"tag":88,"props":4866,"children":4867},{"style":122},[4868],{"type":34,"value":424},{"type":29,"tag":88,"props":4870,"children":4871},{"class":90,"line":767},[4872],{"type":29,"tag":88,"props":4873,"children":4874},{"emptyLinePlaceholder":13},[4875],{"type":34,"value":134},{"type":29,"tag":88,"props":4877,"children":4878},{"class":90,"line":792},[4879,4883,4887],{"type":29,"tag":88,"props":4880,"children":4881},{"style":105},[4882],{"type":34,"value":276},{"type":29,"tag":88,"props":4884,"children":4885},{"style":174},[4886],{"type":34,"value":4809},{"type":29,"tag":88,"props":4888,"children":4889},{"style":122},[4890],{"type":34,"value":2800},{"type":29,"tag":88,"props":4892,"children":4893},{"class":90,"line":817},[4894,4899,4903],{"type":29,"tag":88,"props":4895,"children":4896},{"style":151},[4897],{"type":34,"value":4898},"            OrderRepository",{"type":29,"tag":88,"props":4900,"children":4901},{"style":298},[4902],{"type":34,"value":4840},{"type":29,"tag":88,"props":4904,"children":4905},{"style":122},[4906],{"type":34,"value":4907},",\n",{"type":29,"tag":88,"props":4909,"children":4910},{"class":90,"line":825},[4911,4916,4920,4924],{"type":29,"tag":88,"props":4912,"children":4913},{"style":151},[4914],{"type":34,"value":4915},"            NotificationService",{"type":29,"tag":88,"props":4917,"children":4918},{"style":298},[4919],{"type":34,"value":4864},{"type":29,"tag":88,"props":4921,"children":4922},{"style":122},[4923],{"type":34,"value":306},{"type":29,"tag":88,"props":4925,"children":4926},{"style":122},[4927],{"type":34,"value":125},{"type":29,"tag":88,"props":4929,"children":4930},{"class":90,"line":869},[4931,4935,4939,4944,4948,4952],{"type":29,"tag":88,"props":4932,"children":4933},{"style":873},[4934],{"type":34,"value":876},{"type":29,"tag":88,"props":4936,"children":4937},{"style":122},[4938],{"type":34,"value":338},{"type":29,"tag":88,"props":4940,"children":4941},{"style":157},[4942],{"type":34,"value":4943},"orderRepository ",{"type":29,"tag":88,"props":4945,"children":4946},{"style":163},[4947],{"type":34,"value":166},{"type":29,"tag":88,"props":4949,"children":4950},{"style":157},[4951],{"type":34,"value":4840},{"type":29,"tag":88,"props":4953,"children":4954},{"style":122},[4955],{"type":34,"value":424},{"type":29,"tag":88,"props":4957,"children":4958},{"class":90,"line":900},[4959,4963,4967,4972,4976,4980],{"type":29,"tag":88,"props":4960,"children":4961},{"style":873},[4962],{"type":34,"value":876},{"type":29,"tag":88,"props":4964,"children":4965},{"style":122},[4966],{"type":34,"value":338},{"type":29,"tag":88,"props":4968,"children":4969},{"style":157},[4970],{"type":34,"value":4971},"notificationService ",{"type":29,"tag":88,"props":4973,"children":4974},{"style":163},[4975],{"type":34,"value":166},{"type":29,"tag":88,"props":4977,"children":4978},{"style":157},[4979],{"type":34,"value":4864},{"type":29,"tag":88,"props":4981,"children":4982},{"style":122},[4983],{"type":34,"value":424},{"type":29,"tag":88,"props":4985,"children":4986},{"class":90,"line":929},[4987],{"type":29,"tag":88,"props":4988,"children":4989},{"style":122},[4990],{"type":34,"value":433},{"type":29,"tag":88,"props":4992,"children":4993},{"class":90,"line":937},[4994],{"type":29,"tag":88,"props":4995,"children":4996},{"emptyLinePlaceholder":13},[4997],{"type":34,"value":134},{"type":29,"tag":88,"props":4999,"children":5000},{"class":90,"line":945},[5001,5005,5009,5014,5018,5022,5026,5030],{"type":29,"tag":88,"props":5002,"children":5003},{"style":105},[5004],{"type":34,"value":276},{"type":29,"tag":88,"props":5006,"children":5007},{"style":105},[5008],{"type":34,"value":1303},{"type":29,"tag":88,"props":5010,"children":5011},{"style":174},[5012],{"type":34,"value":5013}," fulfillOrder",{"type":29,"tag":88,"props":5015,"children":5016},{"style":122},[5017],{"type":34,"value":181},{"type":29,"tag":88,"props":5019,"children":5020},{"style":151},[5021],{"type":34,"value":695},{"type":29,"tag":88,"props":5023,"children":5024},{"style":298},[5025],{"type":34,"value":402},{"type":29,"tag":88,"props":5027,"children":5028},{"style":122},[5029],{"type":34,"value":306},{"type":29,"tag":88,"props":5031,"children":5032},{"style":122},[5033],{"type":34,"value":125},{"type":29,"tag":88,"props":5035,"children":5036},{"class":90,"line":981},[5037,5041,5045,5049,5053,5057,5061,5065,5069],{"type":29,"tag":88,"props":5038,"children":5039},{"style":151},[5040],{"type":34,"value":4176},{"type":29,"tag":88,"props":5042,"children":5043},{"style":157},[5044],{"type":34,"value":4181},{"type":29,"tag":88,"props":5046,"children":5047},{"style":163},[5048],{"type":34,"value":166},{"type":29,"tag":88,"props":5050,"children":5051},{"style":157},[5052],{"type":34,"value":4840},{"type":29,"tag":88,"props":5054,"children":5055},{"style":122},[5056],{"type":34,"value":338},{"type":29,"tag":88,"props":5058,"children":5059},{"style":174},[5060],{"type":34,"value":3112},{"type":29,"tag":88,"props":5062,"children":5063},{"style":122},[5064],{"type":34,"value":181},{"type":29,"tag":88,"props":5066,"children":5067},{"style":157},[5068],{"type":34,"value":1836},{"type":29,"tag":88,"props":5070,"children":5071},{"style":122},[5072],{"type":34,"value":3078},{"type":29,"tag":88,"props":5074,"children":5075},{"class":90,"line":1021},[5076,5080,5084,5088,5092,5096,5101,5105,5109],{"type":29,"tag":88,"props":5077,"children":5078},{"style":122},[5079],{"type":34,"value":3132},{"type":29,"tag":88,"props":5081,"children":5082},{"style":174},[5083],{"type":34,"value":3137},{"type":29,"tag":88,"props":5085,"children":5086},{"style":122},[5087],{"type":34,"value":3142},{"type":29,"tag":88,"props":5089,"children":5090},{"style":105},[5091],{"type":34,"value":3147},{"type":29,"tag":88,"props":5093,"children":5094},{"style":105},[5095],{"type":34,"value":171},{"type":29,"tag":88,"props":5097,"children":5098},{"style":174},[5099],{"type":34,"value":5100}," OrderNotFoundException",{"type":29,"tag":88,"props":5102,"children":5103},{"style":122},[5104],{"type":34,"value":181},{"type":29,"tag":88,"props":5106,"children":5107},{"style":157},[5108],{"type":34,"value":1836},{"type":29,"tag":88,"props":5110,"children":5111},{"style":122},[5112],{"type":34,"value":1415},{"type":29,"tag":88,"props":5114,"children":5115},{"class":90,"line":1066},[5116],{"type":29,"tag":88,"props":5117,"children":5118},{"emptyLinePlaceholder":13},[5119],{"type":34,"value":134},{"type":29,"tag":88,"props":5121,"children":5122},{"class":90,"line":1082},[5123,5128,5132,5137,5141,5145,5149,5154],{"type":29,"tag":88,"props":5124,"children":5125},{"style":157},[5126],{"type":34,"value":5127},"        order",{"type":29,"tag":88,"props":5129,"children":5130},{"style":122},[5131],{"type":34,"value":338},{"type":29,"tag":88,"props":5133,"children":5134},{"style":174},[5135],{"type":34,"value":5136},"setStatus",{"type":29,"tag":88,"props":5138,"children":5139},{"style":122},[5140],{"type":34,"value":181},{"type":29,"tag":88,"props":5142,"children":5143},{"style":157},[5144],{"type":34,"value":3064},{"type":29,"tag":88,"props":5146,"children":5147},{"style":122},[5148],{"type":34,"value":338},{"type":29,"tag":88,"props":5150,"children":5151},{"style":157},[5152],{"type":34,"value":5153},"FULFILLING",{"type":29,"tag":88,"props":5155,"children":5156},{"style":122},[5157],{"type":34,"value":357},{"type":29,"tag":88,"props":5159,"children":5160},{"class":90,"line":1090},[5161,5166,5170,5174,5178,5183],{"type":29,"tag":88,"props":5162,"children":5163},{"style":157},[5164],{"type":34,"value":5165},"        orderRepository",{"type":29,"tag":88,"props":5167,"children":5168},{"style":122},[5169],{"type":34,"value":338},{"type":29,"tag":88,"props":5171,"children":5172},{"style":174},[5173],{"type":34,"value":343},{"type":29,"tag":88,"props":5175,"children":5176},{"style":122},[5177],{"type":34,"value":181},{"type":29,"tag":88,"props":5179,"children":5180},{"style":157},[5181],{"type":34,"value":5182},"order",{"type":29,"tag":88,"props":5184,"children":5185},{"style":122},[5186],{"type":34,"value":357},{"type":29,"tag":88,"props":5188,"children":5189},{"class":90,"line":1098},[5190],{"type":29,"tag":88,"props":5191,"children":5192},{"emptyLinePlaceholder":13},[5193],{"type":34,"value":134},{"type":29,"tag":88,"props":5195,"children":5196},{"class":90,"line":1106},[5197,5202,5206,5211,5215,5219,5223,5228,5232,5236],{"type":29,"tag":88,"props":5198,"children":5199},{"style":157},[5200],{"type":34,"value":5201},"        notificationService",{"type":29,"tag":88,"props":5203,"children":5204},{"style":122},[5205],{"type":34,"value":338},{"type":29,"tag":88,"props":5207,"children":5208},{"style":174},[5209],{"type":34,"value":5210},"sendOrderConfirmation",{"type":29,"tag":88,"props":5212,"children":5213},{"style":122},[5214],{"type":34,"value":181},{"type":29,"tag":88,"props":5216,"children":5217},{"style":157},[5218],{"type":34,"value":5182},{"type":29,"tag":88,"props":5220,"children":5221},{"style":122},[5222],{"type":34,"value":338},{"type":29,"tag":88,"props":5224,"children":5225},{"style":174},[5226],{"type":34,"value":5227},"getUserId",{"type":29,"tag":88,"props":5229,"children":5230},{"style":122},[5231],{"type":34,"value":397},{"type":29,"tag":88,"props":5233,"children":5234},{"style":157},[5235],{"type":34,"value":402},{"type":29,"tag":88,"props":5237,"children":5238},{"style":122},[5239],{"type":34,"value":357},{"type":29,"tag":88,"props":5241,"children":5242},{"class":90,"line":1115},[5243],{"type":29,"tag":88,"props":5244,"children":5245},{"style":122},[5246],{"type":34,"value":433},{"type":29,"tag":88,"props":5248,"children":5249},{"class":90,"line":11},[5250],{"type":29,"tag":88,"props":5251,"children":5252},{"style":122},[5253],{"type":34,"value":442},{"type":29,"tag":88,"props":5255,"children":5256},{"class":90,"line":1180},[5257],{"type":29,"tag":88,"props":5258,"children":5259},{"emptyLinePlaceholder":13},[5260],{"type":34,"value":134},{"type":29,"tag":88,"props":5262,"children":5263},{"class":90,"line":1240},[5264],{"type":29,"tag":88,"props":5265,"children":5266},{"style":95},[5267],{"type":34,"value":5268},"\u002F\u002F Implémentation de test\n",{"type":29,"tag":88,"props":5270,"children":5271},{"class":90,"line":1248},[5272,5276],{"type":29,"tag":88,"props":5273,"children":5274},{"style":1974},[5275],{"type":34,"value":1977},{"type":29,"tag":88,"props":5277,"children":5278},{"style":1980},[5279],{"type":34,"value":2536},{"type":29,"tag":88,"props":5281,"children":5282},{"class":90,"line":1256},[5283,5287,5292,5296,5301],{"type":29,"tag":88,"props":5284,"children":5285},{"style":1974},[5286],{"type":34,"value":1977},{"type":29,"tag":88,"props":5288,"children":5289},{"style":1980},[5290],{"type":34,"value":5291},"Profile",{"type":29,"tag":88,"props":5293,"children":5294},{"style":122},[5295],{"type":34,"value":181},{"type":29,"tag":88,"props":5297,"children":5298},{"style":184},[5299],{"type":34,"value":5300},"\"test\"",{"type":29,"tag":88,"props":5302,"children":5303},{"style":122},[5304],{"type":34,"value":3078},{"type":29,"tag":88,"props":5306,"children":5307},{"class":90,"line":1264},[5308,5312,5316,5321,5325,5329],{"type":29,"tag":88,"props":5309,"children":5310},{"style":105},[5311],{"type":34,"value":108},{"type":29,"tag":88,"props":5313,"children":5314},{"style":105},[5315],{"type":34,"value":113},{"type":29,"tag":88,"props":5317,"children":5318},{"style":116},[5319],{"type":34,"value":5320}," MockNotificationService",{"type":29,"tag":88,"props":5322,"children":5323},{"style":105},[5324],{"type":34,"value":1134},{"type":29,"tag":88,"props":5326,"children":5327},{"style":116},[5328],{"type":34,"value":4662},{"type":29,"tag":88,"props":5330,"children":5331},{"style":122},[5332],{"type":34,"value":125},{"type":29,"tag":88,"props":5334,"children":5335},{"class":90,"line":1293},[5336],{"type":29,"tag":88,"props":5337,"children":5338},{"emptyLinePlaceholder":13},[5339],{"type":34,"value":134},{"type":29,"tag":88,"props":5341,"children":5342},{"class":90,"line":1342},[5343,5347,5351,5356,5360,5364,5368,5373,5377,5381,5386],{"type":29,"tag":88,"props":5344,"children":5345},{"style":105},[5346],{"type":34,"value":143},{"type":29,"tag":88,"props":5348,"children":5349},{"style":105},[5350],{"type":34,"value":148},{"type":29,"tag":88,"props":5352,"children":5353},{"style":151},[5354],{"type":34,"value":5355}," List",{"type":29,"tag":88,"props":5357,"children":5358},{"style":122},[5359],{"type":34,"value":1683},{"type":29,"tag":88,"props":5361,"children":5362},{"style":105},[5363],{"type":34,"value":695},{"type":29,"tag":88,"props":5365,"children":5366},{"style":122},[5367],{"type":34,"value":1701},{"type":29,"tag":88,"props":5369,"children":5370},{"style":157},[5371],{"type":34,"value":5372}," sentNotifications ",{"type":29,"tag":88,"props":5374,"children":5375},{"style":163},[5376],{"type":34,"value":166},{"type":29,"tag":88,"props":5378,"children":5379},{"style":105},[5380],{"type":34,"value":171},{"type":29,"tag":88,"props":5382,"children":5383},{"style":151},[5384],{"type":34,"value":5385}," ArrayList",{"type":29,"tag":88,"props":5387,"children":5388},{"style":122},[5389],{"type":34,"value":1724},{"type":29,"tag":88,"props":5391,"children":5392},{"class":90,"line":1418},[5393],{"type":29,"tag":88,"props":5394,"children":5395},{"emptyLinePlaceholder":13},[5396],{"type":34,"value":134},{"type":29,"tag":88,"props":5398,"children":5399},{"class":90,"line":1426},[5400,5404],{"type":29,"tag":88,"props":5401,"children":5402},{"style":1974},[5403],{"type":34,"value":3302},{"type":29,"tag":88,"props":5405,"children":5406},{"style":1980},[5407],{"type":34,"value":3307},{"type":29,"tag":88,"props":5409,"children":5410},{"class":90,"line":1434},[5411,5415,5419,5423,5427,5431,5435,5439,5443,5447,5451],{"type":29,"tag":88,"props":5412,"children":5413},{"style":105},[5414],{"type":34,"value":276},{"type":29,"tag":88,"props":5416,"children":5417},{"style":105},[5418],{"type":34,"value":1303},{"type":29,"tag":88,"props":5420,"children":5421},{"style":174},[5422],{"type":34,"value":4678},{"type":29,"tag":88,"props":5424,"children":5425},{"style":122},[5426],{"type":34,"value":181},{"type":29,"tag":88,"props":5428,"children":5429},{"style":151},[5430],{"type":34,"value":695},{"type":29,"tag":88,"props":5432,"children":5433},{"style":298},[5434],{"type":34,"value":4691},{"type":29,"tag":88,"props":5436,"children":5437},{"style":122},[5438],{"type":34,"value":192},{"type":29,"tag":88,"props":5440,"children":5441},{"style":151},[5442],{"type":34,"value":281},{"type":29,"tag":88,"props":5444,"children":5445},{"style":298},[5446],{"type":34,"value":402},{"type":29,"tag":88,"props":5448,"children":5449},{"style":122},[5450],{"type":34,"value":306},{"type":29,"tag":88,"props":5452,"children":5453},{"style":122},[5454],{"type":34,"value":125},{"type":29,"tag":88,"props":5456,"children":5457},{"class":90,"line":1442},[5458,5463,5467,5472,5476,5481,5486,5491,5496,5501,5505,5509],{"type":29,"tag":88,"props":5459,"children":5460},{"style":157},[5461],{"type":34,"value":5462},"        sentNotifications",{"type":29,"tag":88,"props":5464,"children":5465},{"style":122},[5466],{"type":34,"value":338},{"type":29,"tag":88,"props":5468,"children":5469},{"style":174},[5470],{"type":34,"value":5471},"add",{"type":29,"tag":88,"props":5473,"children":5474},{"style":122},[5475],{"type":34,"value":181},{"type":29,"tag":88,"props":5477,"children":5478},{"style":184},[5479],{"type":34,"value":5480},"\"confirmation:\"",{"type":29,"tag":88,"props":5482,"children":5483},{"style":163},[5484],{"type":34,"value":5485}," +",{"type":29,"tag":88,"props":5487,"children":5488},{"style":157},[5489],{"type":34,"value":5490}," userId ",{"type":29,"tag":88,"props":5492,"children":5493},{"style":163},[5494],{"type":34,"value":5495},"+",{"type":29,"tag":88,"props":5497,"children":5498},{"style":184},[5499],{"type":34,"value":5500}," \":\"",{"type":29,"tag":88,"props":5502,"children":5503},{"style":163},[5504],{"type":34,"value":5485},{"type":29,"tag":88,"props":5506,"children":5507},{"style":157},[5508],{"type":34,"value":402},{"type":29,"tag":88,"props":5510,"children":5511},{"style":122},[5512],{"type":34,"value":357},{"type":29,"tag":88,"props":5514,"children":5515},{"class":90,"line":1451},[5516],{"type":29,"tag":88,"props":5517,"children":5518},{"style":122},[5519],{"type":34,"value":433},{"type":29,"tag":88,"props":5521,"children":5522},{"class":90,"line":1477},[5523],{"type":29,"tag":88,"props":5524,"children":5525},{"style":122},[5526],{"type":34,"value":442},{"type":29,"tag":30,"props":5528,"children":5529},{},[5530,5535,5537,5543],{"type":29,"tag":447,"props":5531,"children":5532},{},[5533],{"type":34,"value":5534},"L'avantage Spring :",{"type":34,"value":5536}," ",{"type":29,"tag":84,"props":5538,"children":5540},{"className":5539},[],[5541],{"type":34,"value":5542},"@Profile(\"test\")",{"type":34,"value":5544}," permet d'utiliser automatiquement le mock en environnement de test sans modifier le code métier. Le framework gère le wiring, le code métier reste pur.",{"type":29,"tag":47,"props":5546,"children":5547},{},[],{"type":29,"tag":51,"props":5549,"children":5551},{"id":5550},"quand-appliquer-le-dip-et-quand-ne-pas-le-faire",[5552],{"type":34,"value":5553},"Quand appliquer le DIP, et quand ne pas le faire",{"type":29,"tag":30,"props":5555,"children":5556},{},[5557],{"type":29,"tag":447,"props":5558,"children":5559},{},[5560],{"type":34,"value":5561},"Appliquer le DIP :",{"type":29,"tag":453,"props":5563,"children":5564},{},[5565,5570,5575],{"type":29,"tag":457,"props":5566,"children":5567},{},[5568],{"type":34,"value":5569},"Toute dépendance vers un système externe (base de données, API tierce, service d'email, service de paiement, file de message)",{"type":29,"tag":457,"props":5571,"children":5572},{},[5573],{"type":34,"value":5574},"Toute dépendance vers une infrastructure susceptible de changer",{"type":29,"tag":457,"props":5576,"children":5577},{},[5578],{"type":34,"value":5579},"Tout code que vous voulez unit-tester sans infrastructure",{"type":29,"tag":30,"props":5581,"children":5582},{},[5583],{"type":29,"tag":447,"props":5584,"children":5585},{},[5586],{"type":34,"value":5587},"Ne pas appliquer le DIP mécaniquement :",{"type":29,"tag":453,"props":5589,"children":5590},{},[5591,5596,5601],{"type":29,"tag":457,"props":5592,"children":5593},{},[5594],{"type":34,"value":5595},"Les entités et value objects du domaine (Order, User, Money) : pas de logique d'infrastructure",{"type":29,"tag":457,"props":5597,"children":5598},{},[5599],{"type":34,"value":5600},"Les utilitaires purs (calculs mathématiques, formatage de dates) : pas d'effet de bord",{"type":29,"tag":457,"props":5602,"children":5603},{},[5604],{"type":34,"value":5605},"Les dépendances stables et peu susceptibles de changer dans des petits projets",{"type":29,"tag":30,"props":5607,"children":5608},{},[5609,5614,5616,5622],{"type":29,"tag":447,"props":5610,"children":5611},{},[5612],{"type":34,"value":5613},"Le signal",{"type":34,"value":5615}," : si écrire un test unitaire pour votre classe nécessite de démarrer une base de données, une queue de messages, ou de configurer un service externe, appliquez le DIP. Cette question est aussi centrale dans les ",{"type":29,"tag":63,"props":5617,"children":5619},{"href":5618},"\u002Ffr\u002Fdette-technique\u002Ftests-integration-legacy-pieges",[5620],{"type":34,"value":5621},"tests d'intégration sur du code legacy",{"type":34,"value":5623}," : l'absence de DIP est souvent ce qui rend ces tests si difficiles et si fragiles à mettre en place.",{"type":29,"tag":47,"props":5625,"children":5626},{},[],{"type":29,"tag":2288,"props":5628,"children":5633},{"cta":5629,"href":5630,"title":5631,"type":5632},"Les 100 pratiques que l'IA n'enseigne pas →","https:\u002F\u002Fkamanga.fr\u002Freferentiel-craft","Le DIP n'est qu'une des 100 pratiques qui rendent un code testable","product",[5634],{"type":29,"tag":30,"props":5635,"children":5636},{},[5637],{"type":34,"value":5638},"Cet article détaille une pratique craft : inverser ses dépendances pour découpler le métier de l'infrastructure. Le Craft Bundle réunit les 100 pratiques que j'applique pour coder propre, du choix d'une abstraction au design d'un test rapide. Celles que l'IA ne vous apprendra jamais parce qu'elle ne les a jamais vues tenir en production.",{"type":29,"tag":47,"props":5640,"children":5641},{},[],{"type":29,"tag":51,"props":5643,"children":5645},{"id":5644},"faq-sur-le-dependency-inversion-principle",[5646],{"type":34,"value":5647},"FAQ sur le Dependency Inversion Principle",{"type":29,"tag":5649,"props":5650,"children":5651},"details",{},[5652,5658],{"type":29,"tag":5653,"props":5654,"children":5655},"summary",{},[5656],{"type":34,"value":5657},"1. Quelle est la différence entre DIP et Dependency Injection ?",{"type":29,"tag":30,"props":5659,"children":5660},{},[5661],{"type":34,"value":5662},"Le DIP est un principe architectural : les modules doivent dépendre d'abstractions. La Dependency Injection (DI) est une technique d'implémentation du DIP : les dépendances sont fournies de l'extérieur plutôt que créées à l'intérieur. On peut respecter le DIP sans DI (ex : factory pattern). On peut utiliser la DI sans respecter le DIP (ex : injecter une classe concrète sans interface). En pratique, les deux vont généralement ensemble.",{"type":29,"tag":5649,"props":5664,"children":5665},{},[5666,5671],{"type":29,"tag":5653,"props":5667,"children":5668},{},[5669],{"type":34,"value":5670},"2. Les containers DI (Spring, .NET DI, Angular) font-ils le travail à notre place ?",{"type":29,"tag":30,"props":5672,"children":5673},{},[5674],{"type":34,"value":5675},"Ils automatisent le wiring (qui injecte quoi), mais ne créent pas les abstractions à notre place. Spring injecte les classes concrètes si vous ne créez pas d'interfaces. La discipline architecturale de créer des interfaces pour les dépendances d'infrastructure reste une décision de l'équipe. Le framework ne peut pas la prendre à votre place.",{"type":29,"tag":5649,"props":5677,"children":5678},{},[5679,5684],{"type":29,"tag":5653,"props":5680,"children":5681},{},[5682],{"type":34,"value":5683},"3. Le DIP ne crée-t-il pas trop d'abstractions ?",{"type":29,"tag":30,"props":5685,"children":5686},{},[5687],{"type":34,"value":5688},"Oui, si mal appliqué. Créer une interface pour chaque classe, même les plus stables, est du sur-engineering. La règle que Martin Fowler formule clairement : créer une abstraction quand il y a au moins 2 implémentations possibles (production + test, provider A + provider B) ou quand la dépendance est vers un système externe. \"Pas d'abstraction prématurée\" s'applique au DIP comme à tout principe.",{"type":29,"tag":5649,"props":5690,"children":5691},{},[5692,5697],{"type":29,"tag":5653,"props":5693,"children":5694},{},[5695],{"type":34,"value":5696},"4. Comment introduire le DIP progressivement dans un codebase existant ?",{"type":29,"tag":30,"props":5698,"children":5699},{},[5700,5702,5708],{"type":34,"value":5701},"Le strangler fig pattern appliqué au DIP : ne pas refactorer tout le code existant d'un coup. À chaque nouvelle fonctionnalité ou bug fix qui touche une classe avec dépendances directes, extraire l'interface et introduire l'injection. Après 6 mois de cette discipline, les zones les plus actives du codebase respectent le DIP. Les zones stables peuvent rester dans l'état existant si elles ne causent pas de problèmes. Dans un contexte de ",{"type":29,"tag":63,"props":5703,"children":5705},{"href":5704},"\u002Ffr\u002Fdette-technique\u002Flegacy-code-evaluer-risque",[5706],{"type":34,"value":5707},"code legacy fortement couplé",{"type":34,"value":5709},", cette approche progressive est souvent la seule viable sans bloquer les livraisons.",{"type":29,"tag":5649,"props":5711,"children":5712},{},[5713,5718],{"type":29,"tag":5653,"props":5714,"children":5715},{},[5716],{"type":34,"value":5717},"5. Le DIP s'applique-t-il aux frontends (React, Vue) ?",{"type":29,"tag":30,"props":5719,"children":5720},{},[5721,5723,5729,5731,5737,5739,5745],{"type":34,"value":5722},"Oui. En React : les composants ne doivent pas appeler directement ",{"type":29,"tag":84,"props":5724,"children":5726},{"className":5725},[],[5727],{"type":34,"value":5728},"fetch()",{"type":34,"value":5730}," ou ",{"type":29,"tag":84,"props":5732,"children":5734},{"className":5733},[],[5735],{"type":34,"value":5736},"axios",{"type":34,"value":5738}," : ils doivent dépendre d'une abstraction (un service, un hook custom, un context) qui peut être mockée dans les tests. ",{"type":29,"tag":84,"props":5740,"children":5742},{"className":5741},[],[5743],{"type":34,"value":5744},"useOrderService()",{"type":34,"value":5746}," hook qui cache l'implémentation HTTP, facilement mockable dans les tests. Le DIP s'applique partout où il y a des effets de bord, frontend inclus.",{"type":29,"tag":47,"props":5748,"children":5749},{},[],{"type":29,"tag":2288,"props":5751,"children":5756},{"cta":5752,"href":5753,"title":5754,"type":5755},"Faire mon auto-évaluation →","\u002Fema","Ressource gratuite : Engineering Maturity Self-Assessment","resource",[5757],{"type":29,"tag":30,"props":5758,"children":5759},{},[5760],{"type":34,"value":5761},"L'Engineering Maturity Self-Assessment couvre le domaine Craft & Conception : évaluez votre niveau sur les principes SOLID, le couplage, et la testabilité. Obtenez un score de maturité et des recommandations concrètes en 10 minutes.",{"type":29,"tag":5763,"props":5764,"children":5765},"style",{},[5766],{"type":34,"value":5767},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":8,"searchDepth":101,"depth":101,"links":5769},[5770,5771,5772,5773,5774,5775,5776],{"id":53,"depth":101,"text":56},{"id":505,"depth":101,"text":508},{"id":571,"depth":101,"text":574},{"id":2305,"depth":101,"text":2308},{"id":4628,"depth":101,"text":4631},{"id":5550,"depth":101,"text":5553},{"id":5644,"depth":101,"text":5647},"markdown","content:fr:architecture-craft:dependency-inversion-pratique.md","content","fr\u002Farchitecture-craft\u002Fdependency-inversion-pratique.md","fr\u002Farchitecture-craft\u002Fdependency-inversion-pratique","md",{"_path":5784,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":5785,"description":5786,"id":817,"date":5787,"listed":13,"nocomments":7,"hidden":7,"categories":5788,"tags":5789,"cover":5791,"readingTime":5792,"body":5797,"_type":5777,"_id":7225,"_source":5779,"_file":7226,"_stem":7227,"_extension":5782},"\u002Ffr\u002Farchitecture-craft\u002Fcouplage-temporel-code-asynchrone","Le couplage temporel : la dette cachée dans votre code asynchrone","Le couplage temporel est invisible dans les revues de code et catastrophique en production. Comment l'identifier, le mesurer et l'éliminer progressivement.","2026-02-06",[6],[5790,17],"refactoring","covers\u002Farticles\u002Fcouplage-temporel-asynchrone.jpg",{"text":5793,"minutes":5794,"time":5795,"words":5796},"8 min read",7.79,467400,1558,{"type":26,"children":5798,"toc":7209},[5799,5804,5809,5814,5819,5822,5828,5840,5845,5855,5988,6000,6003,6009,6016,6021,6031,6036,6042,6047,6576,6582,6587,6600,6609,6612,6618,6636,6659,6669,6687,6690,6696,6702,6707,7030,7036,7049,7054,7060,7065,7082,7085,7091,7101,7113,7116,7125,7128,7134,7147,7168,7181,7194,7197,7205],{"type":29,"tag":30,"props":5800,"children":5801},{},[5802],{"type":34,"value":5803},"Un vendredi soir, 22h. J'étais en astreinte pour une plateforme de paiement dans le secteur bancaire. La chaîne de traitement des virements tombait de façon intermittente depuis 48 heures : 2 à 3 fois par jour, toujours \"résolue\" par un retry manuel ou une correction en base. Le bug semblait se résoudre de lui-même.",{"type":29,"tag":30,"props":5805,"children":5806},{},[5807],{"type":34,"value":5808},"Trois heures plus tard, j'avais trouvé : une contrainte d'ordre implicite entre deux services asynchrones. L'un devait recevoir un événement \"CompteValidé\" avant de traiter un événement \"VirementInitié\". Lors des pics de charge, les deux événements arrivaient dans le désordre. Le service traitait le virement sur un compte qui n'existait pas encore dans son état local.",{"type":29,"tag":30,"props":5810,"children":5811},{},[5812],{"type":34,"value":5813},"Rien dans le code ne signalait cette contrainte. Elle était documentée dans un commentaire Confluence que personne ne lisait plus.",{"type":29,"tag":30,"props":5815,"children":5816},{},[5817],{"type":34,"value":5818},"Ce problème avait un nom : le couplage temporel. Et il était présent depuis 18 mois.",{"type":29,"tag":47,"props":5820,"children":5821},{},[],{"type":29,"tag":51,"props":5823,"children":5825},{"id":5824},"ce-quest-vraiment-le-couplage-temporel",[5826],{"type":34,"value":5827},"Ce qu'est vraiment le couplage temporel",{"type":29,"tag":30,"props":5829,"children":5830},{},[5831,5833,5838],{"type":34,"value":5832},"Le couplage temporel existe quand deux opérations ",{"type":29,"tag":447,"props":5834,"children":5835},{},[5836],{"type":34,"value":5837},"doivent se dérouler dans un ordre spécifique ou dans une fenêtre temporelle précise",{"type":34,"value":5839},", et que cette contrainte n'est pas rendue explicite dans le code.",{"type":29,"tag":30,"props":5841,"children":5842},{},[5843],{"type":34,"value":5844},"C'est une contrainte implicite : rien dans le code ne vous dit que A doit se terminer avant B. Vous le savez parce que vous avez écrit le code, ou parce que vous avez lu la documentation. Le prochain développeur ne le saura peut-être pas.",{"type":29,"tag":30,"props":5846,"children":5847},{},[5848,5853],{"type":29,"tag":447,"props":5849,"children":5850},{},[5851],{"type":34,"value":5852},"Exemple basique",{"type":34,"value":5854}," :",{"type":29,"tag":77,"props":5856,"children":5860},{"className":5857,"code":5858,"language":5859,"meta":8,"style":8},"language-javascript shiki shiki-themes catppuccin-frappe github-dark","\u002F\u002F Couplage temporel implicite :\nawait initializeDatabase();   \u002F\u002F doit s'exécuter en premier\nawait loadConfiguration();    \u002F\u002F dépend de la DB\nawait startHttpServer();       \u002F\u002F dépend de la configuration\n\n\u002F\u002F Si initializeDatabase() échoue silencieusement,\n\u002F\u002F loadConfiguration() peut \"fonctionner\" avec des données partielles\n\u002F\u002F et startHttpServer() démarrera avec une configuration corrompue.\n\u002F\u002F Le bug se manifeste plus tard, dans une feature spécifique.\n","javascript",[5861],{"type":29,"tag":84,"props":5862,"children":5863},{"__ignoreMap":8},[5864,5872,5899,5924,5949,5956,5964,5972,5980],{"type":29,"tag":88,"props":5865,"children":5866},{"class":90,"line":91},[5867],{"type":29,"tag":88,"props":5868,"children":5869},{"style":95},[5870],{"type":34,"value":5871},"\u002F\u002F Couplage temporel implicite :\n",{"type":29,"tag":88,"props":5873,"children":5874},{"class":90,"line":101},[5875,5880,5885,5889,5894],{"type":29,"tag":88,"props":5876,"children":5877},{"style":105},[5878],{"type":34,"value":5879},"await",{"type":29,"tag":88,"props":5881,"children":5882},{"style":174},[5883],{"type":34,"value":5884}," initializeDatabase",{"type":29,"tag":88,"props":5886,"children":5887},{"style":157},[5888],{"type":34,"value":1470},{"type":29,"tag":88,"props":5890,"children":5891},{"style":122},[5892],{"type":34,"value":5893},";",{"type":29,"tag":88,"props":5895,"children":5896},{"style":95},[5897],{"type":34,"value":5898},"   \u002F\u002F doit s'exécuter en premier\n",{"type":29,"tag":88,"props":5900,"children":5901},{"class":90,"line":128},[5902,5906,5911,5915,5919],{"type":29,"tag":88,"props":5903,"children":5904},{"style":105},[5905],{"type":34,"value":5879},{"type":29,"tag":88,"props":5907,"children":5908},{"style":174},[5909],{"type":34,"value":5910}," loadConfiguration",{"type":29,"tag":88,"props":5912,"children":5913},{"style":157},[5914],{"type":34,"value":1470},{"type":29,"tag":88,"props":5916,"children":5917},{"style":122},[5918],{"type":34,"value":5893},{"type":29,"tag":88,"props":5920,"children":5921},{"style":95},[5922],{"type":34,"value":5923},"    \u002F\u002F dépend de la DB\n",{"type":29,"tag":88,"props":5925,"children":5926},{"class":90,"line":137},[5927,5931,5936,5940,5944],{"type":29,"tag":88,"props":5928,"children":5929},{"style":105},[5930],{"type":34,"value":5879},{"type":29,"tag":88,"props":5932,"children":5933},{"style":174},[5934],{"type":34,"value":5935}," startHttpServer",{"type":29,"tag":88,"props":5937,"children":5938},{"style":157},[5939],{"type":34,"value":1470},{"type":29,"tag":88,"props":5941,"children":5942},{"style":122},[5943],{"type":34,"value":5893},{"type":29,"tag":88,"props":5945,"children":5946},{"style":95},[5947],{"type":34,"value":5948},"       \u002F\u002F dépend de la configuration\n",{"type":29,"tag":88,"props":5950,"children":5951},{"class":90,"line":211},[5952],{"type":29,"tag":88,"props":5953,"children":5954},{"emptyLinePlaceholder":13},[5955],{"type":34,"value":134},{"type":29,"tag":88,"props":5957,"children":5958},{"class":90,"line":262},[5959],{"type":29,"tag":88,"props":5960,"children":5961},{"style":95},[5962],{"type":34,"value":5963},"\u002F\u002F Si initializeDatabase() échoue silencieusement,\n",{"type":29,"tag":88,"props":5965,"children":5966},{"class":90,"line":270},[5967],{"type":29,"tag":88,"props":5968,"children":5969},{"style":95},[5970],{"type":34,"value":5971},"\u002F\u002F loadConfiguration() peut \"fonctionner\" avec des données partielles\n",{"type":29,"tag":88,"props":5973,"children":5974},{"class":90,"line":313},[5975],{"type":29,"tag":88,"props":5976,"children":5977},{"style":95},[5978],{"type":34,"value":5979},"\u002F\u002F et startHttpServer() démarrera avec une configuration corrompue.\n",{"type":29,"tag":88,"props":5981,"children":5982},{"class":90,"line":360},[5983],{"type":29,"tag":88,"props":5984,"children":5985},{"style":95},[5986],{"type":34,"value":5987},"\u002F\u002F Le bug se manifeste plus tard, dans une feature spécifique.\n",{"type":29,"tag":30,"props":5989,"children":5990},{},[5991,5993,5998],{"type":34,"value":5992},"Selon les données que j'observe dans mes missions, ",{"type":29,"tag":447,"props":5994,"children":5995},{},[5996],{"type":34,"value":5997},"les incidents intermittents en production représentent 40 à 60% du temps de debugging des équipes senior",{"type":34,"value":5999},", et le couplage temporel en est l'une des causes les plus fréquentes et les moins visibles.",{"type":29,"tag":47,"props":6001,"children":6002},{},[],{"type":29,"tag":51,"props":6004,"children":6006},{"id":6005},"les-3-formes-les-plus-courantes",[6007],{"type":34,"value":6008},"Les 3 formes les plus courantes",{"type":29,"tag":6010,"props":6011,"children":6013},"h3",{"id":6012},"forme-1-la-séquence-obligatoire-non-documentée",[6014],{"type":34,"value":6015},"Forme 1 : La séquence obligatoire non documentée",{"type":29,"tag":30,"props":6017,"children":6018},{},[6019],{"type":34,"value":6020},"Des opérations qui doivent être exécutées dans un ordre précis, sans que cet ordre soit rendu explicite ni protégé par du code.",{"type":29,"tag":30,"props":6022,"children":6023},{},[6024,6029],{"type":29,"tag":447,"props":6025,"children":6026},{},[6027],{"type":34,"value":6028},"Exemple",{"type":34,"value":6030}," : un service qui doit recevoir un événement \"UserCreated\" avant de pouvoir traiter un événement \"UserProfileUpdated\". Si les deux arrivent simultanément (race condition), le traitement échoue ou produit un état incohérent.",{"type":29,"tag":30,"props":6032,"children":6033},{},[6034],{"type":34,"value":6035},"Ce type d'incident coûte en moyenne 2 à 5 heures de debugging pour un développeur senior, et laisse un résidu de méfiance dans le système. L'équipe commence à \"monitorer manuellement\" ce flux, ce qui est un signal fort que la contrainte n'est pas correctement encodée.",{"type":29,"tag":6010,"props":6037,"children":6039},{"id":6038},"forme-2-les-appels-asynchrones-séquentiels-inutiles",[6040],{"type":34,"value":6041},"Forme 2 : Les appels asynchrones séquentiels inutiles",{"type":29,"tag":30,"props":6043,"children":6044},{},[6045],{"type":34,"value":6046},"Des appels asynchrones imbriqués où chaque niveau dépend du précédent, même quand ce n'est pas nécessaire. Même avec async\u002Fawait, le pattern peut rester présent sous une forme différente.",{"type":29,"tag":77,"props":6048,"children":6050},{"className":5857,"code":6049,"language":5859,"meta":8,"style":8},"\u002F\u002F ❌ Couplage temporel implicite même avec async\u002Fawait\nasync function processOrder(orderId) {\n    const order = await getOrder(orderId);\n    const customer = await getCustomer(order.customerId); \u002F\u002F dépend de order\n    const inventory = await checkInventory(order.items);  \u002F\u002F pourrait être parallèle !\n    const payment = await processPayment(customer, order);\n    await sendConfirmation(customer, order);\n}\n\n\u002F\u002F ✅ Parallélisation explicite pour les opérations indépendantes\nasync function processOrder(orderId) {\n    const order = await getOrder(orderId);\n    const [customer, inventory] = await Promise.all([\n        getCustomer(order.customerId),\n        checkInventory(order.items)    \u002F\u002F pas de dépendance sur customer\n    ]);\n    const payment = await processPayment(customer, order);\n    await sendConfirmation(customer, order);\n}\n",[6051],{"type":29,"tag":84,"props":6052,"children":6053},{"__ignoreMap":8},[6054,6062,6096,6133,6182,6229,6271,6299,6306,6313,6321,6352,6383,6441,6465,6491,6503,6542,6569],{"type":29,"tag":88,"props":6055,"children":6056},{"class":90,"line":91},[6057],{"type":29,"tag":88,"props":6058,"children":6059},{"style":95},[6060],{"type":34,"value":6061},"\u002F\u002F ❌ Couplage temporel implicite même avec async\u002Fawait\n",{"type":29,"tag":88,"props":6063,"children":6064},{"class":90,"line":101},[6065,6070,6075,6080,6084,6088,6092],{"type":29,"tag":88,"props":6066,"children":6067},{"style":105},[6068],{"type":34,"value":6069},"async",{"type":29,"tag":88,"props":6071,"children":6072},{"style":105},[6073],{"type":34,"value":6074}," function",{"type":29,"tag":88,"props":6076,"children":6077},{"style":174},[6078],{"type":34,"value":6079}," processOrder",{"type":29,"tag":88,"props":6081,"children":6082},{"style":122},[6083],{"type":34,"value":181},{"type":29,"tag":88,"props":6085,"children":6086},{"style":298},[6087],{"type":34,"value":1836},{"type":29,"tag":88,"props":6089,"children":6090},{"style":122},[6091],{"type":34,"value":306},{"type":29,"tag":88,"props":6093,"children":6094},{"style":122},[6095],{"type":34,"value":125},{"type":29,"tag":88,"props":6097,"children":6098},{"class":90,"line":128},[6099,6104,6109,6114,6119,6124,6129],{"type":29,"tag":88,"props":6100,"children":6101},{"style":105},[6102],{"type":34,"value":6103},"    const",{"type":29,"tag":88,"props":6105,"children":6107},{"style":6106},"--shiki-default:#C6D0F5;--shiki-dark:#79B8FF",[6108],{"type":34,"value":4310},{"type":29,"tag":88,"props":6110,"children":6111},{"style":163},[6112],{"type":34,"value":6113}," =",{"type":29,"tag":88,"props":6115,"children":6116},{"style":105},[6117],{"type":34,"value":6118}," await",{"type":29,"tag":88,"props":6120,"children":6121},{"style":174},[6122],{"type":34,"value":6123}," getOrder",{"type":29,"tag":88,"props":6125,"children":6126},{"style":157},[6127],{"type":34,"value":6128},"(orderId)",{"type":29,"tag":88,"props":6130,"children":6131},{"style":122},[6132],{"type":34,"value":424},{"type":29,"tag":88,"props":6134,"children":6135},{"class":90,"line":137},[6136,6140,6145,6149,6153,6158,6163,6168,6173,6177],{"type":29,"tag":88,"props":6137,"children":6138},{"style":105},[6139],{"type":34,"value":6103},{"type":29,"tag":88,"props":6141,"children":6142},{"style":6106},[6143],{"type":34,"value":6144}," customer",{"type":29,"tag":88,"props":6146,"children":6147},{"style":163},[6148],{"type":34,"value":6113},{"type":29,"tag":88,"props":6150,"children":6151},{"style":105},[6152],{"type":34,"value":6118},{"type":29,"tag":88,"props":6154,"children":6155},{"style":174},[6156],{"type":34,"value":6157}," getCustomer",{"type":29,"tag":88,"props":6159,"children":6160},{"style":157},[6161],{"type":34,"value":6162},"(order",{"type":29,"tag":88,"props":6164,"children":6166},{"style":6165},"--shiki-default:#81C8BE;--shiki-dark:#E1E4E8",[6167],{"type":34,"value":338},{"type":29,"tag":88,"props":6169,"children":6170},{"style":157},[6171],{"type":34,"value":6172},"customerId)",{"type":29,"tag":88,"props":6174,"children":6175},{"style":122},[6176],{"type":34,"value":5893},{"type":29,"tag":88,"props":6178,"children":6179},{"style":95},[6180],{"type":34,"value":6181}," \u002F\u002F dépend de order\n",{"type":29,"tag":88,"props":6183,"children":6184},{"class":90,"line":211},[6185,6189,6194,6198,6202,6207,6211,6215,6220,6224],{"type":29,"tag":88,"props":6186,"children":6187},{"style":105},[6188],{"type":34,"value":6103},{"type":29,"tag":88,"props":6190,"children":6191},{"style":6106},[6192],{"type":34,"value":6193}," inventory",{"type":29,"tag":88,"props":6195,"children":6196},{"style":163},[6197],{"type":34,"value":6113},{"type":29,"tag":88,"props":6199,"children":6200},{"style":105},[6201],{"type":34,"value":6118},{"type":29,"tag":88,"props":6203,"children":6204},{"style":174},[6205],{"type":34,"value":6206}," checkInventory",{"type":29,"tag":88,"props":6208,"children":6209},{"style":157},[6210],{"type":34,"value":6162},{"type":29,"tag":88,"props":6212,"children":6213},{"style":6165},[6214],{"type":34,"value":338},{"type":29,"tag":88,"props":6216,"children":6217},{"style":157},[6218],{"type":34,"value":6219},"items)",{"type":29,"tag":88,"props":6221,"children":6222},{"style":122},[6223],{"type":34,"value":5893},{"type":29,"tag":88,"props":6225,"children":6226},{"style":95},[6227],{"type":34,"value":6228},"  \u002F\u002F pourrait être parallèle !\n",{"type":29,"tag":88,"props":6230,"children":6231},{"class":90,"line":262},[6232,6236,6240,6244,6248,6253,6258,6262,6267],{"type":29,"tag":88,"props":6233,"children":6234},{"style":105},[6235],{"type":34,"value":6103},{"type":29,"tag":88,"props":6237,"children":6238},{"style":6106},[6239],{"type":34,"value":2605},{"type":29,"tag":88,"props":6241,"children":6242},{"style":163},[6243],{"type":34,"value":6113},{"type":29,"tag":88,"props":6245,"children":6246},{"style":105},[6247],{"type":34,"value":6118},{"type":29,"tag":88,"props":6249,"children":6250},{"style":174},[6251],{"type":34,"value":6252}," processPayment",{"type":29,"tag":88,"props":6254,"children":6255},{"style":157},[6256],{"type":34,"value":6257},"(customer",{"type":29,"tag":88,"props":6259,"children":6260},{"style":122},[6261],{"type":34,"value":192},{"type":29,"tag":88,"props":6263,"children":6264},{"style":157},[6265],{"type":34,"value":6266}," order)",{"type":29,"tag":88,"props":6268,"children":6269},{"style":122},[6270],{"type":34,"value":424},{"type":29,"tag":88,"props":6272,"children":6273},{"class":90,"line":270},[6274,6279,6283,6287,6291,6295],{"type":29,"tag":88,"props":6275,"children":6276},{"style":105},[6277],{"type":34,"value":6278},"    await",{"type":29,"tag":88,"props":6280,"children":6281},{"style":174},[6282],{"type":34,"value":686},{"type":29,"tag":88,"props":6284,"children":6285},{"style":157},[6286],{"type":34,"value":6257},{"type":29,"tag":88,"props":6288,"children":6289},{"style":122},[6290],{"type":34,"value":192},{"type":29,"tag":88,"props":6292,"children":6293},{"style":157},[6294],{"type":34,"value":6266},{"type":29,"tag":88,"props":6296,"children":6297},{"style":122},[6298],{"type":34,"value":424},{"type":29,"tag":88,"props":6300,"children":6301},{"class":90,"line":313},[6302],{"type":29,"tag":88,"props":6303,"children":6304},{"style":122},[6305],{"type":34,"value":442},{"type":29,"tag":88,"props":6307,"children":6308},{"class":90,"line":360},[6309],{"type":29,"tag":88,"props":6310,"children":6311},{"emptyLinePlaceholder":13},[6312],{"type":34,"value":134},{"type":29,"tag":88,"props":6314,"children":6315},{"class":90,"line":409},[6316],{"type":29,"tag":88,"props":6317,"children":6318},{"style":95},[6319],{"type":34,"value":6320},"\u002F\u002F ✅ Parallélisation explicite pour les opérations indépendantes\n",{"type":29,"tag":88,"props":6322,"children":6323},{"class":90,"line":427},[6324,6328,6332,6336,6340,6344,6348],{"type":29,"tag":88,"props":6325,"children":6326},{"style":105},[6327],{"type":34,"value":6069},{"type":29,"tag":88,"props":6329,"children":6330},{"style":105},[6331],{"type":34,"value":6074},{"type":29,"tag":88,"props":6333,"children":6334},{"style":174},[6335],{"type":34,"value":6079},{"type":29,"tag":88,"props":6337,"children":6338},{"style":122},[6339],{"type":34,"value":181},{"type":29,"tag":88,"props":6341,"children":6342},{"style":298},[6343],{"type":34,"value":1836},{"type":29,"tag":88,"props":6345,"children":6346},{"style":122},[6347],{"type":34,"value":306},{"type":29,"tag":88,"props":6349,"children":6350},{"style":122},[6351],{"type":34,"value":125},{"type":29,"tag":88,"props":6353,"children":6354},{"class":90,"line":436},[6355,6359,6363,6367,6371,6375,6379],{"type":29,"tag":88,"props":6356,"children":6357},{"style":105},[6358],{"type":34,"value":6103},{"type":29,"tag":88,"props":6360,"children":6361},{"style":6106},[6362],{"type":34,"value":4310},{"type":29,"tag":88,"props":6364,"children":6365},{"style":163},[6366],{"type":34,"value":6113},{"type":29,"tag":88,"props":6368,"children":6369},{"style":105},[6370],{"type":34,"value":6118},{"type":29,"tag":88,"props":6372,"children":6373},{"style":174},[6374],{"type":34,"value":6123},{"type":29,"tag":88,"props":6376,"children":6377},{"style":157},[6378],{"type":34,"value":6128},{"type":29,"tag":88,"props":6380,"children":6381},{"style":122},[6382],{"type":34,"value":424},{"type":29,"tag":88,"props":6384,"children":6385},{"class":90,"line":767},[6386,6390,6395,6400,6404,6408,6413,6417,6421,6427,6431,6436],{"type":29,"tag":88,"props":6387,"children":6388},{"style":105},[6389],{"type":34,"value":6103},{"type":29,"tag":88,"props":6391,"children":6392},{"style":122},[6393],{"type":34,"value":6394}," [",{"type":29,"tag":88,"props":6396,"children":6397},{"style":6106},[6398],{"type":34,"value":6399},"customer",{"type":29,"tag":88,"props":6401,"children":6402},{"style":122},[6403],{"type":34,"value":192},{"type":29,"tag":88,"props":6405,"children":6406},{"style":6106},[6407],{"type":34,"value":6193},{"type":29,"tag":88,"props":6409,"children":6410},{"style":122},[6411],{"type":34,"value":6412},"]",{"type":29,"tag":88,"props":6414,"children":6415},{"style":163},[6416],{"type":34,"value":6113},{"type":29,"tag":88,"props":6418,"children":6419},{"style":105},[6420],{"type":34,"value":6118},{"type":29,"tag":88,"props":6422,"children":6424},{"style":6423},"--shiki-default:#E5C890;--shiki-default-font-style:italic;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit",[6425],{"type":34,"value":6426}," Promise",{"type":29,"tag":88,"props":6428,"children":6429},{"style":6165},[6430],{"type":34,"value":338},{"type":29,"tag":88,"props":6432,"children":6433},{"style":174},[6434],{"type":34,"value":6435},"all",{"type":29,"tag":88,"props":6437,"children":6438},{"style":157},[6439],{"type":34,"value":6440},"([\n",{"type":29,"tag":88,"props":6442,"children":6443},{"class":90,"line":792},[6444,6449,6453,6457,6461],{"type":29,"tag":88,"props":6445,"children":6446},{"style":174},[6447],{"type":34,"value":6448},"        getCustomer",{"type":29,"tag":88,"props":6450,"children":6451},{"style":157},[6452],{"type":34,"value":6162},{"type":29,"tag":88,"props":6454,"children":6455},{"style":6165},[6456],{"type":34,"value":338},{"type":29,"tag":88,"props":6458,"children":6459},{"style":157},[6460],{"type":34,"value":6172},{"type":29,"tag":88,"props":6462,"children":6463},{"style":122},[6464],{"type":34,"value":4907},{"type":29,"tag":88,"props":6466,"children":6467},{"class":90,"line":817},[6468,6473,6477,6481,6486],{"type":29,"tag":88,"props":6469,"children":6470},{"style":174},[6471],{"type":34,"value":6472},"        checkInventory",{"type":29,"tag":88,"props":6474,"children":6475},{"style":157},[6476],{"type":34,"value":6162},{"type":29,"tag":88,"props":6478,"children":6479},{"style":6165},[6480],{"type":34,"value":338},{"type":29,"tag":88,"props":6482,"children":6483},{"style":157},[6484],{"type":34,"value":6485},"items)    ",{"type":29,"tag":88,"props":6487,"children":6488},{"style":95},[6489],{"type":34,"value":6490},"\u002F\u002F pas de dépendance sur customer\n",{"type":29,"tag":88,"props":6492,"children":6493},{"class":90,"line":825},[6494,6499],{"type":29,"tag":88,"props":6495,"children":6496},{"style":157},[6497],{"type":34,"value":6498},"    ])",{"type":29,"tag":88,"props":6500,"children":6501},{"style":122},[6502],{"type":34,"value":424},{"type":29,"tag":88,"props":6504,"children":6505},{"class":90,"line":869},[6506,6510,6514,6518,6522,6526,6530,6534,6538],{"type":29,"tag":88,"props":6507,"children":6508},{"style":105},[6509],{"type":34,"value":6103},{"type":29,"tag":88,"props":6511,"children":6512},{"style":6106},[6513],{"type":34,"value":2605},{"type":29,"tag":88,"props":6515,"children":6516},{"style":163},[6517],{"type":34,"value":6113},{"type":29,"tag":88,"props":6519,"children":6520},{"style":105},[6521],{"type":34,"value":6118},{"type":29,"tag":88,"props":6523,"children":6524},{"style":174},[6525],{"type":34,"value":6252},{"type":29,"tag":88,"props":6527,"children":6528},{"style":157},[6529],{"type":34,"value":6257},{"type":29,"tag":88,"props":6531,"children":6532},{"style":122},[6533],{"type":34,"value":192},{"type":29,"tag":88,"props":6535,"children":6536},{"style":157},[6537],{"type":34,"value":6266},{"type":29,"tag":88,"props":6539,"children":6540},{"style":122},[6541],{"type":34,"value":424},{"type":29,"tag":88,"props":6543,"children":6544},{"class":90,"line":900},[6545,6549,6553,6557,6561,6565],{"type":29,"tag":88,"props":6546,"children":6547},{"style":105},[6548],{"type":34,"value":6278},{"type":29,"tag":88,"props":6550,"children":6551},{"style":174},[6552],{"type":34,"value":686},{"type":29,"tag":88,"props":6554,"children":6555},{"style":157},[6556],{"type":34,"value":6257},{"type":29,"tag":88,"props":6558,"children":6559},{"style":122},[6560],{"type":34,"value":192},{"type":29,"tag":88,"props":6562,"children":6563},{"style":157},[6564],{"type":34,"value":6266},{"type":29,"tag":88,"props":6566,"children":6567},{"style":122},[6568],{"type":34,"value":424},{"type":29,"tag":88,"props":6570,"children":6571},{"class":90,"line":929},[6572],{"type":29,"tag":88,"props":6573,"children":6574},{"style":122},[6575],{"type":34,"value":442},{"type":29,"tag":6010,"props":6577,"children":6579},{"id":6578},"forme-3-les-timeouts-implicites-ou-absents",[6580],{"type":34,"value":6581},"Forme 3 : Les timeouts implicites ou absents",{"type":29,"tag":30,"props":6583,"children":6584},{},[6585],{"type":34,"value":6586},"Des appels vers des services externes (API, base de données, message broker) sans timeout défini. Le comportement par défaut de la plupart des clients HTTP est d'attendre indéfiniment, ou avec un timeout système de plusieurs minutes.",{"type":29,"tag":30,"props":6588,"children":6589},{},[6590,6592,6598],{"type":34,"value":6591},"Ce qui se passe ensuite est prévisible : un service tiers commence à répondre lentement. Votre service attend. Les connexions s'accumulent. Le pool de connexions s'épuise. Votre service commence à rejeter des requêtes. La cascade se propage vers les services upstream. C'est précisément le scénario que les ",{"type":29,"tag":63,"props":6593,"children":6595},{"href":6594},"\u002Ffr\u002Farchitecture-craft\u002Fpatterns-resilience-circuit-breaker-retry",[6596],{"type":34,"value":6597},"patterns de résilience comme le circuit breaker et le retry",{"type":34,"value":6599}," sont conçus pour prévenir.",{"type":29,"tag":2288,"props":6601,"children":6603},{"cta":2290,"href":2291,"title":6602,"type":2293},"Vous voulez acquérir le réflexe qui repère un couplage temporel avant qu'il parte en prod ?",[6604],{"type":29,"tag":30,"props":6605,"children":6606},{},[6607],{"type":34,"value":6608},"Voir une séquence asynchrone implicite dans votre propre code, ça ne s'apprend pas en lisant un article : ça se travaille. En mentoring 1:1, je relis votre code avec vous, on rend les contraintes d'ordre explicites, on introduit idempotence et timeouts là où il faut. Vous repartez avec le réflexe d'écrire de l'asynchrone qui ne casse pas sous la charge.",{"type":29,"tag":47,"props":6610,"children":6611},{},[],{"type":29,"tag":51,"props":6613,"children":6615},{"id":6614},"comment-le-détecter-dans-votre-code",[6616],{"type":34,"value":6617},"Comment le détecter dans votre code",{"type":29,"tag":30,"props":6619,"children":6620},{},[6621,6626,6628,6634],{"type":29,"tag":447,"props":6622,"children":6623},{},[6624],{"type":34,"value":6625},"Dans le code",{"type":34,"value":6627},", je cherche ces patterns comme indicateurs potentiels, et les ",{"type":29,"tag":63,"props":6629,"children":6631},{"href":6630},"\u002Ffr\u002Fdette-technique\u002Foutils-analyse-statique-2026",[6632],{"type":34,"value":6633},"outils d'analyse statique",{"type":34,"value":6635}," permettent d'automatiser une partie de cette détection à grande échelle :",{"type":29,"tag":453,"props":6637,"children":6638},{},[6639,6644,6649,6654],{"type":29,"tag":457,"props":6640,"children":6641},{},[6642],{"type":34,"value":6643},"Appels asynchrones séquentiels qui pourraient être parallèles : vérifiez si chacun dépend vraiment du précédent",{"type":29,"tag":457,"props":6645,"children":6646},{},[6647],{"type":34,"value":6648},"Absence de timeout sur les appels vers des services externes",{"type":29,"tag":457,"props":6650,"children":6651},{},[6652],{"type":34,"value":6653},"Commentaires du type \"\u002F\u002F doit être appelé après X\" : la contrainte est documentée mais non protégée par du code",{"type":29,"tag":457,"props":6655,"children":6656},{},[6657],{"type":34,"value":6658},"Messages ou événements qui doivent être traités dans un ordre précis sans mécanisme de garantie",{"type":29,"tag":30,"props":6660,"children":6661},{},[6662,6667],{"type":29,"tag":447,"props":6663,"children":6664},{},[6665],{"type":34,"value":6666},"En production",{"type":34,"value":6668},", les signaux sont différents :",{"type":29,"tag":453,"props":6670,"children":6671},{},[6672,6677,6682],{"type":29,"tag":457,"props":6673,"children":6674},{},[6675],{"type":34,"value":6676},"Incidents intermittents qui se résolvent avec un retry → indicateur fort de race condition ou de contrainte temporelle non respectée",{"type":29,"tag":457,"props":6678,"children":6679},{},[6680],{"type":34,"value":6681},"Latence qui augmente linéairement avec la charge → indicateur d'opérations séquentielles qui pourraient être parallèles",{"type":29,"tag":457,"props":6683,"children":6684},{},[6685],{"type":34,"value":6686},"Timeouts qui se propagent en cascade → indicateur d'absence de timeout et de circuit breaker",{"type":29,"tag":47,"props":6688,"children":6689},{},[],{"type":29,"tag":51,"props":6691,"children":6693},{"id":6692},"les-3-corrections-prioritaires",[6694],{"type":34,"value":6695},"Les 3 corrections prioritaires",{"type":29,"tag":6010,"props":6697,"children":6699},{"id":6698},"idempotence-opérations-retriables-sans-effet-de-bord",[6700],{"type":34,"value":6701},"Idempotence : opérations retriables sans effet de bord",{"type":29,"tag":30,"props":6703,"children":6704},{},[6705],{"type":34,"value":6706},"Chaque opération qui peut échouer et être retentée doit être idempotente : la ré-exécuter avec le même input produit le même résultat, sans effets de bord additionnels.",{"type":29,"tag":77,"props":6708,"children":6710},{"className":81,"code":6709,"language":80,"meta":8,"style":8},"\u002F\u002F ❌ Non-idempotent : chaque appel crée un enregistrement\npublic void createOrder(OrderCommand cmd) {\n    Order order = new Order(cmd);\n    orderRepository.save(order);  \u002F\u002F crée un nouveau record à chaque appel\n}\n\n\u002F\u002F ✅ Idempotent : même résultat quel que soit le nombre d'appels\npublic void createOrder(OrderCommand cmd) {\n    if (orderRepository.existsById(cmd.getIdempotencyKey())) {\n        return;  \u002F\u002F déjà traité\n    }\n    Order order = new Order(cmd);\n    orderRepository.save(order);\n}\n",[6711],{"type":29,"tag":84,"props":6712,"children":6713},{"__ignoreMap":8},[6714,6722,6759,6796,6829,6836,6843,6851,6886,6938,6954,6961,6996,7023],{"type":29,"tag":88,"props":6715,"children":6716},{"class":90,"line":91},[6717],{"type":29,"tag":88,"props":6718,"children":6719},{"style":95},[6720],{"type":34,"value":6721},"\u002F\u002F ❌ Non-idempotent : chaque appel crée un enregistrement\n",{"type":29,"tag":88,"props":6723,"children":6724},{"class":90,"line":101},[6725,6729,6733,6737,6741,6746,6751,6755],{"type":29,"tag":88,"props":6726,"children":6727},{"style":105},[6728],{"type":34,"value":108},{"type":29,"tag":88,"props":6730,"children":6731},{"style":105},[6732],{"type":34,"value":1303},{"type":29,"tag":88,"props":6734,"children":6735},{"style":174},[6736],{"type":34,"value":286},{"type":29,"tag":88,"props":6738,"children":6739},{"style":122},[6740],{"type":34,"value":181},{"type":29,"tag":88,"props":6742,"children":6743},{"style":151},[6744],{"type":34,"value":6745},"OrderCommand",{"type":29,"tag":88,"props":6747,"children":6748},{"style":157},[6749],{"type":34,"value":6750}," cmd",{"type":29,"tag":88,"props":6752,"children":6753},{"style":122},[6754],{"type":34,"value":306},{"type":29,"tag":88,"props":6756,"children":6757},{"style":122},[6758],{"type":34,"value":125},{"type":29,"tag":88,"props":6760,"children":6761},{"class":90,"line":128},[6762,6767,6771,6775,6779,6783,6787,6792],{"type":29,"tag":88,"props":6763,"children":6764},{"style":151},[6765],{"type":34,"value":6766},"    Order",{"type":29,"tag":88,"props":6768,"children":6769},{"style":157},[6770],{"type":34,"value":4181},{"type":29,"tag":88,"props":6772,"children":6773},{"style":163},[6774],{"type":34,"value":166},{"type":29,"tag":88,"props":6776,"children":6777},{"style":105},[6778],{"type":34,"value":171},{"type":29,"tag":88,"props":6780,"children":6781},{"style":174},[6782],{"type":34,"value":2740},{"type":29,"tag":88,"props":6784,"children":6785},{"style":122},[6786],{"type":34,"value":181},{"type":29,"tag":88,"props":6788,"children":6789},{"style":157},[6790],{"type":34,"value":6791},"cmd",{"type":29,"tag":88,"props":6793,"children":6794},{"style":122},[6795],{"type":34,"value":357},{"type":29,"tag":88,"props":6797,"children":6798},{"class":90,"line":137},[6799,6804,6808,6812,6816,6820,6824],{"type":29,"tag":88,"props":6800,"children":6801},{"style":157},[6802],{"type":34,"value":6803},"    orderRepository",{"type":29,"tag":88,"props":6805,"children":6806},{"style":122},[6807],{"type":34,"value":338},{"type":29,"tag":88,"props":6809,"children":6810},{"style":174},[6811],{"type":34,"value":343},{"type":29,"tag":88,"props":6813,"children":6814},{"style":122},[6815],{"type":34,"value":181},{"type":29,"tag":88,"props":6817,"children":6818},{"style":157},[6819],{"type":34,"value":5182},{"type":29,"tag":88,"props":6821,"children":6822},{"style":122},[6823],{"type":34,"value":203},{"type":29,"tag":88,"props":6825,"children":6826},{"style":95},[6827],{"type":34,"value":6828},"  \u002F\u002F crée un nouveau record à chaque appel\n",{"type":29,"tag":88,"props":6830,"children":6831},{"class":90,"line":211},[6832],{"type":29,"tag":88,"props":6833,"children":6834},{"style":122},[6835],{"type":34,"value":442},{"type":29,"tag":88,"props":6837,"children":6838},{"class":90,"line":262},[6839],{"type":29,"tag":88,"props":6840,"children":6841},{"emptyLinePlaceholder":13},[6842],{"type":34,"value":134},{"type":29,"tag":88,"props":6844,"children":6845},{"class":90,"line":270},[6846],{"type":29,"tag":88,"props":6847,"children":6848},{"style":95},[6849],{"type":34,"value":6850},"\u002F\u002F ✅ Idempotent : même résultat quel que soit le nombre d'appels\n",{"type":29,"tag":88,"props":6852,"children":6853},{"class":90,"line":313},[6854,6858,6862,6866,6870,6874,6878,6882],{"type":29,"tag":88,"props":6855,"children":6856},{"style":105},[6857],{"type":34,"value":108},{"type":29,"tag":88,"props":6859,"children":6860},{"style":105},[6861],{"type":34,"value":1303},{"type":29,"tag":88,"props":6863,"children":6864},{"style":174},[6865],{"type":34,"value":286},{"type":29,"tag":88,"props":6867,"children":6868},{"style":122},[6869],{"type":34,"value":181},{"type":29,"tag":88,"props":6871,"children":6872},{"style":151},[6873],{"type":34,"value":6745},{"type":29,"tag":88,"props":6875,"children":6876},{"style":157},[6877],{"type":34,"value":6750},{"type":29,"tag":88,"props":6879,"children":6880},{"style":122},[6881],{"type":34,"value":306},{"type":29,"tag":88,"props":6883,"children":6884},{"style":122},[6885],{"type":34,"value":125},{"type":29,"tag":88,"props":6887,"children":6888},{"class":90,"line":360},[6889,6894,6898,6903,6907,6912,6916,6920,6924,6929,6934],{"type":29,"tag":88,"props":6890,"children":6891},{"style":105},[6892],{"type":34,"value":6893},"    if",{"type":29,"tag":88,"props":6895,"children":6896},{"style":122},[6897],{"type":34,"value":2891},{"type":29,"tag":88,"props":6899,"children":6900},{"style":157},[6901],{"type":34,"value":6902},"orderRepository",{"type":29,"tag":88,"props":6904,"children":6905},{"style":122},[6906],{"type":34,"value":338},{"type":29,"tag":88,"props":6908,"children":6909},{"style":174},[6910],{"type":34,"value":6911},"existsById",{"type":29,"tag":88,"props":6913,"children":6914},{"style":122},[6915],{"type":34,"value":181},{"type":29,"tag":88,"props":6917,"children":6918},{"style":157},[6919],{"type":34,"value":6791},{"type":29,"tag":88,"props":6921,"children":6922},{"style":122},[6923],{"type":34,"value":338},{"type":29,"tag":88,"props":6925,"children":6926},{"style":174},[6927],{"type":34,"value":6928},"getIdempotencyKey",{"type":29,"tag":88,"props":6930,"children":6931},{"style":122},[6932],{"type":34,"value":6933},"()))",{"type":29,"tag":88,"props":6935,"children":6936},{"style":122},[6937],{"type":34,"value":125},{"type":29,"tag":88,"props":6939,"children":6940},{"class":90,"line":409},[6941,6945,6949],{"type":29,"tag":88,"props":6942,"children":6943},{"style":105},[6944],{"type":34,"value":415},{"type":29,"tag":88,"props":6946,"children":6947},{"style":122},[6948],{"type":34,"value":5893},{"type":29,"tag":88,"props":6950,"children":6951},{"style":95},[6952],{"type":34,"value":6953},"  \u002F\u002F déjà traité\n",{"type":29,"tag":88,"props":6955,"children":6956},{"class":90,"line":427},[6957],{"type":29,"tag":88,"props":6958,"children":6959},{"style":122},[6960],{"type":34,"value":433},{"type":29,"tag":88,"props":6962,"children":6963},{"class":90,"line":436},[6964,6968,6972,6976,6980,6984,6988,6992],{"type":29,"tag":88,"props":6965,"children":6966},{"style":151},[6967],{"type":34,"value":6766},{"type":29,"tag":88,"props":6969,"children":6970},{"style":157},[6971],{"type":34,"value":4181},{"type":29,"tag":88,"props":6973,"children":6974},{"style":163},[6975],{"type":34,"value":166},{"type":29,"tag":88,"props":6977,"children":6978},{"style":105},[6979],{"type":34,"value":171},{"type":29,"tag":88,"props":6981,"children":6982},{"style":174},[6983],{"type":34,"value":2740},{"type":29,"tag":88,"props":6985,"children":6986},{"style":122},[6987],{"type":34,"value":181},{"type":29,"tag":88,"props":6989,"children":6990},{"style":157},[6991],{"type":34,"value":6791},{"type":29,"tag":88,"props":6993,"children":6994},{"style":122},[6995],{"type":34,"value":357},{"type":29,"tag":88,"props":6997,"children":6998},{"class":90,"line":767},[6999,7003,7007,7011,7015,7019],{"type":29,"tag":88,"props":7000,"children":7001},{"style":157},[7002],{"type":34,"value":6803},{"type":29,"tag":88,"props":7004,"children":7005},{"style":122},[7006],{"type":34,"value":338},{"type":29,"tag":88,"props":7008,"children":7009},{"style":174},[7010],{"type":34,"value":343},{"type":29,"tag":88,"props":7012,"children":7013},{"style":122},[7014],{"type":34,"value":181},{"type":29,"tag":88,"props":7016,"children":7017},{"style":157},[7018],{"type":34,"value":5182},{"type":29,"tag":88,"props":7020,"children":7021},{"style":122},[7022],{"type":34,"value":357},{"type":29,"tag":88,"props":7024,"children":7025},{"class":90,"line":792},[7026],{"type":29,"tag":88,"props":7027,"children":7028},{"style":122},[7029],{"type":34,"value":442},{"type":29,"tag":6010,"props":7031,"children":7033},{"id":7032},"sagas-orchestration-explicite-des-séquences-longues",[7034],{"type":34,"value":7035},"Sagas : orchestration explicite des séquences longues",{"type":29,"tag":30,"props":7037,"children":7038},{},[7039,7041,7047],{"type":34,"value":7040},"Pour les transactions distribuées qui s'étendent sur plusieurs services, le pattern Saga, décrit par Vernon Vaughn dans \"Implementing Domain-Driven Design\", rend la séquence explicite et gère les compensations en cas d'échec partiel. Réduire ce couplage est aussi un objectif à inscrire dans un ",{"type":29,"tag":63,"props":7042,"children":7044},{"href":7043},"\u002Ffr\u002Fdette-technique\u002Fprogramme-refactoring-approuve-business",[7045],{"type":34,"value":7046},"programme de refactoring validé par le business",{"type":34,"value":7048},", pour que ces améliorations soient planifiées et financées correctement.",{"type":29,"tag":30,"props":7050,"children":7051},{},[7052],{"type":34,"value":7053},"Chorégraphié ou orchestré, le pattern Saga transforme une contrainte implicite d'ordre en protocole explicite avec gestion des cas d'échec.",{"type":29,"tag":6010,"props":7055,"children":7057},{"id":7056},"timeouts-explicites-sur-tous-les-appels-externes",[7058],{"type":34,"value":7059},"Timeouts explicites sur tous les appels externes",{"type":29,"tag":30,"props":7061,"children":7062},{},[7063],{"type":34,"value":7064},"Tout appel vers un service externe doit avoir un timeout défini par le code, pas par la valeur par défaut du client HTTP. Ce seul changement élimine la propagation en cascade lors des dégradations de services.",{"type":29,"tag":7066,"props":7067,"children":7068},"blockquote",{},[7069],{"type":29,"tag":30,"props":7070,"children":7071},{},[7072,7074,7080],{"type":34,"value":7073},"Dans la plateforme bancaire que j'évoquais en ouverture, l'introduction de l'idempotence sur le service de virement a résolu le problème définitivement en 3 jours de développement. Le bug était présent depuis 18 mois. 18 mois de corrections manuelles, de runbooks, de post-mortems, résolus par un ",{"type":29,"tag":84,"props":7075,"children":7077},{"className":7076},[],[7078],{"type":34,"value":7079},"idempotencyKey",{"type":34,"value":7081}," et une vérification de doublon.",{"type":29,"tag":47,"props":7083,"children":7084},{},[],{"type":29,"tag":51,"props":7086,"children":7088},{"id":7087},"la-règle-dor",[7089],{"type":34,"value":7090},"La règle d'or",{"type":29,"tag":30,"props":7092,"children":7093},{},[7094,7099],{"type":29,"tag":447,"props":7095,"children":7096},{},[7097],{"type":34,"value":7098},"Chaque opération asynchrone doit être idempotente et retriable.",{"type":34,"value":7100}," Si elle ne l'est pas, la contrainte temporelle qui en découle doit être rendue explicite et protégée par du code, pas par de la documentation.",{"type":29,"tag":30,"props":7102,"children":7103},{},[7104,7106,7111],{"type":34,"value":7105},"L'introduction de l'idempotence et des timeouts explicites sur les 5 à 10 flux les plus critiques réduit de ",{"type":29,"tag":447,"props":7107,"children":7108},{},[7109],{"type":34,"value":7110},"70 à 80%",{"type":34,"value":7112}," le risque associé au couplage temporel existant dans un système.",{"type":29,"tag":47,"props":7114,"children":7115},{},[],{"type":29,"tag":2288,"props":7117,"children":7119},{"cta":5629,"href":5630,"title":7118,"type":5632},"Maîtriser le couplage temporel n'est qu'une pratique : il en existe 100",[7120],{"type":29,"tag":30,"props":7121,"children":7122},{},[7123],{"type":34,"value":7124},"Rendre explicite une contrainte d'ordre, c'est une des pratiques craft qui séparent le code qui tient en prod du code qui tombe au premier pic de charge. Le Craft Bundle réunit les 100 pratiques que j'applique pour coder propre, celles que l'IA ne vous apprendra jamais parce qu'elle ne les a jamais vues casser un vendredi soir en astreinte.",{"type":29,"tag":47,"props":7126,"children":7127},{},[],{"type":29,"tag":51,"props":7129,"children":7131},{"id":7130},"faq-sur-le-couplage-temporel",[7132],{"type":34,"value":7133},"FAQ sur le couplage temporel",{"type":29,"tag":5649,"props":7135,"children":7136},{},[7137,7142],{"type":29,"tag":5653,"props":7138,"children":7139},{},[7140],{"type":34,"value":7141},"1. Quelle est la différence entre couplage temporel et couplage spatial ?",{"type":29,"tag":30,"props":7143,"children":7144},{},[7145],{"type":34,"value":7146},"Le couplage spatial (structural coupling) concerne la dépendance directe entre deux composants : A connaît et appelle B. Le couplage temporel concerne la dépendance sur l'ordre ou le timing : A doit s'exécuter avant B, ou A et B doivent s'exécuter dans la même fenêtre temporelle. Les deux sont des formes de couplage, mais le temporel est plus difficile à détecter car il n'apparaît pas dans les dépendances statiques du code. C'est précisément ce qui le rend dangereux.",{"type":29,"tag":5649,"props":7148,"children":7149},{},[7150,7155],{"type":29,"tag":5653,"props":7151,"children":7152},{},[7153],{"type":34,"value":7154},"2. Comment tester les problèmes de couplage temporel ?",{"type":29,"tag":30,"props":7156,"children":7157},{},[7158,7160,7166],{"type":34,"value":7159},"Le chaos engineering est la méthode la plus efficace : injecter des délais aléatoires sur les appels vers les services dépendants et observer si le système se comporte correctement. Les outils comme Chaos Monkey, Gremlin, ou Pumba permettent d'introduire des latences contrôlées en environnement de staging. Pour commencer sans outil spécifique : injecter un ",{"type":29,"tag":84,"props":7161,"children":7163},{"className":7162},[],[7164],{"type":34,"value":7165},"sleep(aléatoire)",{"type":34,"value":7167}," en environnement de test et vérifier que les timeouts et les garanties d'ordre fonctionnent comme attendu.",{"type":29,"tag":5649,"props":7169,"children":7170},{},[7171,7176],{"type":29,"tag":5653,"props":7172,"children":7173},{},[7174],{"type":34,"value":7175},"3. L'idempotence est-elle possible sur tous les types d'opérations ?",{"type":29,"tag":30,"props":7177,"children":7178},{},[7179],{"type":34,"value":7180},"Presque toujours, avec la bonne conception. La clé est l'idempotency key : un identifiant unique de la requête que le client génère et que le serveur utilise pour détecter les doublons. Les opérations financières, les envois d'emails, et les modifications d'état peuvent toutes être rendues idempotentes avec ce pattern. La seule limitation réelle concerne les opérations dont le résultat dépend de l'heure exacte, mais celles-ci peuvent être gérées avec un mécanisme de verrou temporel.",{"type":29,"tag":5649,"props":7182,"children":7183},{},[7184,7189],{"type":29,"tag":5653,"props":7185,"children":7186},{},[7187],{"type":34,"value":7188},"4. Quelle est la différence entre couplage temporel et race condition ?",{"type":29,"tag":30,"props":7190,"children":7191},{},[7192],{"type":34,"value":7193},"Une race condition est un cas particulier de couplage temporel : deux opérations concurrentes accèdent au même état partagé et le résultat dépend de l'ordre d'exécution. Le couplage temporel est plus large : il inclut aussi les séquences non-concurrentes qui doivent se dérouler dans un ordre précis. Toutes les race conditions sont des couplages temporels, mais tous les couplages temporels ne sont pas des race conditions.",{"type":29,"tag":47,"props":7195,"children":7196},{},[],{"type":29,"tag":2288,"props":7198,"children":7199},{"cta":5752,"href":5753,"title":5754,"type":5755},[7200],{"type":29,"tag":30,"props":7201,"children":7202},{},[7203],{"type":34,"value":7204},"L'Engineering Maturity Self-Assessment couvre le domaine Architecture & Résilience : évaluez votre niveau sur la gestion du couplage, les patterns asynchrones, et la robustesse de vos services. Score et recommandations en 10 minutes.",{"type":29,"tag":5763,"props":7206,"children":7207},{},[7208],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":7210},[7211,7212,7217,7218,7223,7224],{"id":5824,"depth":101,"text":5827},{"id":6005,"depth":101,"text":6008,"children":7213},[7214,7215,7216],{"id":6012,"depth":128,"text":6015},{"id":6038,"depth":128,"text":6041},{"id":6578,"depth":128,"text":6581},{"id":6614,"depth":101,"text":6617},{"id":6692,"depth":101,"text":6695,"children":7219},[7220,7221,7222],{"id":6698,"depth":128,"text":6701},{"id":7032,"depth":128,"text":7035},{"id":7056,"depth":128,"text":7059},{"id":7087,"depth":101,"text":7090},{"id":7130,"depth":101,"text":7133},"content:fr:architecture-craft:couplage-temporel-code-asynchrone.md","fr\u002Farchitecture-craft\u002Fcouplage-temporel-code-asynchrone.md","fr\u002Farchitecture-craft\u002Fcouplage-temporel-code-asynchrone",{"_path":65,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":7229,"description":7230,"id":409,"date":7231,"listed":13,"nocomments":7,"hidden":7,"categories":7232,"tags":7233,"cover":7234,"readingTime":7235,"body":7239,"_type":5777,"_id":9882,"_source":5779,"_file":9883,"_stem":9884,"_extension":5782},"Clean Architecture : les 3 règles qui suffisent","La Clean Architecture est souvent sur-implémentée. 3 règles fondamentales couvrent 80% de la valeur sans la complexité qui fait fuir les équipes.","2026-01-26",[6],[17,16],"covers\u002Farticles\u002Fclean-architecture-regles.jpg",{"text":21,"minutes":7236,"time":7237,"words":7238},8.615,516900,1723,{"type":26,"children":7240,"toc":9873},[7241,7246,7251,7256,7261,7264,7270,7275,7280,7285,7298,7301,7307,7312,7331,7339,7357,7810,7826,7829,7835,7840,7847,7888,8583,8593,8602,8605,8611,8616,8626,8633,8666,9699,9702,9708,9718,9728,9738,9741,9747,9757,9767,9776,9779,9785,9798,9811,9824,9837,9858,9861,9869],{"type":29,"tag":30,"props":7242,"children":7243},{},[7244],{"type":34,"value":7245},"J'accompagnais une équipe engineering chez Canal+ (20 développeurs). Une API de 45 endpoints, 4 ans de code accumulé, une couverture de tests à 28%. Les nouveaux développeurs atteignaient leur autonomie en 7 semaines. Pas parce qu'ils étaient mauvais, parce que le code était impossible à naviguer.",{"type":29,"tag":30,"props":7247,"children":7248},{},[7249],{"type":34,"value":7250},"Ils m'ont demandé si la Clean Architecture pouvait les aider. Ma réponse : oui, mais pas telle qu'on l'applique généralement.",{"type":29,"tag":30,"props":7252,"children":7253},{},[7254],{"type":34,"value":7255},"J'ai introduit 3 règles, pas les 8 couches du diagramme en cercles de Robert Martin. En 4 mois : couverture de tests passée de 28% à 67%, lead time baissé de 35%, onboarding raccourci de 7 à 3 semaines.",{"type":29,"tag":30,"props":7257,"children":7258},{},[7259],{"type":34,"value":7260},"La Clean Architecture n'est pas une religion. C'est un outil. Et comme tout outil, c'est la maîtrise qui compte, pas la conformité.",{"type":29,"tag":47,"props":7262,"children":7263},{},[],{"type":29,"tag":51,"props":7265,"children":7267},{"id":7266},"pourquoi-la-clean-architecture-divise-les-équipes",[7268],{"type":34,"value":7269},"Pourquoi la Clean Architecture divise les équipes",{"type":29,"tag":30,"props":7271,"children":7272},{},[7273],{"type":34,"value":7274},"L'architecture \"full Clean\" avec des entités, des use cases, des interfaces presenters, des controllers, des gateways se justifie dans des contextes spécifiques : applications complexes avec des règles métier riches, systèmes qui doivent changer de framework ou de base de données, projets long-terme avec de nombreux développeurs.",{"type":29,"tag":30,"props":7276,"children":7277},{},[7278],{"type":34,"value":7279},"Dans la plupart des contextes (une API REST de taille moyenne, une application en phase de croissance), la mise en place complète génère plus de complexité qu'elle n'en résout. Les symptômes sont toujours les mêmes : des dizaines de fichiers pour chaque feature, des indirections qui rendent le debug cauchemardesque, des juniors qui passent 3 jours à comprendre où écrire un bout de logique.",{"type":29,"tag":30,"props":7281,"children":7282},{},[7283],{"type":34,"value":7284},"Le problème n'est pas la Clean Architecture. C'est l'application dogmatique de sa forme sans en comprendre l'essence.",{"type":29,"tag":30,"props":7286,"children":7287},{},[7288,7290,7296],{"type":34,"value":7289},"Robert C. Martin (Uncle Bob) a formalisé ces principes dans son livre éponyme de 2017. Ce qu'il dit, et que beaucoup oublient : les couches ne sont pas une prescription rigide. Ce sont des guides. L'essence, elle, tient en 3 règles. Et quand une équipe adopte cette architecture, documenter les décisions structurantes dans des ",{"type":29,"tag":63,"props":7291,"children":7293},{"href":7292},"\u002Ffr\u002Farchitecture-craft\u002Fadr-architecture-decision-record",[7294],{"type":34,"value":7295},"Architecture Decision Records",{"type":34,"value":7297}," évite de refaire les mêmes débats à chaque nouveau développeur.",{"type":29,"tag":47,"props":7299,"children":7300},{},[],{"type":29,"tag":51,"props":7302,"children":7304},{"id":7303},"règle-1-la-règle-de-dépendance-les-flèches-pointent-vers-lintérieur",[7305],{"type":34,"value":7306},"Règle 1 : La règle de dépendance : les flèches pointent vers l'intérieur",{"type":29,"tag":30,"props":7308,"children":7309},{},[7310],{"type":34,"value":7311},"C'est la règle fondamentale. Dans un système bien architecturé, les modules de haut niveau (métier, règles business) ne doivent jamais dépendre des modules de bas niveau (frameworks, base de données, HTTP).",{"type":29,"tag":30,"props":7313,"children":7314},{},[7315,7317,7322,7324,7329],{"type":34,"value":7316},"La dépendance va dans une seule direction : ",{"type":29,"tag":447,"props":7318,"children":7319},{},[7320],{"type":34,"value":7321},"de l'extérieur vers l'intérieur",{"type":34,"value":7323},". Les couches externes dépendent des couches internes. Jamais l'inverse. C'est exactement ce que formule le ",{"type":29,"tag":63,"props":7325,"children":7326},{"href":5},[7327],{"type":34,"value":7328},"Dependency Inversion Principle",{"type":34,"value":7330},", et l'appliquer concrètement est le premier pas vers une codebase testable et maintenable.",{"type":29,"tag":30,"props":7332,"children":7333},{},[7334],{"type":29,"tag":447,"props":7335,"children":7336},{},[7337],{"type":34,"value":7338},"Ce que cela signifie concrètement :",{"type":29,"tag":453,"props":7340,"children":7341},{},[7342,7347,7352],{"type":29,"tag":457,"props":7343,"children":7344},{},[7345],{"type":34,"value":7346},"Votre logique métier ne doit pas importer Spring, Express, Django, ou aucun framework",{"type":29,"tag":457,"props":7348,"children":7349},{},[7350],{"type":34,"value":7351},"Votre logique métier ne doit pas importer de driver de base de données ou d'ORM",{"type":29,"tag":457,"props":7353,"children":7354},{},[7355],{"type":34,"value":7356},"Votre logique métier ne doit pas connaître le format HTTP (statut codes, headers)",{"type":29,"tag":77,"props":7358,"children":7360},{"className":81,"code":7359,"language":80,"meta":8,"style":8},"\u002F\u002F Mauvais : la logique métier dépend de Spring\n@Service\npublic class OrderService {\n    @Autowired\n    private OrderRepository repository; \u002F\u002F dépendance sur Spring Data\n\n    public void processOrder(Long orderId) {\n        Order order = repository.findById(orderId)\n            .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); \u002F\u002F dépendance sur Spring HTTP\n        \u002F\u002F logique métier...\n    }\n}\n\n\u002F\u002F Mieux : la logique métier ne connaît pas Spring\npublic class ProcessOrderUseCase {\n    private final OrderRepository repository; \u002F\u002F interface, pas Spring Data\n\n    public void execute(OrderId orderId) {\n        Order order = repository.findById(orderId)\n            .orElseThrow(() -> new OrderNotFoundException(orderId)); \u002F\u002F exception métier\n        \u002F\u002F logique métier pure...\n    }\n}\n",[7361],{"type":29,"tag":84,"props":7362,"children":7363},{"__ignoreMap":8},[7364,7372,7383,7402,7414,7438,7445,7481,7520,7576,7584,7591,7598,7605,7613,7633,7661,7668,7705,7744,7788,7796,7803],{"type":29,"tag":88,"props":7365,"children":7366},{"class":90,"line":91},[7367],{"type":29,"tag":88,"props":7368,"children":7369},{"style":95},[7370],{"type":34,"value":7371},"\u002F\u002F Mauvais : la logique métier dépend de Spring\n",{"type":29,"tag":88,"props":7373,"children":7374},{"class":90,"line":101},[7375,7379],{"type":29,"tag":88,"props":7376,"children":7377},{"style":1974},[7378],{"type":34,"value":1977},{"type":29,"tag":88,"props":7380,"children":7381},{"style":1980},[7382],{"type":34,"value":2536},{"type":29,"tag":88,"props":7384,"children":7385},{"class":90,"line":128},[7386,7390,7394,7398],{"type":29,"tag":88,"props":7387,"children":7388},{"style":105},[7389],{"type":34,"value":108},{"type":29,"tag":88,"props":7391,"children":7392},{"style":105},[7393],{"type":34,"value":113},{"type":29,"tag":88,"props":7395,"children":7396},{"style":116},[7397],{"type":34,"value":119},{"type":29,"tag":88,"props":7399,"children":7400},{"style":122},[7401],{"type":34,"value":125},{"type":29,"tag":88,"props":7403,"children":7404},{"class":90,"line":137},[7405,7409],{"type":29,"tag":88,"props":7406,"children":7407},{"style":1974},[7408],{"type":34,"value":3302},{"type":29,"tag":88,"props":7410,"children":7411},{"style":1980},[7412],{"type":34,"value":7413},"Autowired\n",{"type":29,"tag":88,"props":7415,"children":7416},{"class":90,"line":211},[7417,7421,7425,7429,7433],{"type":29,"tag":88,"props":7418,"children":7419},{"style":105},[7420],{"type":34,"value":143},{"type":29,"tag":88,"props":7422,"children":7423},{"style":151},[7424],{"type":34,"value":606},{"type":29,"tag":88,"props":7426,"children":7427},{"style":157},[7428],{"type":34,"value":785},{"type":29,"tag":88,"props":7430,"children":7431},{"style":122},[7432],{"type":34,"value":5893},{"type":29,"tag":88,"props":7434,"children":7435},{"style":95},[7436],{"type":34,"value":7437}," \u002F\u002F dépendance sur Spring Data\n",{"type":29,"tag":88,"props":7439,"children":7440},{"class":90,"line":262},[7441],{"type":29,"tag":88,"props":7442,"children":7443},{"emptyLinePlaceholder":13},[7444],{"type":34,"value":134},{"type":29,"tag":88,"props":7446,"children":7447},{"class":90,"line":270},[7448,7452,7456,7460,7464,7469,7473,7477],{"type":29,"tag":88,"props":7449,"children":7450},{"style":105},[7451],{"type":34,"value":276},{"type":29,"tag":88,"props":7453,"children":7454},{"style":105},[7455],{"type":34,"value":1303},{"type":29,"tag":88,"props":7457,"children":7458},{"style":174},[7459],{"type":34,"value":6079},{"type":29,"tag":88,"props":7461,"children":7462},{"style":122},[7463],{"type":34,"value":181},{"type":29,"tag":88,"props":7465,"children":7466},{"style":151},[7467],{"type":34,"value":7468},"Long",{"type":29,"tag":88,"props":7470,"children":7471},{"style":298},[7472],{"type":34,"value":402},{"type":29,"tag":88,"props":7474,"children":7475},{"style":122},[7476],{"type":34,"value":306},{"type":29,"tag":88,"props":7478,"children":7479},{"style":122},[7480],{"type":34,"value":125},{"type":29,"tag":88,"props":7482,"children":7483},{"class":90,"line":313},[7484,7488,7492,7496,7500,7504,7508,7512,7516],{"type":29,"tag":88,"props":7485,"children":7486},{"style":151},[7487],{"type":34,"value":4176},{"type":29,"tag":88,"props":7489,"children":7490},{"style":157},[7491],{"type":34,"value":4181},{"type":29,"tag":88,"props":7493,"children":7494},{"style":163},[7495],{"type":34,"value":166},{"type":29,"tag":88,"props":7497,"children":7498},{"style":157},[7499],{"type":34,"value":785},{"type":29,"tag":88,"props":7501,"children":7502},{"style":122},[7503],{"type":34,"value":338},{"type":29,"tag":88,"props":7505,"children":7506},{"style":174},[7507],{"type":34,"value":3112},{"type":29,"tag":88,"props":7509,"children":7510},{"style":122},[7511],{"type":34,"value":181},{"type":29,"tag":88,"props":7513,"children":7514},{"style":157},[7515],{"type":34,"value":1836},{"type":29,"tag":88,"props":7517,"children":7518},{"style":122},[7519],{"type":34,"value":3078},{"type":29,"tag":88,"props":7521,"children":7522},{"class":90,"line":360},[7523,7527,7531,7535,7539,7543,7548,7552,7557,7561,7566,7571],{"type":29,"tag":88,"props":7524,"children":7525},{"style":122},[7526],{"type":34,"value":3132},{"type":29,"tag":88,"props":7528,"children":7529},{"style":174},[7530],{"type":34,"value":3137},{"type":29,"tag":88,"props":7532,"children":7533},{"style":122},[7534],{"type":34,"value":3142},{"type":29,"tag":88,"props":7536,"children":7537},{"style":105},[7538],{"type":34,"value":3147},{"type":29,"tag":88,"props":7540,"children":7541},{"style":105},[7542],{"type":34,"value":171},{"type":29,"tag":88,"props":7544,"children":7545},{"style":174},[7546],{"type":34,"value":7547}," ResponseStatusException",{"type":29,"tag":88,"props":7549,"children":7550},{"style":122},[7551],{"type":34,"value":181},{"type":29,"tag":88,"props":7553,"children":7554},{"style":157},[7555],{"type":34,"value":7556},"HttpStatus",{"type":29,"tag":88,"props":7558,"children":7559},{"style":122},[7560],{"type":34,"value":338},{"type":29,"tag":88,"props":7562,"children":7563},{"style":157},[7564],{"type":34,"value":7565},"NOT_FOUND",{"type":29,"tag":88,"props":7567,"children":7568},{"style":122},[7569],{"type":34,"value":7570},"));",{"type":29,"tag":88,"props":7572,"children":7573},{"style":95},[7574],{"type":34,"value":7575}," \u002F\u002F dépendance sur Spring HTTP\n",{"type":29,"tag":88,"props":7577,"children":7578},{"class":90,"line":409},[7579],{"type":29,"tag":88,"props":7580,"children":7581},{"style":95},[7582],{"type":34,"value":7583},"        \u002F\u002F logique métier...\n",{"type":29,"tag":88,"props":7585,"children":7586},{"class":90,"line":427},[7587],{"type":29,"tag":88,"props":7588,"children":7589},{"style":122},[7590],{"type":34,"value":433},{"type":29,"tag":88,"props":7592,"children":7593},{"class":90,"line":436},[7594],{"type":29,"tag":88,"props":7595,"children":7596},{"style":122},[7597],{"type":34,"value":442},{"type":29,"tag":88,"props":7599,"children":7600},{"class":90,"line":767},[7601],{"type":29,"tag":88,"props":7602,"children":7603},{"emptyLinePlaceholder":13},[7604],{"type":34,"value":134},{"type":29,"tag":88,"props":7606,"children":7607},{"class":90,"line":792},[7608],{"type":29,"tag":88,"props":7609,"children":7610},{"style":95},[7611],{"type":34,"value":7612},"\u002F\u002F Mieux : la logique métier ne connaît pas Spring\n",{"type":29,"tag":88,"props":7614,"children":7615},{"class":90,"line":817},[7616,7620,7624,7629],{"type":29,"tag":88,"props":7617,"children":7618},{"style":105},[7619],{"type":34,"value":108},{"type":29,"tag":88,"props":7621,"children":7622},{"style":105},[7623],{"type":34,"value":113},{"type":29,"tag":88,"props":7625,"children":7626},{"style":116},[7627],{"type":34,"value":7628}," ProcessOrderUseCase",{"type":29,"tag":88,"props":7630,"children":7631},{"style":122},[7632],{"type":34,"value":125},{"type":29,"tag":88,"props":7634,"children":7635},{"class":90,"line":825},[7636,7640,7644,7648,7652,7656],{"type":29,"tag":88,"props":7637,"children":7638},{"style":105},[7639],{"type":34,"value":143},{"type":29,"tag":88,"props":7641,"children":7642},{"style":105},[7643],{"type":34,"value":148},{"type":29,"tag":88,"props":7645,"children":7646},{"style":151},[7647],{"type":34,"value":606},{"type":29,"tag":88,"props":7649,"children":7650},{"style":157},[7651],{"type":34,"value":785},{"type":29,"tag":88,"props":7653,"children":7654},{"style":122},[7655],{"type":34,"value":5893},{"type":29,"tag":88,"props":7657,"children":7658},{"style":95},[7659],{"type":34,"value":7660}," \u002F\u002F interface, pas Spring Data\n",{"type":29,"tag":88,"props":7662,"children":7663},{"class":90,"line":869},[7664],{"type":29,"tag":88,"props":7665,"children":7666},{"emptyLinePlaceholder":13},[7667],{"type":34,"value":134},{"type":29,"tag":88,"props":7669,"children":7670},{"class":90,"line":900},[7671,7675,7679,7684,7688,7693,7697,7701],{"type":29,"tag":88,"props":7672,"children":7673},{"style":105},[7674],{"type":34,"value":276},{"type":29,"tag":88,"props":7676,"children":7677},{"style":105},[7678],{"type":34,"value":1303},{"type":29,"tag":88,"props":7680,"children":7681},{"style":174},[7682],{"type":34,"value":7683}," execute",{"type":29,"tag":88,"props":7685,"children":7686},{"style":122},[7687],{"type":34,"value":181},{"type":29,"tag":88,"props":7689,"children":7690},{"style":151},[7691],{"type":34,"value":7692},"OrderId",{"type":29,"tag":88,"props":7694,"children":7695},{"style":298},[7696],{"type":34,"value":402},{"type":29,"tag":88,"props":7698,"children":7699},{"style":122},[7700],{"type":34,"value":306},{"type":29,"tag":88,"props":7702,"children":7703},{"style":122},[7704],{"type":34,"value":125},{"type":29,"tag":88,"props":7706,"children":7707},{"class":90,"line":929},[7708,7712,7716,7720,7724,7728,7732,7736,7740],{"type":29,"tag":88,"props":7709,"children":7710},{"style":151},[7711],{"type":34,"value":4176},{"type":29,"tag":88,"props":7713,"children":7714},{"style":157},[7715],{"type":34,"value":4181},{"type":29,"tag":88,"props":7717,"children":7718},{"style":163},[7719],{"type":34,"value":166},{"type":29,"tag":88,"props":7721,"children":7722},{"style":157},[7723],{"type":34,"value":785},{"type":29,"tag":88,"props":7725,"children":7726},{"style":122},[7727],{"type":34,"value":338},{"type":29,"tag":88,"props":7729,"children":7730},{"style":174},[7731],{"type":34,"value":3112},{"type":29,"tag":88,"props":7733,"children":7734},{"style":122},[7735],{"type":34,"value":181},{"type":29,"tag":88,"props":7737,"children":7738},{"style":157},[7739],{"type":34,"value":1836},{"type":29,"tag":88,"props":7741,"children":7742},{"style":122},[7743],{"type":34,"value":3078},{"type":29,"tag":88,"props":7745,"children":7746},{"class":90,"line":937},[7747,7751,7755,7759,7763,7767,7771,7775,7779,7783],{"type":29,"tag":88,"props":7748,"children":7749},{"style":122},[7750],{"type":34,"value":3132},{"type":29,"tag":88,"props":7752,"children":7753},{"style":174},[7754],{"type":34,"value":3137},{"type":29,"tag":88,"props":7756,"children":7757},{"style":122},[7758],{"type":34,"value":3142},{"type":29,"tag":88,"props":7760,"children":7761},{"style":105},[7762],{"type":34,"value":3147},{"type":29,"tag":88,"props":7764,"children":7765},{"style":105},[7766],{"type":34,"value":171},{"type":29,"tag":88,"props":7768,"children":7769},{"style":174},[7770],{"type":34,"value":5100},{"type":29,"tag":88,"props":7772,"children":7773},{"style":122},[7774],{"type":34,"value":181},{"type":29,"tag":88,"props":7776,"children":7777},{"style":157},[7778],{"type":34,"value":1836},{"type":29,"tag":88,"props":7780,"children":7781},{"style":122},[7782],{"type":34,"value":7570},{"type":29,"tag":88,"props":7784,"children":7785},{"style":95},[7786],{"type":34,"value":7787}," \u002F\u002F exception métier\n",{"type":29,"tag":88,"props":7789,"children":7790},{"class":90,"line":945},[7791],{"type":29,"tag":88,"props":7792,"children":7793},{"style":95},[7794],{"type":34,"value":7795},"        \u002F\u002F logique métier pure...\n",{"type":29,"tag":88,"props":7797,"children":7798},{"class":90,"line":981},[7799],{"type":29,"tag":88,"props":7800,"children":7801},{"style":122},[7802],{"type":34,"value":433},{"type":29,"tag":88,"props":7804,"children":7805},{"class":90,"line":1021},[7806],{"type":29,"tag":88,"props":7807,"children":7808},{"style":122},[7809],{"type":34,"value":442},{"type":29,"tag":30,"props":7811,"children":7812},{},[7813,7818,7820,7824],{"type":29,"tag":447,"props":7814,"children":7815},{},[7816],{"type":34,"value":7817},"Pourquoi c'est important :",{"type":34,"value":7819}," si votre logique métier est indépendante des frameworks, vous pouvez la tester sans démarrer de serveur HTTP et sans base de données. Vos tests métier s'exécutent en millisecondes, ce qui résout précisément le problème des ",{"type":29,"tag":63,"props":7821,"children":7822},{"href":5618},[7823],{"type":34,"value":5621},{"type":34,"value":7825}," où chaque test démarre une vraie infrastructure. Et si vous changez de framework un jour, la logique métier n'est pas touchée.",{"type":29,"tag":47,"props":7827,"children":7828},{},[],{"type":29,"tag":51,"props":7830,"children":7832},{"id":7831},"règle-2-les-entités-métier-ne-connaissent-pas-linfrastructure",[7833],{"type":34,"value":7834},"Règle 2 : Les entités métier ne connaissent pas l'infrastructure",{"type":29,"tag":30,"props":7836,"children":7837},{},[7838],{"type":34,"value":7839},"Vos objets métier (Order, User, Product, Contract) doivent pouvoir exister et être testés sans base de données, sans framework de persistance, sans format de sérialisation.",{"type":29,"tag":30,"props":7841,"children":7842},{},[7843],{"type":29,"tag":447,"props":7844,"children":7845},{},[7846],{"type":34,"value":7338},{"type":29,"tag":453,"props":7848,"children":7849},{},[7850,7870,7883],{"type":29,"tag":457,"props":7851,"children":7852},{},[7853,7855,7861,7862,7868],{"type":34,"value":7854},"Pas d'annotations JPA (",{"type":29,"tag":84,"props":7856,"children":7858},{"className":7857},[],[7859],{"type":34,"value":7860},"@Entity",{"type":34,"value":544},{"type":29,"tag":84,"props":7863,"children":7865},{"className":7864},[],[7866],{"type":34,"value":7867},"@Column",{"type":34,"value":7869},") sur vos classes métier",{"type":29,"tag":457,"props":7871,"children":7872},{},[7873,7875,7881],{"type":34,"value":7874},"Pas de décorateurs de sérialisation (",{"type":29,"tag":84,"props":7876,"children":7878},{"className":7877},[],[7879],{"type":34,"value":7880},"@JsonProperty",{"type":34,"value":7882},") sur vos domaines objects",{"type":29,"tag":457,"props":7884,"children":7885},{},[7886],{"type":34,"value":7887},"Pas d'héritage de classes framework dans vos entités métier",{"type":29,"tag":77,"props":7889,"children":7891},{"className":81,"code":7890,"language":80,"meta":8,"style":8},"\u002F\u002F Entité métier polluée par l'infrastructure\n@Entity\n@Table(name = \"orders\")\npublic class Order {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    @ApiModelProperty  \u002F\u002F annotation Swagger\n    private Long id;\n\n    @Column(nullable = false)\n    @NotEmpty          \u002F\u002F annotation validation HTTP\n    private Long customerId;\n}\n\n\u002F\u002F Entité métier pure : aucune annotation framework\npublic class Order {\n    private final OrderId id;\n    private final CustomerId customerId;\n    private OrderStatus status;\n\n    public Order(OrderId id, CustomerId customerId, OrderStatus status) {\n        this.id = id;\n        this.customerId = customerId;\n        this.status = status;\n    }\n\n    public void confirm() {\n        if (this.status != OrderStatus.PENDING) {\n            throw new OrderAlreadyConfirmedException(this.id);\n        }\n        this.status = OrderStatus.CONFIRMED;\n    }\n}\n\u002F\u002F La persistance est gérée par une entité JPA séparée dans la couche infrastructure\n",[7892],{"type":29,"tag":84,"props":7893,"children":7894},{"__ignoreMap":8},[7895,7903,7915,7949,7968,7980,8023,8040,8060,8067,8101,8118,8138,8145,8152,8160,8179,8203,8227,8248,8255,8310,8338,8366,8394,8401,8408,8432,8482,8518,8525,8561,8568,8575],{"type":29,"tag":88,"props":7896,"children":7897},{"class":90,"line":91},[7898],{"type":29,"tag":88,"props":7899,"children":7900},{"style":95},[7901],{"type":34,"value":7902},"\u002F\u002F Entité métier polluée par l'infrastructure\n",{"type":29,"tag":88,"props":7904,"children":7905},{"class":90,"line":101},[7906,7910],{"type":29,"tag":88,"props":7907,"children":7908},{"style":1974},[7909],{"type":34,"value":1977},{"type":29,"tag":88,"props":7911,"children":7912},{"style":1980},[7913],{"type":34,"value":7914},"Entity\n",{"type":29,"tag":88,"props":7916,"children":7917},{"class":90,"line":128},[7918,7922,7927,7931,7936,7940,7945],{"type":29,"tag":88,"props":7919,"children":7920},{"style":1974},[7921],{"type":34,"value":1977},{"type":29,"tag":88,"props":7923,"children":7924},{"style":1980},[7925],{"type":34,"value":7926},"Table",{"type":29,"tag":88,"props":7928,"children":7929},{"style":122},[7930],{"type":34,"value":181},{"type":29,"tag":88,"props":7932,"children":7933},{"style":6106},[7934],{"type":34,"value":7935},"name",{"type":29,"tag":88,"props":7937,"children":7938},{"style":163},[7939],{"type":34,"value":6113},{"type":29,"tag":88,"props":7941,"children":7942},{"style":184},[7943],{"type":34,"value":7944}," \"orders\"",{"type":29,"tag":88,"props":7946,"children":7947},{"style":122},[7948],{"type":34,"value":3078},{"type":29,"tag":88,"props":7950,"children":7951},{"class":90,"line":137},[7952,7956,7960,7964],{"type":29,"tag":88,"props":7953,"children":7954},{"style":105},[7955],{"type":34,"value":108},{"type":29,"tag":88,"props":7957,"children":7958},{"style":105},[7959],{"type":34,"value":113},{"type":29,"tag":88,"props":7961,"children":7962},{"style":116},[7963],{"type":34,"value":2740},{"type":29,"tag":88,"props":7965,"children":7966},{"style":122},[7967],{"type":34,"value":125},{"type":29,"tag":88,"props":7969,"children":7970},{"class":90,"line":211},[7971,7975],{"type":29,"tag":88,"props":7972,"children":7973},{"style":1974},[7974],{"type":34,"value":3302},{"type":29,"tag":88,"props":7976,"children":7977},{"style":1980},[7978],{"type":34,"value":7979},"Id\n",{"type":29,"tag":88,"props":7981,"children":7982},{"class":90,"line":262},[7983,7987,7992,7996,8001,8005,8010,8014,8019],{"type":29,"tag":88,"props":7984,"children":7985},{"style":1974},[7986],{"type":34,"value":3302},{"type":29,"tag":88,"props":7988,"children":7989},{"style":1980},[7990],{"type":34,"value":7991},"GeneratedValue",{"type":29,"tag":88,"props":7993,"children":7994},{"style":122},[7995],{"type":34,"value":181},{"type":29,"tag":88,"props":7997,"children":7998},{"style":6106},[7999],{"type":34,"value":8000},"strategy",{"type":29,"tag":88,"props":8002,"children":8003},{"style":163},[8004],{"type":34,"value":6113},{"type":29,"tag":88,"props":8006,"children":8007},{"style":157},[8008],{"type":34,"value":8009}," GenerationType",{"type":29,"tag":88,"props":8011,"children":8012},{"style":122},[8013],{"type":34,"value":338},{"type":29,"tag":88,"props":8015,"children":8016},{"style":157},[8017],{"type":34,"value":8018},"IDENTITY",{"type":29,"tag":88,"props":8020,"children":8021},{"style":122},[8022],{"type":34,"value":3078},{"type":29,"tag":88,"props":8024,"children":8025},{"class":90,"line":270},[8026,8030,8035],{"type":29,"tag":88,"props":8027,"children":8028},{"style":1974},[8029],{"type":34,"value":3302},{"type":29,"tag":88,"props":8031,"children":8032},{"style":1980},[8033],{"type":34,"value":8034},"ApiModelProperty",{"type":29,"tag":88,"props":8036,"children":8037},{"style":95},[8038],{"type":34,"value":8039},"  \u002F\u002F annotation Swagger\n",{"type":29,"tag":88,"props":8041,"children":8042},{"class":90,"line":313},[8043,8047,8052,8056],{"type":29,"tag":88,"props":8044,"children":8045},{"style":105},[8046],{"type":34,"value":143},{"type":29,"tag":88,"props":8048,"children":8049},{"style":151},[8050],{"type":34,"value":8051}," Long",{"type":29,"tag":88,"props":8053,"children":8054},{"style":157},[8055],{"type":34,"value":3435},{"type":29,"tag":88,"props":8057,"children":8058},{"style":122},[8059],{"type":34,"value":424},{"type":29,"tag":88,"props":8061,"children":8062},{"class":90,"line":360},[8063],{"type":29,"tag":88,"props":8064,"children":8065},{"emptyLinePlaceholder":13},[8066],{"type":34,"value":134},{"type":29,"tag":88,"props":8068,"children":8069},{"class":90,"line":409},[8070,8074,8079,8083,8088,8092,8097],{"type":29,"tag":88,"props":8071,"children":8072},{"style":1974},[8073],{"type":34,"value":3302},{"type":29,"tag":88,"props":8075,"children":8076},{"style":1980},[8077],{"type":34,"value":8078},"Column",{"type":29,"tag":88,"props":8080,"children":8081},{"style":122},[8082],{"type":34,"value":181},{"type":29,"tag":88,"props":8084,"children":8085},{"style":6106},[8086],{"type":34,"value":8087},"nullable",{"type":29,"tag":88,"props":8089,"children":8090},{"style":163},[8091],{"type":34,"value":6113},{"type":29,"tag":88,"props":8093,"children":8094},{"style":873},[8095],{"type":34,"value":8096}," false",{"type":29,"tag":88,"props":8098,"children":8099},{"style":122},[8100],{"type":34,"value":3078},{"type":29,"tag":88,"props":8102,"children":8103},{"class":90,"line":427},[8104,8108,8113],{"type":29,"tag":88,"props":8105,"children":8106},{"style":1974},[8107],{"type":34,"value":3302},{"type":29,"tag":88,"props":8109,"children":8110},{"style":1980},[8111],{"type":34,"value":8112},"NotEmpty",{"type":29,"tag":88,"props":8114,"children":8115},{"style":95},[8116],{"type":34,"value":8117},"          \u002F\u002F annotation validation HTTP\n",{"type":29,"tag":88,"props":8119,"children":8120},{"class":90,"line":436},[8121,8125,8129,8134],{"type":29,"tag":88,"props":8122,"children":8123},{"style":105},[8124],{"type":34,"value":143},{"type":29,"tag":88,"props":8126,"children":8127},{"style":151},[8128],{"type":34,"value":8051},{"type":29,"tag":88,"props":8130,"children":8131},{"style":157},[8132],{"type":34,"value":8133}," customerId",{"type":29,"tag":88,"props":8135,"children":8136},{"style":122},[8137],{"type":34,"value":424},{"type":29,"tag":88,"props":8139,"children":8140},{"class":90,"line":767},[8141],{"type":29,"tag":88,"props":8142,"children":8143},{"style":122},[8144],{"type":34,"value":442},{"type":29,"tag":88,"props":8146,"children":8147},{"class":90,"line":792},[8148],{"type":29,"tag":88,"props":8149,"children":8150},{"emptyLinePlaceholder":13},[8151],{"type":34,"value":134},{"type":29,"tag":88,"props":8153,"children":8154},{"class":90,"line":817},[8155],{"type":29,"tag":88,"props":8156,"children":8157},{"style":95},[8158],{"type":34,"value":8159},"\u002F\u002F Entité métier pure : aucune annotation framework\n",{"type":29,"tag":88,"props":8161,"children":8162},{"class":90,"line":825},[8163,8167,8171,8175],{"type":29,"tag":88,"props":8164,"children":8165},{"style":105},[8166],{"type":34,"value":108},{"type":29,"tag":88,"props":8168,"children":8169},{"style":105},[8170],{"type":34,"value":113},{"type":29,"tag":88,"props":8172,"children":8173},{"style":116},[8174],{"type":34,"value":2740},{"type":29,"tag":88,"props":8176,"children":8177},{"style":122},[8178],{"type":34,"value":125},{"type":29,"tag":88,"props":8180,"children":8181},{"class":90,"line":869},[8182,8186,8190,8195,8199],{"type":29,"tag":88,"props":8183,"children":8184},{"style":105},[8185],{"type":34,"value":143},{"type":29,"tag":88,"props":8187,"children":8188},{"style":105},[8189],{"type":34,"value":148},{"type":29,"tag":88,"props":8191,"children":8192},{"style":151},[8193],{"type":34,"value":8194}," OrderId",{"type":29,"tag":88,"props":8196,"children":8197},{"style":157},[8198],{"type":34,"value":3435},{"type":29,"tag":88,"props":8200,"children":8201},{"style":122},[8202],{"type":34,"value":424},{"type":29,"tag":88,"props":8204,"children":8205},{"class":90,"line":900},[8206,8210,8214,8219,8223],{"type":29,"tag":88,"props":8207,"children":8208},{"style":105},[8209],{"type":34,"value":143},{"type":29,"tag":88,"props":8211,"children":8212},{"style":105},[8213],{"type":34,"value":148},{"type":29,"tag":88,"props":8215,"children":8216},{"style":151},[8217],{"type":34,"value":8218}," CustomerId",{"type":29,"tag":88,"props":8220,"children":8221},{"style":157},[8222],{"type":34,"value":8133},{"type":29,"tag":88,"props":8224,"children":8225},{"style":122},[8226],{"type":34,"value":424},{"type":29,"tag":88,"props":8228,"children":8229},{"class":90,"line":929},[8230,8234,8239,8244],{"type":29,"tag":88,"props":8231,"children":8232},{"style":105},[8233],{"type":34,"value":143},{"type":29,"tag":88,"props":8235,"children":8236},{"style":151},[8237],{"type":34,"value":8238}," OrderStatus",{"type":29,"tag":88,"props":8240,"children":8241},{"style":157},[8242],{"type":34,"value":8243}," status",{"type":29,"tag":88,"props":8245,"children":8246},{"style":122},[8247],{"type":34,"value":424},{"type":29,"tag":88,"props":8249,"children":8250},{"class":90,"line":937},[8251],{"type":29,"tag":88,"props":8252,"children":8253},{"emptyLinePlaceholder":13},[8254],{"type":34,"value":134},{"type":29,"tag":88,"props":8256,"children":8257},{"class":90,"line":945},[8258,8262,8266,8270,8274,8278,8282,8286,8290,8294,8298,8302,8306],{"type":29,"tag":88,"props":8259,"children":8260},{"style":105},[8261],{"type":34,"value":276},{"type":29,"tag":88,"props":8263,"children":8264},{"style":174},[8265],{"type":34,"value":2740},{"type":29,"tag":88,"props":8267,"children":8268},{"style":122},[8269],{"type":34,"value":181},{"type":29,"tag":88,"props":8271,"children":8272},{"style":151},[8273],{"type":34,"value":7692},{"type":29,"tag":88,"props":8275,"children":8276},{"style":298},[8277],{"type":34,"value":3435},{"type":29,"tag":88,"props":8279,"children":8280},{"style":122},[8281],{"type":34,"value":192},{"type":29,"tag":88,"props":8283,"children":8284},{"style":151},[8285],{"type":34,"value":8218},{"type":29,"tag":88,"props":8287,"children":8288},{"style":298},[8289],{"type":34,"value":8133},{"type":29,"tag":88,"props":8291,"children":8292},{"style":122},[8293],{"type":34,"value":192},{"type":29,"tag":88,"props":8295,"children":8296},{"style":151},[8297],{"type":34,"value":8238},{"type":29,"tag":88,"props":8299,"children":8300},{"style":298},[8301],{"type":34,"value":8243},{"type":29,"tag":88,"props":8303,"children":8304},{"style":122},[8305],{"type":34,"value":306},{"type":29,"tag":88,"props":8307,"children":8308},{"style":122},[8309],{"type":34,"value":125},{"type":29,"tag":88,"props":8311,"children":8312},{"class":90,"line":981},[8313,8317,8321,8326,8330,8334],{"type":29,"tag":88,"props":8314,"children":8315},{"style":873},[8316],{"type":34,"value":876},{"type":29,"tag":88,"props":8318,"children":8319},{"style":122},[8320],{"type":34,"value":338},{"type":29,"tag":88,"props":8322,"children":8323},{"style":157},[8324],{"type":34,"value":8325},"id ",{"type":29,"tag":88,"props":8327,"children":8328},{"style":163},[8329],{"type":34,"value":166},{"type":29,"tag":88,"props":8331,"children":8332},{"style":157},[8333],{"type":34,"value":3435},{"type":29,"tag":88,"props":8335,"children":8336},{"style":122},[8337],{"type":34,"value":424},{"type":29,"tag":88,"props":8339,"children":8340},{"class":90,"line":1021},[8341,8345,8349,8354,8358,8362],{"type":29,"tag":88,"props":8342,"children":8343},{"style":873},[8344],{"type":34,"value":876},{"type":29,"tag":88,"props":8346,"children":8347},{"style":122},[8348],{"type":34,"value":338},{"type":29,"tag":88,"props":8350,"children":8351},{"style":157},[8352],{"type":34,"value":8353},"customerId ",{"type":29,"tag":88,"props":8355,"children":8356},{"style":163},[8357],{"type":34,"value":166},{"type":29,"tag":88,"props":8359,"children":8360},{"style":157},[8361],{"type":34,"value":8133},{"type":29,"tag":88,"props":8363,"children":8364},{"style":122},[8365],{"type":34,"value":424},{"type":29,"tag":88,"props":8367,"children":8368},{"class":90,"line":1066},[8369,8373,8377,8382,8386,8390],{"type":29,"tag":88,"props":8370,"children":8371},{"style":873},[8372],{"type":34,"value":876},{"type":29,"tag":88,"props":8374,"children":8375},{"style":122},[8376],{"type":34,"value":338},{"type":29,"tag":88,"props":8378,"children":8379},{"style":157},[8380],{"type":34,"value":8381},"status ",{"type":29,"tag":88,"props":8383,"children":8384},{"style":163},[8385],{"type":34,"value":166},{"type":29,"tag":88,"props":8387,"children":8388},{"style":157},[8389],{"type":34,"value":8243},{"type":29,"tag":88,"props":8391,"children":8392},{"style":122},[8393],{"type":34,"value":424},{"type":29,"tag":88,"props":8395,"children":8396},{"class":90,"line":1082},[8397],{"type":29,"tag":88,"props":8398,"children":8399},{"style":122},[8400],{"type":34,"value":433},{"type":29,"tag":88,"props":8402,"children":8403},{"class":90,"line":1090},[8404],{"type":29,"tag":88,"props":8405,"children":8406},{"emptyLinePlaceholder":13},[8407],{"type":34,"value":134},{"type":29,"tag":88,"props":8409,"children":8410},{"class":90,"line":1098},[8411,8415,8419,8424,8428],{"type":29,"tag":88,"props":8412,"children":8413},{"style":105},[8414],{"type":34,"value":276},{"type":29,"tag":88,"props":8416,"children":8417},{"style":105},[8418],{"type":34,"value":1303},{"type":29,"tag":88,"props":8420,"children":8421},{"style":174},[8422],{"type":34,"value":8423}," confirm",{"type":29,"tag":88,"props":8425,"children":8426},{"style":122},[8427],{"type":34,"value":1470},{"type":29,"tag":88,"props":8429,"children":8430},{"style":122},[8431],{"type":34,"value":125},{"type":29,"tag":88,"props":8433,"children":8434},{"class":90,"line":1106},[8435,8439,8443,8448,8452,8456,8461,8465,8469,8474,8478],{"type":29,"tag":88,"props":8436,"children":8437},{"style":105},[8438],{"type":34,"value":2886},{"type":29,"tag":88,"props":8440,"children":8441},{"style":122},[8442],{"type":34,"value":2891},{"type":29,"tag":88,"props":8444,"children":8445},{"style":873},[8446],{"type":34,"value":8447},"this",{"type":29,"tag":88,"props":8449,"children":8450},{"style":122},[8451],{"type":34,"value":338},{"type":29,"tag":88,"props":8453,"children":8454},{"style":157},[8455],{"type":34,"value":8381},{"type":29,"tag":88,"props":8457,"children":8458},{"style":163},[8459],{"type":34,"value":8460},"!=",{"type":29,"tag":88,"props":8462,"children":8463},{"style":157},[8464],{"type":34,"value":8238},{"type":29,"tag":88,"props":8466,"children":8467},{"style":122},[8468],{"type":34,"value":338},{"type":29,"tag":88,"props":8470,"children":8471},{"style":157},[8472],{"type":34,"value":8473},"PENDING",{"type":29,"tag":88,"props":8475,"children":8476},{"style":122},[8477],{"type":34,"value":306},{"type":29,"tag":88,"props":8479,"children":8480},{"style":122},[8481],{"type":34,"value":125},{"type":29,"tag":88,"props":8483,"children":8484},{"class":90,"line":1115},[8485,8489,8493,8498,8502,8506,8510,8514],{"type":29,"tag":88,"props":8486,"children":8487},{"style":105},[8488],{"type":34,"value":2927},{"type":29,"tag":88,"props":8490,"children":8491},{"style":105},[8492],{"type":34,"value":171},{"type":29,"tag":88,"props":8494,"children":8495},{"style":174},[8496],{"type":34,"value":8497}," OrderAlreadyConfirmedException",{"type":29,"tag":88,"props":8499,"children":8500},{"style":122},[8501],{"type":34,"value":181},{"type":29,"tag":88,"props":8503,"children":8504},{"style":873},[8505],{"type":34,"value":8447},{"type":29,"tag":88,"props":8507,"children":8508},{"style":122},[8509],{"type":34,"value":338},{"type":29,"tag":88,"props":8511,"children":8512},{"style":157},[8513],{"type":34,"value":3410},{"type":29,"tag":88,"props":8515,"children":8516},{"style":122},[8517],{"type":34,"value":357},{"type":29,"tag":88,"props":8519,"children":8520},{"class":90,"line":11},[8521],{"type":29,"tag":88,"props":8522,"children":8523},{"style":122},[8524],{"type":34,"value":2966},{"type":29,"tag":88,"props":8526,"children":8527},{"class":90,"line":1180},[8528,8532,8536,8540,8544,8548,8552,8557],{"type":29,"tag":88,"props":8529,"children":8530},{"style":873},[8531],{"type":34,"value":876},{"type":29,"tag":88,"props":8533,"children":8534},{"style":122},[8535],{"type":34,"value":338},{"type":29,"tag":88,"props":8537,"children":8538},{"style":157},[8539],{"type":34,"value":8381},{"type":29,"tag":88,"props":8541,"children":8542},{"style":163},[8543],{"type":34,"value":166},{"type":29,"tag":88,"props":8545,"children":8546},{"style":157},[8547],{"type":34,"value":8238},{"type":29,"tag":88,"props":8549,"children":8550},{"style":122},[8551],{"type":34,"value":338},{"type":29,"tag":88,"props":8553,"children":8554},{"style":157},[8555],{"type":34,"value":8556},"CONFIRMED",{"type":29,"tag":88,"props":8558,"children":8559},{"style":122},[8560],{"type":34,"value":424},{"type":29,"tag":88,"props":8562,"children":8563},{"class":90,"line":1240},[8564],{"type":29,"tag":88,"props":8565,"children":8566},{"style":122},[8567],{"type":34,"value":433},{"type":29,"tag":88,"props":8569,"children":8570},{"class":90,"line":1248},[8571],{"type":29,"tag":88,"props":8572,"children":8573},{"style":122},[8574],{"type":34,"value":442},{"type":29,"tag":88,"props":8576,"children":8577},{"class":90,"line":1256},[8578],{"type":29,"tag":88,"props":8579,"children":8580},{"style":95},[8581],{"type":34,"value":8582},"\u002F\u002F La persistance est gérée par une entité JPA séparée dans la couche infrastructure\n",{"type":29,"tag":30,"props":8584,"children":8585},{},[8586,8591],{"type":29,"tag":447,"props":8587,"children":8588},{},[8589],{"type":34,"value":8590},"L'erreur courante :",{"type":34,"value":8592}," mettre les annotations de persistance directement sur les objets métier par pragmatisme. Ça fonctionne pour les petites applications. Sur une application qui grandit, ça crée un couplage fort entre la représentation métier et le schéma de base de données, deux choses qui évoluent à des rythmes différents.",{"type":29,"tag":2288,"props":8594,"children":8596},{"cta":2290,"href":2291,"title":8595,"type":2293},"Vous voulez savoir où placer la frontière entre métier et infrastructure, sur votre vrai code ?",[8597],{"type":29,"tag":30,"props":8598,"children":8599},{},[8600],{"type":34,"value":8601},"Décider quelle annotation polluer, quel objet garder pur, où tracer la règle de dépendance, ça ne se lit pas dans un article : ça se travaille sur votre codebase. En mentoring 1:1, je relis vos use cases et vos entités avec vous et on découpe ensemble les couches qui résistent. Vous repartez avec le réflexe de sentir un couplage avant qu'il vous coûte cher.",{"type":29,"tag":47,"props":8603,"children":8604},{},[],{"type":29,"tag":51,"props":8606,"children":8608},{"id":8607},"règle-3-les-use-cases-orchestrent-sans-dépendre-du-delivery-mechanism",[8609],{"type":34,"value":8610},"Règle 3 : Les use cases orchestrent sans dépendre du delivery mechanism",{"type":29,"tag":30,"props":8612,"children":8613},{},[8614],{"type":34,"value":8615},"Un use case implémente un cas d'utilisation métier. Il orchestre des entités, appelle des repositories, et retourne un résultat.",{"type":29,"tag":30,"props":8617,"children":8618},{},[8619,8624],{"type":29,"tag":447,"props":8620,"children":8621},{},[8622],{"type":34,"value":8623},"Ce qu'il ne doit pas faire :",{"type":34,"value":8625}," connaître comment son résultat va être utilisé : HTTP response, message queue, CLI output, test assertion. Le use case retourne un objet métier. La couche externe décide de comment le sérialiser.",{"type":29,"tag":30,"props":8627,"children":8628},{},[8629],{"type":29,"tag":447,"props":8630,"children":8631},{},[8632],{"type":34,"value":7338},{"type":29,"tag":453,"props":8634,"children":8635},{},[8636,8649,8661],{"type":29,"tag":457,"props":8637,"children":8638},{},[8639,8641,8647],{"type":34,"value":8640},"Un use case ne retourne pas de ",{"type":29,"tag":84,"props":8642,"children":8644},{"className":8643},[],[8645],{"type":34,"value":8646},"ResponseEntity\u003C>",{"type":34,"value":8648}," ou d'objet HTTP",{"type":29,"tag":457,"props":8650,"children":8651},{},[8652,8654,8660],{"type":34,"value":8653},"Un use case ne lève pas d'exceptions HTTP (",{"type":29,"tag":84,"props":8655,"children":8657},{"className":8656},[],[8658],{"type":34,"value":8659},"HttpStatus.NOT_FOUND",{"type":34,"value":306},{"type":29,"tag":457,"props":8662,"children":8663},{},[8664],{"type":34,"value":8665},"Un use case peut être appelé depuis un controller HTTP, un consumer de message queue, ou un test sans modification",{"type":29,"tag":77,"props":8667,"children":8669},{"className":81,"code":8668,"language":80,"meta":8,"style":8},"\u002F\u002F Use case indépendant du delivery mechanism : POJO pur, pas d'import Spring\npublic class CreateUserUseCase {\n    private final UserRepository userRepository;\n    private final EmailService emailService;\n\n    public CreateUserUseCase(UserRepository userRepository, EmailService emailService) {\n        this.userRepository = userRepository;\n        this.emailService = emailService;\n    }\n\n    public User execute(CreateUserCommand command) {\n        if (userRepository.existsByEmail(command.email())) {\n            throw new EmailAlreadyExistsException(command.email()); \u002F\u002F exception métier\n        }\n        User user = User.create(command.email(), command.name());\n        userRepository.save(user);\n        emailService.sendWelcome(user);\n        return user; \u002F\u002F retourne un objet métier, pas un objet HTTP\n    }\n}\n\n\u002F\u002F Le controller Spring gère la sérialisation et le mapping HTTP\n@RestController\n@RequestMapping(\"\u002Fusers\")\npublic class UserController {\n    private final CreateUserUseCase createUserUseCase;\n\n    public UserController(CreateUserUseCase createUserUseCase) {\n        this.createUserUseCase = createUserUseCase;\n    }\n\n    @PostMapping\n    public ResponseEntity\u003CUserDTO> createUser(@RequestBody CreateUserRequest request) {\n        try {\n            CreateUserCommand command = new CreateUserCommand(request.email(), request.name());\n            User user = createUserUseCase.execute(command);\n            return ResponseEntity.status(201).body(UserDTO.fromDomain(user));\n        } catch (EmailAlreadyExistsException e) {\n            return ResponseEntity.status(409).build();\n        }\n    }\n}\n",[8670],{"type":29,"tag":84,"props":8671,"children":8672},{"__ignoreMap":8},[8673,8681,8701,8726,8751,8758,8802,8830,8858,8865,8872,8910,8960,9001,9008,9074,9103,9132,9153,9160,9167,9174,9182,9194,9219,9239,9263,9270,9302,9330,9337,9344,9356,9417,9429,9492,9533,9602,9637,9678,9685,9692],{"type":29,"tag":88,"props":8674,"children":8675},{"class":90,"line":91},[8676],{"type":29,"tag":88,"props":8677,"children":8678},{"style":95},[8679],{"type":34,"value":8680},"\u002F\u002F Use case indépendant du delivery mechanism : POJO pur, pas d'import Spring\n",{"type":29,"tag":88,"props":8682,"children":8683},{"class":90,"line":101},[8684,8688,8692,8697],{"type":29,"tag":88,"props":8685,"children":8686},{"style":105},[8687],{"type":34,"value":108},{"type":29,"tag":88,"props":8689,"children":8690},{"style":105},[8691],{"type":34,"value":113},{"type":29,"tag":88,"props":8693,"children":8694},{"style":116},[8695],{"type":34,"value":8696}," CreateUserUseCase",{"type":29,"tag":88,"props":8698,"children":8699},{"style":122},[8700],{"type":34,"value":125},{"type":29,"tag":88,"props":8702,"children":8703},{"class":90,"line":128},[8704,8708,8712,8717,8722],{"type":29,"tag":88,"props":8705,"children":8706},{"style":105},[8707],{"type":34,"value":143},{"type":29,"tag":88,"props":8709,"children":8710},{"style":105},[8711],{"type":34,"value":148},{"type":29,"tag":88,"props":8713,"children":8714},{"style":151},[8715],{"type":34,"value":8716}," UserRepository",{"type":29,"tag":88,"props":8718,"children":8719},{"style":157},[8720],{"type":34,"value":8721}," userRepository",{"type":29,"tag":88,"props":8723,"children":8724},{"style":122},[8725],{"type":34,"value":424},{"type":29,"tag":88,"props":8727,"children":8728},{"class":90,"line":137},[8729,8733,8737,8742,8747],{"type":29,"tag":88,"props":8730,"children":8731},{"style":105},[8732],{"type":34,"value":143},{"type":29,"tag":88,"props":8734,"children":8735},{"style":105},[8736],{"type":34,"value":148},{"type":29,"tag":88,"props":8738,"children":8739},{"style":151},[8740],{"type":34,"value":8741}," EmailService",{"type":29,"tag":88,"props":8743,"children":8744},{"style":157},[8745],{"type":34,"value":8746}," emailService",{"type":29,"tag":88,"props":8748,"children":8749},{"style":122},[8750],{"type":34,"value":424},{"type":29,"tag":88,"props":8752,"children":8753},{"class":90,"line":211},[8754],{"type":29,"tag":88,"props":8755,"children":8756},{"emptyLinePlaceholder":13},[8757],{"type":34,"value":134},{"type":29,"tag":88,"props":8759,"children":8760},{"class":90,"line":262},[8761,8765,8769,8773,8778,8782,8786,8790,8794,8798],{"type":29,"tag":88,"props":8762,"children":8763},{"style":105},[8764],{"type":34,"value":276},{"type":29,"tag":88,"props":8766,"children":8767},{"style":174},[8768],{"type":34,"value":8696},{"type":29,"tag":88,"props":8770,"children":8771},{"style":122},[8772],{"type":34,"value":181},{"type":29,"tag":88,"props":8774,"children":8775},{"style":151},[8776],{"type":34,"value":8777},"UserRepository",{"type":29,"tag":88,"props":8779,"children":8780},{"style":298},[8781],{"type":34,"value":8721},{"type":29,"tag":88,"props":8783,"children":8784},{"style":122},[8785],{"type":34,"value":192},{"type":29,"tag":88,"props":8787,"children":8788},{"style":151},[8789],{"type":34,"value":8741},{"type":29,"tag":88,"props":8791,"children":8792},{"style":298},[8793],{"type":34,"value":8746},{"type":29,"tag":88,"props":8795,"children":8796},{"style":122},[8797],{"type":34,"value":306},{"type":29,"tag":88,"props":8799,"children":8800},{"style":122},[8801],{"type":34,"value":125},{"type":29,"tag":88,"props":8803,"children":8804},{"class":90,"line":270},[8805,8809,8813,8818,8822,8826],{"type":29,"tag":88,"props":8806,"children":8807},{"style":873},[8808],{"type":34,"value":876},{"type":29,"tag":88,"props":8810,"children":8811},{"style":122},[8812],{"type":34,"value":338},{"type":29,"tag":88,"props":8814,"children":8815},{"style":157},[8816],{"type":34,"value":8817},"userRepository ",{"type":29,"tag":88,"props":8819,"children":8820},{"style":163},[8821],{"type":34,"value":166},{"type":29,"tag":88,"props":8823,"children":8824},{"style":157},[8825],{"type":34,"value":8721},{"type":29,"tag":88,"props":8827,"children":8828},{"style":122},[8829],{"type":34,"value":424},{"type":29,"tag":88,"props":8831,"children":8832},{"class":90,"line":313},[8833,8837,8841,8846,8850,8854],{"type":29,"tag":88,"props":8834,"children":8835},{"style":873},[8836],{"type":34,"value":876},{"type":29,"tag":88,"props":8838,"children":8839},{"style":122},[8840],{"type":34,"value":338},{"type":29,"tag":88,"props":8842,"children":8843},{"style":157},[8844],{"type":34,"value":8845},"emailService ",{"type":29,"tag":88,"props":8847,"children":8848},{"style":163},[8849],{"type":34,"value":166},{"type":29,"tag":88,"props":8851,"children":8852},{"style":157},[8853],{"type":34,"value":8746},{"type":29,"tag":88,"props":8855,"children":8856},{"style":122},[8857],{"type":34,"value":424},{"type":29,"tag":88,"props":8859,"children":8860},{"class":90,"line":360},[8861],{"type":29,"tag":88,"props":8862,"children":8863},{"style":122},[8864],{"type":34,"value":433},{"type":29,"tag":88,"props":8866,"children":8867},{"class":90,"line":409},[8868],{"type":29,"tag":88,"props":8869,"children":8870},{"emptyLinePlaceholder":13},[8871],{"type":34,"value":134},{"type":29,"tag":88,"props":8873,"children":8874},{"class":90,"line":427},[8875,8879,8884,8888,8892,8897,8902,8906],{"type":29,"tag":88,"props":8876,"children":8877},{"style":105},[8878],{"type":34,"value":276},{"type":29,"tag":88,"props":8880,"children":8881},{"style":151},[8882],{"type":34,"value":8883}," User",{"type":29,"tag":88,"props":8885,"children":8886},{"style":174},[8887],{"type":34,"value":7683},{"type":29,"tag":88,"props":8889,"children":8890},{"style":122},[8891],{"type":34,"value":181},{"type":29,"tag":88,"props":8893,"children":8894},{"style":151},[8895],{"type":34,"value":8896},"CreateUserCommand",{"type":29,"tag":88,"props":8898,"children":8899},{"style":298},[8900],{"type":34,"value":8901}," command",{"type":29,"tag":88,"props":8903,"children":8904},{"style":122},[8905],{"type":34,"value":306},{"type":29,"tag":88,"props":8907,"children":8908},{"style":122},[8909],{"type":34,"value":125},{"type":29,"tag":88,"props":8911,"children":8912},{"class":90,"line":436},[8913,8917,8921,8926,8930,8935,8939,8944,8948,8952,8956],{"type":29,"tag":88,"props":8914,"children":8915},{"style":105},[8916],{"type":34,"value":2886},{"type":29,"tag":88,"props":8918,"children":8919},{"style":122},[8920],{"type":34,"value":2891},{"type":29,"tag":88,"props":8922,"children":8923},{"style":157},[8924],{"type":34,"value":8925},"userRepository",{"type":29,"tag":88,"props":8927,"children":8928},{"style":122},[8929],{"type":34,"value":338},{"type":29,"tag":88,"props":8931,"children":8932},{"style":174},[8933],{"type":34,"value":8934},"existsByEmail",{"type":29,"tag":88,"props":8936,"children":8937},{"style":122},[8938],{"type":34,"value":181},{"type":29,"tag":88,"props":8940,"children":8941},{"style":157},[8942],{"type":34,"value":8943},"command",{"type":29,"tag":88,"props":8945,"children":8946},{"style":122},[8947],{"type":34,"value":338},{"type":29,"tag":88,"props":8949,"children":8950},{"style":174},[8951],{"type":34,"value":1366},{"type":29,"tag":88,"props":8953,"children":8954},{"style":122},[8955],{"type":34,"value":6933},{"type":29,"tag":88,"props":8957,"children":8958},{"style":122},[8959],{"type":34,"value":125},{"type":29,"tag":88,"props":8961,"children":8962},{"class":90,"line":767},[8963,8967,8971,8976,8980,8984,8988,8992,8997],{"type":29,"tag":88,"props":8964,"children":8965},{"style":105},[8966],{"type":34,"value":2927},{"type":29,"tag":88,"props":8968,"children":8969},{"style":105},[8970],{"type":34,"value":171},{"type":29,"tag":88,"props":8972,"children":8973},{"style":174},[8974],{"type":34,"value":8975}," EmailAlreadyExistsException",{"type":29,"tag":88,"props":8977,"children":8978},{"style":122},[8979],{"type":34,"value":181},{"type":29,"tag":88,"props":8981,"children":8982},{"style":157},[8983],{"type":34,"value":8943},{"type":29,"tag":88,"props":8985,"children":8986},{"style":122},[8987],{"type":34,"value":338},{"type":29,"tag":88,"props":8989,"children":8990},{"style":174},[8991],{"type":34,"value":1366},{"type":29,"tag":88,"props":8993,"children":8994},{"style":122},[8995],{"type":34,"value":8996},"());",{"type":29,"tag":88,"props":8998,"children":8999},{"style":95},[9000],{"type":34,"value":7787},{"type":29,"tag":88,"props":9002,"children":9003},{"class":90,"line":792},[9004],{"type":29,"tag":88,"props":9005,"children":9006},{"style":122},[9007],{"type":34,"value":2966},{"type":29,"tag":88,"props":9009,"children":9010},{"class":90,"line":817},[9011,9016,9021,9025,9029,9033,9038,9042,9046,9050,9054,9058,9062,9066,9070],{"type":29,"tag":88,"props":9012,"children":9013},{"style":151},[9014],{"type":34,"value":9015},"        User",{"type":29,"tag":88,"props":9017,"children":9018},{"style":157},[9019],{"type":34,"value":9020}," user ",{"type":29,"tag":88,"props":9022,"children":9023},{"style":163},[9024],{"type":34,"value":166},{"type":29,"tag":88,"props":9026,"children":9027},{"style":157},[9028],{"type":34,"value":8883},{"type":29,"tag":88,"props":9030,"children":9031},{"style":122},[9032],{"type":34,"value":338},{"type":29,"tag":88,"props":9034,"children":9035},{"style":174},[9036],{"type":34,"value":9037},"create",{"type":29,"tag":88,"props":9039,"children":9040},{"style":122},[9041],{"type":34,"value":181},{"type":29,"tag":88,"props":9043,"children":9044},{"style":157},[9045],{"type":34,"value":8943},{"type":29,"tag":88,"props":9047,"children":9048},{"style":122},[9049],{"type":34,"value":338},{"type":29,"tag":88,"props":9051,"children":9052},{"style":174},[9053],{"type":34,"value":1366},{"type":29,"tag":88,"props":9055,"children":9056},{"style":122},[9057],{"type":34,"value":397},{"type":29,"tag":88,"props":9059,"children":9060},{"style":157},[9061],{"type":34,"value":8901},{"type":29,"tag":88,"props":9063,"children":9064},{"style":122},[9065],{"type":34,"value":338},{"type":29,"tag":88,"props":9067,"children":9068},{"style":174},[9069],{"type":34,"value":7935},{"type":29,"tag":88,"props":9071,"children":9072},{"style":122},[9073],{"type":34,"value":2958},{"type":29,"tag":88,"props":9075,"children":9076},{"class":90,"line":825},[9077,9082,9086,9090,9094,9099],{"type":29,"tag":88,"props":9078,"children":9079},{"style":157},[9080],{"type":34,"value":9081},"        userRepository",{"type":29,"tag":88,"props":9083,"children":9084},{"style":122},[9085],{"type":34,"value":338},{"type":29,"tag":88,"props":9087,"children":9088},{"style":174},[9089],{"type":34,"value":343},{"type":29,"tag":88,"props":9091,"children":9092},{"style":122},[9093],{"type":34,"value":181},{"type":29,"tag":88,"props":9095,"children":9096},{"style":157},[9097],{"type":34,"value":9098},"user",{"type":29,"tag":88,"props":9100,"children":9101},{"style":122},[9102],{"type":34,"value":357},{"type":29,"tag":88,"props":9104,"children":9105},{"class":90,"line":869},[9106,9111,9115,9120,9124,9128],{"type":29,"tag":88,"props":9107,"children":9108},{"style":157},[9109],{"type":34,"value":9110},"        emailService",{"type":29,"tag":88,"props":9112,"children":9113},{"style":122},[9114],{"type":34,"value":338},{"type":29,"tag":88,"props":9116,"children":9117},{"style":174},[9118],{"type":34,"value":9119},"sendWelcome",{"type":29,"tag":88,"props":9121,"children":9122},{"style":122},[9123],{"type":34,"value":181},{"type":29,"tag":88,"props":9125,"children":9126},{"style":157},[9127],{"type":34,"value":9098},{"type":29,"tag":88,"props":9129,"children":9130},{"style":122},[9131],{"type":34,"value":357},{"type":29,"tag":88,"props":9133,"children":9134},{"class":90,"line":900},[9135,9139,9144,9148],{"type":29,"tag":88,"props":9136,"children":9137},{"style":105},[9138],{"type":34,"value":415},{"type":29,"tag":88,"props":9140,"children":9141},{"style":157},[9142],{"type":34,"value":9143}," user",{"type":29,"tag":88,"props":9145,"children":9146},{"style":122},[9147],{"type":34,"value":5893},{"type":29,"tag":88,"props":9149,"children":9150},{"style":95},[9151],{"type":34,"value":9152}," \u002F\u002F retourne un objet métier, pas un objet HTTP\n",{"type":29,"tag":88,"props":9154,"children":9155},{"class":90,"line":929},[9156],{"type":29,"tag":88,"props":9157,"children":9158},{"style":122},[9159],{"type":34,"value":433},{"type":29,"tag":88,"props":9161,"children":9162},{"class":90,"line":937},[9163],{"type":29,"tag":88,"props":9164,"children":9165},{"style":122},[9166],{"type":34,"value":442},{"type":29,"tag":88,"props":9168,"children":9169},{"class":90,"line":945},[9170],{"type":29,"tag":88,"props":9171,"children":9172},{"emptyLinePlaceholder":13},[9173],{"type":34,"value":134},{"type":29,"tag":88,"props":9175,"children":9176},{"class":90,"line":981},[9177],{"type":29,"tag":88,"props":9178,"children":9179},{"style":95},[9180],{"type":34,"value":9181},"\u002F\u002F Le controller Spring gère la sérialisation et le mapping HTTP\n",{"type":29,"tag":88,"props":9183,"children":9184},{"class":90,"line":1021},[9185,9189],{"type":29,"tag":88,"props":9186,"children":9187},{"style":1974},[9188],{"type":34,"value":1977},{"type":29,"tag":88,"props":9190,"children":9191},{"style":1980},[9192],{"type":34,"value":9193},"RestController\n",{"type":29,"tag":88,"props":9195,"children":9196},{"class":90,"line":1066},[9197,9201,9206,9210,9215],{"type":29,"tag":88,"props":9198,"children":9199},{"style":1974},[9200],{"type":34,"value":1977},{"type":29,"tag":88,"props":9202,"children":9203},{"style":1980},[9204],{"type":34,"value":9205},"RequestMapping",{"type":29,"tag":88,"props":9207,"children":9208},{"style":122},[9209],{"type":34,"value":181},{"type":29,"tag":88,"props":9211,"children":9212},{"style":184},[9213],{"type":34,"value":9214},"\"\u002Fusers\"",{"type":29,"tag":88,"props":9216,"children":9217},{"style":122},[9218],{"type":34,"value":3078},{"type":29,"tag":88,"props":9220,"children":9221},{"class":90,"line":1082},[9222,9226,9230,9235],{"type":29,"tag":88,"props":9223,"children":9224},{"style":105},[9225],{"type":34,"value":108},{"type":29,"tag":88,"props":9227,"children":9228},{"style":105},[9229],{"type":34,"value":113},{"type":29,"tag":88,"props":9231,"children":9232},{"style":116},[9233],{"type":34,"value":9234}," UserController",{"type":29,"tag":88,"props":9236,"children":9237},{"style":122},[9238],{"type":34,"value":125},{"type":29,"tag":88,"props":9240,"children":9241},{"class":90,"line":1090},[9242,9246,9250,9254,9259],{"type":29,"tag":88,"props":9243,"children":9244},{"style":105},[9245],{"type":34,"value":143},{"type":29,"tag":88,"props":9247,"children":9248},{"style":105},[9249],{"type":34,"value":148},{"type":29,"tag":88,"props":9251,"children":9252},{"style":151},[9253],{"type":34,"value":8696},{"type":29,"tag":88,"props":9255,"children":9256},{"style":157},[9257],{"type":34,"value":9258}," createUserUseCase",{"type":29,"tag":88,"props":9260,"children":9261},{"style":122},[9262],{"type":34,"value":424},{"type":29,"tag":88,"props":9264,"children":9265},{"class":90,"line":1098},[9266],{"type":29,"tag":88,"props":9267,"children":9268},{"emptyLinePlaceholder":13},[9269],{"type":34,"value":134},{"type":29,"tag":88,"props":9271,"children":9272},{"class":90,"line":1106},[9273,9277,9281,9285,9290,9294,9298],{"type":29,"tag":88,"props":9274,"children":9275},{"style":105},[9276],{"type":34,"value":276},{"type":29,"tag":88,"props":9278,"children":9279},{"style":174},[9280],{"type":34,"value":9234},{"type":29,"tag":88,"props":9282,"children":9283},{"style":122},[9284],{"type":34,"value":181},{"type":29,"tag":88,"props":9286,"children":9287},{"style":151},[9288],{"type":34,"value":9289},"CreateUserUseCase",{"type":29,"tag":88,"props":9291,"children":9292},{"style":298},[9293],{"type":34,"value":9258},{"type":29,"tag":88,"props":9295,"children":9296},{"style":122},[9297],{"type":34,"value":306},{"type":29,"tag":88,"props":9299,"children":9300},{"style":122},[9301],{"type":34,"value":125},{"type":29,"tag":88,"props":9303,"children":9304},{"class":90,"line":1115},[9305,9309,9313,9318,9322,9326],{"type":29,"tag":88,"props":9306,"children":9307},{"style":873},[9308],{"type":34,"value":876},{"type":29,"tag":88,"props":9310,"children":9311},{"style":122},[9312],{"type":34,"value":338},{"type":29,"tag":88,"props":9314,"children":9315},{"style":157},[9316],{"type":34,"value":9317},"createUserUseCase ",{"type":29,"tag":88,"props":9319,"children":9320},{"style":163},[9321],{"type":34,"value":166},{"type":29,"tag":88,"props":9323,"children":9324},{"style":157},[9325],{"type":34,"value":9258},{"type":29,"tag":88,"props":9327,"children":9328},{"style":122},[9329],{"type":34,"value":424},{"type":29,"tag":88,"props":9331,"children":9332},{"class":90,"line":11},[9333],{"type":29,"tag":88,"props":9334,"children":9335},{"style":122},[9336],{"type":34,"value":433},{"type":29,"tag":88,"props":9338,"children":9339},{"class":90,"line":1180},[9340],{"type":29,"tag":88,"props":9341,"children":9342},{"emptyLinePlaceholder":13},[9343],{"type":34,"value":134},{"type":29,"tag":88,"props":9345,"children":9346},{"class":90,"line":1240},[9347,9351],{"type":29,"tag":88,"props":9348,"children":9349},{"style":1974},[9350],{"type":34,"value":3302},{"type":29,"tag":88,"props":9352,"children":9353},{"style":1980},[9354],{"type":34,"value":9355},"PostMapping\n",{"type":29,"tag":88,"props":9357,"children":9358},{"class":90,"line":1248},[9359,9363,9368,9372,9377,9381,9386,9390,9394,9399,9404,9409,9413],{"type":29,"tag":88,"props":9360,"children":9361},{"style":105},[9362],{"type":34,"value":276},{"type":29,"tag":88,"props":9364,"children":9365},{"style":151},[9366],{"type":34,"value":9367}," ResponseEntity",{"type":29,"tag":88,"props":9369,"children":9370},{"style":122},[9371],{"type":34,"value":1683},{"type":29,"tag":88,"props":9373,"children":9374},{"style":105},[9375],{"type":34,"value":9376},"UserDTO",{"type":29,"tag":88,"props":9378,"children":9379},{"style":122},[9380],{"type":34,"value":1701},{"type":29,"tag":88,"props":9382,"children":9383},{"style":174},[9384],{"type":34,"value":9385}," createUser",{"type":29,"tag":88,"props":9387,"children":9388},{"style":122},[9389],{"type":34,"value":181},{"type":29,"tag":88,"props":9391,"children":9392},{"style":1974},[9393],{"type":34,"value":1977},{"type":29,"tag":88,"props":9395,"children":9396},{"style":1980},[9397],{"type":34,"value":9398},"RequestBody",{"type":29,"tag":88,"props":9400,"children":9401},{"style":151},[9402],{"type":34,"value":9403}," CreateUserRequest",{"type":29,"tag":88,"props":9405,"children":9406},{"style":298},[9407],{"type":34,"value":9408}," request",{"type":29,"tag":88,"props":9410,"children":9411},{"style":122},[9412],{"type":34,"value":306},{"type":29,"tag":88,"props":9414,"children":9415},{"style":122},[9416],{"type":34,"value":125},{"type":29,"tag":88,"props":9418,"children":9419},{"class":90,"line":1256},[9420,9425],{"type":29,"tag":88,"props":9421,"children":9422},{"style":105},[9423],{"type":34,"value":9424},"        try",{"type":29,"tag":88,"props":9426,"children":9427},{"style":122},[9428],{"type":34,"value":125},{"type":29,"tag":88,"props":9430,"children":9431},{"class":90,"line":1264},[9432,9437,9442,9446,9450,9455,9459,9464,9468,9472,9476,9480,9484,9488],{"type":29,"tag":88,"props":9433,"children":9434},{"style":151},[9435],{"type":34,"value":9436},"            CreateUserCommand",{"type":29,"tag":88,"props":9438,"children":9439},{"style":157},[9440],{"type":34,"value":9441}," command ",{"type":29,"tag":88,"props":9443,"children":9444},{"style":163},[9445],{"type":34,"value":166},{"type":29,"tag":88,"props":9447,"children":9448},{"style":105},[9449],{"type":34,"value":171},{"type":29,"tag":88,"props":9451,"children":9452},{"style":174},[9453],{"type":34,"value":9454}," CreateUserCommand",{"type":29,"tag":88,"props":9456,"children":9457},{"style":122},[9458],{"type":34,"value":181},{"type":29,"tag":88,"props":9460,"children":9461},{"style":157},[9462],{"type":34,"value":9463},"request",{"type":29,"tag":88,"props":9465,"children":9466},{"style":122},[9467],{"type":34,"value":338},{"type":29,"tag":88,"props":9469,"children":9470},{"style":174},[9471],{"type":34,"value":1366},{"type":29,"tag":88,"props":9473,"children":9474},{"style":122},[9475],{"type":34,"value":397},{"type":29,"tag":88,"props":9477,"children":9478},{"style":157},[9479],{"type":34,"value":9408},{"type":29,"tag":88,"props":9481,"children":9482},{"style":122},[9483],{"type":34,"value":338},{"type":29,"tag":88,"props":9485,"children":9486},{"style":174},[9487],{"type":34,"value":7935},{"type":29,"tag":88,"props":9489,"children":9490},{"style":122},[9491],{"type":34,"value":2958},{"type":29,"tag":88,"props":9493,"children":9494},{"class":90,"line":1293},[9495,9500,9504,9508,9512,9516,9521,9525,9529],{"type":29,"tag":88,"props":9496,"children":9497},{"style":151},[9498],{"type":34,"value":9499},"            User",{"type":29,"tag":88,"props":9501,"children":9502},{"style":157},[9503],{"type":34,"value":9020},{"type":29,"tag":88,"props":9505,"children":9506},{"style":163},[9507],{"type":34,"value":166},{"type":29,"tag":88,"props":9509,"children":9510},{"style":157},[9511],{"type":34,"value":9258},{"type":29,"tag":88,"props":9513,"children":9514},{"style":122},[9515],{"type":34,"value":338},{"type":29,"tag":88,"props":9517,"children":9518},{"style":174},[9519],{"type":34,"value":9520},"execute",{"type":29,"tag":88,"props":9522,"children":9523},{"style":122},[9524],{"type":34,"value":181},{"type":29,"tag":88,"props":9526,"children":9527},{"style":157},[9528],{"type":34,"value":8943},{"type":29,"tag":88,"props":9530,"children":9531},{"style":122},[9532],{"type":34,"value":357},{"type":29,"tag":88,"props":9534,"children":9535},{"class":90,"line":1342},[9536,9541,9545,9549,9554,9558,9563,9568,9573,9577,9581,9585,9590,9594,9598],{"type":29,"tag":88,"props":9537,"children":9538},{"style":105},[9539],{"type":34,"value":9540},"            return",{"type":29,"tag":88,"props":9542,"children":9543},{"style":157},[9544],{"type":34,"value":9367},{"type":29,"tag":88,"props":9546,"children":9547},{"style":122},[9548],{"type":34,"value":338},{"type":29,"tag":88,"props":9550,"children":9551},{"style":174},[9552],{"type":34,"value":9553},"status",{"type":29,"tag":88,"props":9555,"children":9556},{"style":122},[9557],{"type":34,"value":181},{"type":29,"tag":88,"props":9559,"children":9560},{"style":195},[9561],{"type":34,"value":9562},"201",{"type":29,"tag":88,"props":9564,"children":9565},{"style":122},[9566],{"type":34,"value":9567},").",{"type":29,"tag":88,"props":9569,"children":9570},{"style":174},[9571],{"type":34,"value":9572},"body",{"type":29,"tag":88,"props":9574,"children":9575},{"style":122},[9576],{"type":34,"value":181},{"type":29,"tag":88,"props":9578,"children":9579},{"style":157},[9580],{"type":34,"value":9376},{"type":29,"tag":88,"props":9582,"children":9583},{"style":122},[9584],{"type":34,"value":338},{"type":29,"tag":88,"props":9586,"children":9587},{"style":174},[9588],{"type":34,"value":9589},"fromDomain",{"type":29,"tag":88,"props":9591,"children":9592},{"style":122},[9593],{"type":34,"value":181},{"type":29,"tag":88,"props":9595,"children":9596},{"style":157},[9597],{"type":34,"value":9098},{"type":29,"tag":88,"props":9599,"children":9600},{"style":122},[9601],{"type":34,"value":1415},{"type":29,"tag":88,"props":9603,"children":9604},{"class":90,"line":1418},[9605,9610,9615,9619,9624,9629,9633],{"type":29,"tag":88,"props":9606,"children":9607},{"style":122},[9608],{"type":34,"value":9609},"        }",{"type":29,"tag":88,"props":9611,"children":9612},{"style":105},[9613],{"type":34,"value":9614}," catch",{"type":29,"tag":88,"props":9616,"children":9617},{"style":122},[9618],{"type":34,"value":2891},{"type":29,"tag":88,"props":9620,"children":9621},{"style":151},[9622],{"type":34,"value":9623},"EmailAlreadyExistsException",{"type":29,"tag":88,"props":9625,"children":9626},{"style":298},[9627],{"type":34,"value":9628}," e",{"type":29,"tag":88,"props":9630,"children":9631},{"style":122},[9632],{"type":34,"value":306},{"type":29,"tag":88,"props":9634,"children":9635},{"style":122},[9636],{"type":34,"value":125},{"type":29,"tag":88,"props":9638,"children":9639},{"class":90,"line":1426},[9640,9644,9648,9652,9656,9660,9665,9669,9674],{"type":29,"tag":88,"props":9641,"children":9642},{"style":105},[9643],{"type":34,"value":9540},{"type":29,"tag":88,"props":9645,"children":9646},{"style":157},[9647],{"type":34,"value":9367},{"type":29,"tag":88,"props":9649,"children":9650},{"style":122},[9651],{"type":34,"value":338},{"type":29,"tag":88,"props":9653,"children":9654},{"style":174},[9655],{"type":34,"value":9553},{"type":29,"tag":88,"props":9657,"children":9658},{"style":122},[9659],{"type":34,"value":181},{"type":29,"tag":88,"props":9661,"children":9662},{"style":195},[9663],{"type":34,"value":9664},"409",{"type":29,"tag":88,"props":9666,"children":9667},{"style":122},[9668],{"type":34,"value":9567},{"type":29,"tag":88,"props":9670,"children":9671},{"style":174},[9672],{"type":34,"value":9673},"build",{"type":29,"tag":88,"props":9675,"children":9676},{"style":122},[9677],{"type":34,"value":1810},{"type":29,"tag":88,"props":9679,"children":9680},{"class":90,"line":1434},[9681],{"type":29,"tag":88,"props":9682,"children":9683},{"style":122},[9684],{"type":34,"value":2966},{"type":29,"tag":88,"props":9686,"children":9687},{"class":90,"line":1442},[9688],{"type":29,"tag":88,"props":9689,"children":9690},{"style":122},[9691],{"type":34,"value":433},{"type":29,"tag":88,"props":9693,"children":9694},{"class":90,"line":1451},[9695],{"type":29,"tag":88,"props":9696,"children":9697},{"style":122},[9698],{"type":34,"value":442},{"type":29,"tag":47,"props":9700,"children":9701},{},[],{"type":29,"tag":51,"props":9703,"children":9705},{"id":9704},"les-anti-patterns-courants-à-éviter",[9706],{"type":34,"value":9707},"Les anti-patterns courants à éviter",{"type":29,"tag":30,"props":9709,"children":9710},{},[9711,9716],{"type":29,"tag":447,"props":9712,"children":9713},{},[9714],{"type":34,"value":9715},"L'Anemic Domain Model :",{"type":34,"value":9717}," les entités ne contiennent que des getters\u002Fsetters, et toute la logique est dans les services. Le domaine est vide de sens. La logique métier se retrouve dispersée dans tous les services et est difficile à tester isolément.",{"type":29,"tag":30,"props":9719,"children":9720},{},[9721,9726],{"type":29,"tag":447,"props":9722,"children":9723},{},[9724],{"type":34,"value":9725},"Le God Service :",{"type":34,"value":9727}," un service qui fait tout : valide, orchestre, persiste, formate. Difficile à tester, impossible à réutiliser, cauchemar à maintenir.",{"type":29,"tag":30,"props":9729,"children":9730},{},[9731,9736],{"type":29,"tag":447,"props":9732,"children":9733},{},[9734],{"type":34,"value":9735},"Le leak d'infrastructure :",{"type":34,"value":9737}," des dépendances sur des frameworks qui se propagent jusqu'aux entités métier. Le signe infaillible que la règle 2 est violée.",{"type":29,"tag":47,"props":9739,"children":9740},{},[],{"type":29,"tag":51,"props":9742,"children":9744},{"id":9743},"quand-appliquer-les-3-règles-quand-ne-pas-les-appliquer",[9745],{"type":34,"value":9746},"Quand appliquer les 3 règles, quand ne pas les appliquer",{"type":29,"tag":30,"props":9748,"children":9749},{},[9750,9755],{"type":29,"tag":447,"props":9751,"children":9752},{},[9753],{"type":34,"value":9754},"Appliquer dès que :",{"type":34,"value":9756}," la logique métier est non-triviale, l'application doit durer plus de 2 ans, ou plusieurs développeurs travaillent sur le même codebase.",{"type":29,"tag":30,"props":9758,"children":9759},{},[9760,9765],{"type":29,"tag":447,"props":9761,"children":9762},{},[9763],{"type":34,"value":9764},"Ne pas appliquer dans sa totalité :",{"type":34,"value":9766}," pour des scripts, des prototypes, des outils internes à courte durée de vie. La Clean Architecture a un coût d'entrée qui doit être justifié par la longévité et la complexité du projet.",{"type":29,"tag":2288,"props":9768,"children":9770},{"cta":5629,"href":5630,"title":9769,"type":5632},"Tracer la règle de dépendance n'est qu'une pratique parmi 100",[9771],{"type":29,"tag":30,"props":9772,"children":9773},{},[9774],{"type":34,"value":9775},"Cet article isole une pratique : garder le métier indépendant de l'infrastructure. Le Craft Bundle réunit les 100 pratiques que j'applique pour coder propre, des frontières de couches au découpage des use cases en passant par les tests qui tournent en millisecondes. Ce sont les réflexes que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vus tenir une codebase sur quatre ans.",{"type":29,"tag":47,"props":9777,"children":9778},{},[],{"type":29,"tag":51,"props":9780,"children":9782},{"id":9781},"faq-sur-la-clean-architecture",[9783],{"type":34,"value":9784},"FAQ sur la Clean Architecture",{"type":29,"tag":5649,"props":9786,"children":9787},{},[9788,9793],{"type":29,"tag":5653,"props":9789,"children":9790},{},[9791],{"type":34,"value":9792},"1. La Clean Architecture est-elle compatible avec les frameworks comme Spring ou NestJS ?",{"type":29,"tag":30,"props":9794,"children":9795},{},[9796],{"type":34,"value":9797},"Oui, mais avec discipline. Spring et NestJS sont excellents comme couches d'infrastructure (injection de dépendances, routing HTTP). La règle est de ne pas laisser leurs annotations et abstractions contaminer les couches métier. Utiliser la DI du framework pour injecter les dépendances dans les use cases, sans que les use cases aient connaissance du framework lui-même.",{"type":29,"tag":5649,"props":9799,"children":9800},{},[9801,9806],{"type":29,"tag":5653,"props":9802,"children":9803},{},[9804],{"type":34,"value":9805},"2. Faut-il refactoriser tout un codebase existant pour appliquer ces 3 règles ?",{"type":29,"tag":30,"props":9807,"children":9808},{},[9809],{"type":34,"value":9810},"Non. Appliquer les 3 règles progressivement, au fil des nouvelles features et des refactorings planifiés. Commencer par les modules les plus actifs, ceux sur lesquels l'équipe travaille le plus souvent. Sur les modules legacy stables, le coût du refactoring n'est pas justifié si le gain opérationnel est faible. C'est la stratégie que j'applique systématiquement dans mes missions.",{"type":29,"tag":5649,"props":9812,"children":9813},{},[9814,9819],{"type":29,"tag":5653,"props":9815,"children":9816},{},[9817],{"type":34,"value":9818},"3. La Clean Architecture ralentit-elle le développement au départ ?",{"type":29,"tag":30,"props":9820,"children":9821},{},[9822],{"type":34,"value":9823},"Légèrement, sur les 2 à 4 premières semaines. Le coût est l'apprentissage de la structuration correcte du code. Après cette période, le développement accélère parce que les tests sont rapides, les changements sont localisés, et les nouveaux développeurs comprennent la structure rapidement. Sur l'équipe dont je parlais en ouverture, le ralentissement initial a été compensé dès le premier mois.",{"type":29,"tag":5649,"props":9825,"children":9826},{},[9827,9832],{"type":29,"tag":5653,"props":9828,"children":9829},{},[9830],{"type":34,"value":9831},"4. Clean Architecture, Hexagonal Architecture, Onion Architecture : quelle différence ?",{"type":29,"tag":30,"props":9833,"children":9834},{},[9835],{"type":34,"value":9836},"Ce sont des variantes du même principe : séparer le domaine de l'infrastructure et diriger les dépendances vers le centre. Les différences sont principalement de vocabulaire et d'emphase. L'Hexagonal (ports et adapters) est souvent plus simple à expliquer. La Clean Architecture est plus prescriptive sur les couches. Choisissez le vocabulaire qui résonne avec votre équipe. Le principe est le même.",{"type":29,"tag":5649,"props":9838,"children":9839},{},[9840,9845],{"type":29,"tag":5653,"props":9841,"children":9842},{},[9843],{"type":34,"value":9844},"5. Comment justifier le temps d'investissement en Clean Architecture auprès du management ?",{"type":29,"tag":30,"props":9846,"children":9847},{},[9848,9850,9856],{"type":34,"value":9849},"Trois arguments concrets que j'utilise : (1) Les tests métier s'exécutent en secondes et non en minutes, réduisant le feedback loop et le temps de CI. (2) Les nouveaux développeurs atteignent l'autonomie 2 à 4 semaines plus tôt, ce qui représente une économie de 40 à 80 heures d'accompagnement par recrutement. (3) Les changements de framework ou de base de données, qui arrivent tous les 3 à 5 ans, ne nécessitent pas de réécriture de la logique métier. Pour un CTO qui prend ses fonctions, investir dans ces fondations architecturales fait partie des ",{"type":29,"tag":63,"props":9851,"children":9853},{"href":9852},"\u002Ffr\u002Fmanagement\u002Fcto-premiere-annee-90-jours",[9854],{"type":34,"value":9855},"décisions structurantes à prendre dans les 90 premiers jours",{"type":34,"value":9857},", avant que la dette s'accumule et rende le changement trop coûteux.",{"type":29,"tag":47,"props":9859,"children":9860},{},[],{"type":29,"tag":2288,"props":9862,"children":9863},{"cta":5752,"href":5753,"title":5754,"type":5755},[9864],{"type":29,"tag":30,"props":9865,"children":9866},{},[9867],{"type":34,"value":9868},"L'Engineering Maturity Self-Assessment couvre le domaine Architecture & Craft : évaluez votre niveau sur la séparation des couches, le couplage, et la testabilité de votre codebase. Score et recommandations en 10 minutes.",{"type":29,"tag":5763,"props":9870,"children":9871},{},[9872],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":9874},[9875,9876,9877,9878,9879,9880,9881],{"id":7266,"depth":101,"text":7269},{"id":7303,"depth":101,"text":7306},{"id":7831,"depth":101,"text":7834},{"id":8607,"depth":101,"text":8610},{"id":9704,"depth":101,"text":9707},{"id":9743,"depth":101,"text":9746},{"id":9781,"depth":101,"text":9784},"content:fr:architecture-craft:clean-architecture-3-regles.md","fr\u002Farchitecture-craft\u002Fclean-architecture-3-regles.md","fr\u002Farchitecture-craft\u002Fclean-architecture-3-regles",{"_path":7292,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9886,"description":9887,"id":211,"date":9888,"listed":13,"nocomments":7,"hidden":7,"categories":9889,"tags":9890,"cover":9892,"readingTime":9893,"body":9897,"_type":5777,"_id":10675,"_source":5779,"_file":10676,"_stem":10677,"_extension":5782},"Architecture décisionnelle : pourquoi les ADRs changent tout","Chaque équipe refait les mêmes débats architecturaux parce que personne ne documente les décisions passées. Les ADRs résolvent ça en 30 minutes de mise en place.","2026-01-14",[6],[9891,17],"documentation","covers\u002Farticles\u002Fadr-architecture-decision.jpg",{"text":5793,"minutes":9894,"time":9895,"words":9896},7.395,443700,1479,{"type":26,"children":9898,"toc":10666},[9899,9904,9909,9914,9919,9922,9928,9940,9945,9950,9968,9973,9986,9989,9995,10000,10010,10020,10060,10070,10080,10295,10304,10307,10313,10318,10323,10341,10354,10357,10363,10368,10376,10381,10391,10401,10411,10424,10427,10433,10441,10446,10451,10454,10460,10540,10549,10552,10558,10571,10592,10618,10631,10651,10654,10662],{"type":29,"tag":30,"props":9900,"children":9901},{},[9902],{"type":34,"value":9903},"J'ai rejoint une équipe bancaire en mission où le même débat revenait toutes les deux semaines : \"Pourquoi on a choisi PostgreSQL plutôt que MongoDB ?\" La décision avait deux ans. Personne ne s'en souvenait. Et chaque fois, on reconstruisait le contexte de zéro, parfois en prenant une direction différente de la précédente.",{"type":29,"tag":30,"props":9905,"children":9906},{},[9907],{"type":34,"value":9908},"Ce n'était pas un manque d'intelligence. C'était un manque de mémoire organisationnelle.",{"type":29,"tag":30,"props":9910,"children":9911},{},[9912],{"type":34,"value":9913},"Les Architecture Decision Records (ADRs) sont la réponse à ce problème. Un document court (une à deux pages) qui répond à une seule question : \"Pourquoi avons-nous fait ce choix technique ?\" Le concept existe depuis les années 2000. La plupart des équipes ne l'utilisent toujours pas.",{"type":29,"tag":30,"props":9915,"children":9916},{},[9917],{"type":34,"value":9918},"Et ça leur coûte cher.",{"type":29,"tag":47,"props":9920,"children":9921},{},[],{"type":29,"tag":51,"props":9923,"children":9925},{"id":9924},"le-coût-réel-des-décisions-non-documentées",[9926],{"type":34,"value":9927},"Le coût réel des décisions non documentées",{"type":29,"tag":30,"props":9929,"children":9930},{},[9931,9933,9938],{"type":34,"value":9932},"Dans une équipe de 10 développeurs, si chaque développeur perd 2 heures par mois à reconstruire le contexte de décisions passées, ça représente ",{"type":29,"tag":447,"props":9934,"children":9935},{},[9936],{"type":34,"value":9937},"240 heures par an",{"type":34,"value":9939},", soit plus de 6 semaines-développeur perdues sur des débats déjà tranchés.",{"type":29,"tag":30,"props":9941,"children":9942},{},[9943],{"type":34,"value":9944},"Quand j'ai mené cet exercice chez un client dans le secteur assurance (60 développeurs, 8 équipes), les résultats étaient éloquents : 73% des développeurs n'avaient pas conscience des 3 dernières décisions architecturales majeures prises par leur propre équipe. Le coût en onboardings ratés, en refactorings inutiles, en duplications de solutions était supérieur à 400 heures par trimestre.",{"type":29,"tag":30,"props":9946,"children":9947},{},[9948],{"type":34,"value":9949},"J'ai demandé à chaque équipe de répondre par écrit à trois questions :",{"type":29,"tag":453,"props":9951,"children":9952},{},[9953,9958,9963],{"type":29,"tag":457,"props":9954,"children":9955},{},[9956],{"type":34,"value":9957},"\"Pourquoi utilisez-vous cette technologie plutôt que l'alternative ?\"",{"type":29,"tag":457,"props":9959,"children":9960},{},[9961],{"type":34,"value":9962},"\"Qui a pris la décision d'adopter ce pattern et quand ?\"",{"type":29,"tag":457,"props":9964,"children":9965},{},[9966],{"type":34,"value":9967},"\"Avez-vous des décisions en cours avec lesquelles vous n'êtes pas d'accord mais que vous n'avez jamais remises en question ?\"",{"type":29,"tag":30,"props":9969,"children":9970},{},[9971],{"type":34,"value":9972},"La diversité des réponses (et surtout les \"je ne sais pas\") a suffi à convaincre les équipes de changer leurs pratiques.",{"type":29,"tag":30,"props":9974,"children":9975},{},[9976,9978,9984],{"type":34,"value":9977},"Michael Nygard, dans son billet fondateur de 2011 sur les ADRs, posait la même exigence : capturer les décisions architecturalement significatives et leur contexte, pas seulement leur résultat. Ce qui importe, c'est de comprendre ",{"type":29,"tag":9979,"props":9980,"children":9981},"em",{},[9982],{"type":34,"value":9983},"pourquoi",{"type":34,"value":9985}," une décision a été prise, pas seulement laquelle.",{"type":29,"tag":47,"props":9987,"children":9988},{},[],{"type":29,"tag":51,"props":9990,"children":9992},{"id":9991},"le-template-adr-en-5-sections",[9993],{"type":34,"value":9994},"Le template ADR en 5 sections",{"type":29,"tag":30,"props":9996,"children":9997},{},[9998],{"type":34,"value":9999},"Un ADR bien rédigé répond à 5 questions dans l'ordre :",{"type":29,"tag":30,"props":10001,"children":10002},{},[10003,10008],{"type":29,"tag":447,"props":10004,"children":10005},{},[10006],{"type":34,"value":10007},"Contexte",{"type":34,"value":10009}," : quelle situation nécessite cette décision ? Quelles contraintes s'appliquent ? Qui est impliqué ?",{"type":29,"tag":30,"props":10011,"children":10012},{},[10013,10018],{"type":29,"tag":447,"props":10014,"children":10015},{},[10016],{"type":34,"value":10017},"Décision",{"type":34,"value":10019}," : quelle est la décision prise, formulée comme une assertion active (\"Nous utilisons PostgreSQL comme base de données principale\") plutôt que comme une question ouverte.",{"type":29,"tag":30,"props":10021,"children":10022},{},[10023,10028,10030,10036,10038,10044,10045,10051,10052,10058],{"type":29,"tag":447,"props":10024,"children":10025},{},[10026],{"type":34,"value":10027},"Statut",{"type":34,"value":10029}," : ",{"type":29,"tag":84,"props":10031,"children":10033},{"className":10032},[],[10034],{"type":34,"value":10035},"proposed",{"type":34,"value":10037}," | ",{"type":29,"tag":84,"props":10039,"children":10041},{"className":10040},[],[10042],{"type":34,"value":10043},"accepted",{"type":34,"value":10037},{"type":29,"tag":84,"props":10046,"children":10048},{"className":10047},[],[10049],{"type":34,"value":10050},"deprecated",{"type":34,"value":10037},{"type":29,"tag":84,"props":10053,"children":10055},{"className":10054},[],[10056],{"type":34,"value":10057},"superseded",{"type":34,"value":10059},". Le statut évolue dans le temps : une décision peut être remplacée par une nouvelle ADR.",{"type":29,"tag":30,"props":10061,"children":10062},{},[10063,10068],{"type":29,"tag":447,"props":10064,"children":10065},{},[10066],{"type":34,"value":10067},"Conséquences",{"type":34,"value":10069}," : implications positives et négatives. Qu'est-ce qui devient plus simple ? Qu'est-ce qui devient plus difficile ?",{"type":29,"tag":30,"props":10071,"children":10072},{},[10073,10078],{"type":29,"tag":447,"props":10074,"children":10075},{},[10076],{"type":34,"value":10077},"Alternatives considérées",{"type":34,"value":10079}," : quelles autres options ont été évaluées et pourquoi ont-elles été écartées ?",{"type":29,"tag":77,"props":10081,"children":10084},{"code":10082,"language":5777,"meta":8,"className":10083,"style":8},"# ADR-0001 : Utilisation de PostgreSQL comme base de données principale\n\n## Contexte\nNotre service de gestion des commandes nécessite une base de données relationnelle\navec support des transactions ACID. L'équipe a de l'expérience avec PostgreSQL et MySQL.\nContrainte : déploiement sur AWS, budget infrastructure limité.\n\n## Décision\nNous utilisons PostgreSQL 15 comme base de données principale pour tous les services\nqui nécessitent une persistance relationnelle.\n\n## Statut\nAccepté (2026-01-14)\n\n## Conséquences\n- Positives : ACID garanti, support JSON natif, extensions riches (PostGIS si besoin)\n- Négatives : scaling vertical nécessaire avant sharding ; expertise spécifique requise\n- Impact sur l'équipe : formation nécessaire pour 3 développeurs juniors\n\n## Alternatives considérées\n- MySQL 8.0 : écarté car support JSON moins mature et licensing Oracle\n- MongoDB : écarté car nos données sont relationnelles\n- DynamoDB : écarté car coût à l'usage imprévisible et expertise absente\n","language-markdown shiki shiki-themes catppuccin-frappe github-dark",[10085],{"type":29,"tag":84,"props":10086,"children":10087},{"__ignoreMap":8},[10088,10097,10104,10113,10121,10129,10137,10144,10152,10160,10168,10175,10183,10191,10198,10206,10220,10232,10244,10251,10259,10271,10283],{"type":29,"tag":88,"props":10089,"children":10090},{"class":90,"line":91},[10091],{"type":29,"tag":88,"props":10092,"children":10094},{"style":10093},"--shiki-default:#E78284;--shiki-default-font-weight:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold",[10095],{"type":34,"value":10096},"# ADR-0001 : Utilisation de PostgreSQL comme base de données principale\n",{"type":29,"tag":88,"props":10098,"children":10099},{"class":90,"line":101},[10100],{"type":29,"tag":88,"props":10101,"children":10102},{"emptyLinePlaceholder":13},[10103],{"type":34,"value":134},{"type":29,"tag":88,"props":10105,"children":10106},{"class":90,"line":128},[10107],{"type":29,"tag":88,"props":10108,"children":10110},{"style":10109},"--shiki-default:#EF9F76;--shiki-default-font-weight:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold",[10111],{"type":34,"value":10112},"## Contexte\n",{"type":29,"tag":88,"props":10114,"children":10115},{"class":90,"line":137},[10116],{"type":29,"tag":88,"props":10117,"children":10118},{"style":157},[10119],{"type":34,"value":10120},"Notre service de gestion des commandes nécessite une base de données relationnelle\n",{"type":29,"tag":88,"props":10122,"children":10123},{"class":90,"line":211},[10124],{"type":29,"tag":88,"props":10125,"children":10126},{"style":157},[10127],{"type":34,"value":10128},"avec support des transactions ACID. L'équipe a de l'expérience avec PostgreSQL et MySQL.\n",{"type":29,"tag":88,"props":10130,"children":10131},{"class":90,"line":262},[10132],{"type":29,"tag":88,"props":10133,"children":10134},{"style":157},[10135],{"type":34,"value":10136},"Contrainte : déploiement sur AWS, budget infrastructure limité.\n",{"type":29,"tag":88,"props":10138,"children":10139},{"class":90,"line":270},[10140],{"type":29,"tag":88,"props":10141,"children":10142},{"emptyLinePlaceholder":13},[10143],{"type":34,"value":134},{"type":29,"tag":88,"props":10145,"children":10146},{"class":90,"line":313},[10147],{"type":29,"tag":88,"props":10148,"children":10149},{"style":10109},[10150],{"type":34,"value":10151},"## Décision\n",{"type":29,"tag":88,"props":10153,"children":10154},{"class":90,"line":360},[10155],{"type":29,"tag":88,"props":10156,"children":10157},{"style":157},[10158],{"type":34,"value":10159},"Nous utilisons PostgreSQL 15 comme base de données principale pour tous les services\n",{"type":29,"tag":88,"props":10161,"children":10162},{"class":90,"line":409},[10163],{"type":29,"tag":88,"props":10164,"children":10165},{"style":157},[10166],{"type":34,"value":10167},"qui nécessitent une persistance relationnelle.\n",{"type":29,"tag":88,"props":10169,"children":10170},{"class":90,"line":427},[10171],{"type":29,"tag":88,"props":10172,"children":10173},{"emptyLinePlaceholder":13},[10174],{"type":34,"value":134},{"type":29,"tag":88,"props":10176,"children":10177},{"class":90,"line":436},[10178],{"type":29,"tag":88,"props":10179,"children":10180},{"style":10109},[10181],{"type":34,"value":10182},"## Statut\n",{"type":29,"tag":88,"props":10184,"children":10185},{"class":90,"line":767},[10186],{"type":29,"tag":88,"props":10187,"children":10188},{"style":157},[10189],{"type":34,"value":10190},"Accepté (2026-01-14)\n",{"type":29,"tag":88,"props":10192,"children":10193},{"class":90,"line":792},[10194],{"type":29,"tag":88,"props":10195,"children":10196},{"emptyLinePlaceholder":13},[10197],{"type":34,"value":134},{"type":29,"tag":88,"props":10199,"children":10200},{"class":90,"line":817},[10201],{"type":29,"tag":88,"props":10202,"children":10203},{"style":10109},[10204],{"type":34,"value":10205},"## Conséquences\n",{"type":29,"tag":88,"props":10207,"children":10208},{"class":90,"line":825},[10209,10215],{"type":29,"tag":88,"props":10210,"children":10212},{"style":10211},"--shiki-default:#81C8BE;--shiki-dark:#FFAB70",[10213],{"type":34,"value":10214},"-",{"type":29,"tag":88,"props":10216,"children":10217},{"style":157},[10218],{"type":34,"value":10219}," Positives : ACID garanti, support JSON natif, extensions riches (PostGIS si besoin)\n",{"type":29,"tag":88,"props":10221,"children":10222},{"class":90,"line":869},[10223,10227],{"type":29,"tag":88,"props":10224,"children":10225},{"style":10211},[10226],{"type":34,"value":10214},{"type":29,"tag":88,"props":10228,"children":10229},{"style":157},[10230],{"type":34,"value":10231}," Négatives : scaling vertical nécessaire avant sharding ; expertise spécifique requise\n",{"type":29,"tag":88,"props":10233,"children":10234},{"class":90,"line":900},[10235,10239],{"type":29,"tag":88,"props":10236,"children":10237},{"style":10211},[10238],{"type":34,"value":10214},{"type":29,"tag":88,"props":10240,"children":10241},{"style":157},[10242],{"type":34,"value":10243}," Impact sur l'équipe : formation nécessaire pour 3 développeurs juniors\n",{"type":29,"tag":88,"props":10245,"children":10246},{"class":90,"line":929},[10247],{"type":29,"tag":88,"props":10248,"children":10249},{"emptyLinePlaceholder":13},[10250],{"type":34,"value":134},{"type":29,"tag":88,"props":10252,"children":10253},{"class":90,"line":937},[10254],{"type":29,"tag":88,"props":10255,"children":10256},{"style":10109},[10257],{"type":34,"value":10258},"## Alternatives considérées\n",{"type":29,"tag":88,"props":10260,"children":10261},{"class":90,"line":945},[10262,10266],{"type":29,"tag":88,"props":10263,"children":10264},{"style":10211},[10265],{"type":34,"value":10214},{"type":29,"tag":88,"props":10267,"children":10268},{"style":157},[10269],{"type":34,"value":10270}," MySQL 8.0 : écarté car support JSON moins mature et licensing Oracle\n",{"type":29,"tag":88,"props":10272,"children":10273},{"class":90,"line":981},[10274,10278],{"type":29,"tag":88,"props":10275,"children":10276},{"style":10211},[10277],{"type":34,"value":10214},{"type":29,"tag":88,"props":10279,"children":10280},{"style":157},[10281],{"type":34,"value":10282}," MongoDB : écarté car nos données sont relationnelles\n",{"type":29,"tag":88,"props":10284,"children":10285},{"class":90,"line":1021},[10286,10290],{"type":29,"tag":88,"props":10287,"children":10288},{"style":10211},[10289],{"type":34,"value":10214},{"type":29,"tag":88,"props":10291,"children":10292},{"style":157},[10293],{"type":34,"value":10294}," DynamoDB : écarté car coût à l'usage imprévisible et expertise absente\n",{"type":29,"tag":2288,"props":10296,"children":10298},{"cta":2290,"href":2291,"title":10297,"type":2293},"Vous voulez savoir formuler une décision d'archi qui tienne la route six mois plus tard ?",[10299],{"type":29,"tag":30,"props":10300,"children":10301},{},[10302],{"type":34,"value":10303},"Rédiger un ADR qui capture vraiment le contexte, les contraintes et les alternatives, ça ne s'improvise pas : un développeur senior sait quelles décisions méritent d'être tracées et comment les écrire pour qu'elles servent. En mentoring 1:1, on travaille vos décisions techniques réelles ensemble, je vous montre comment raisonner sur les conséquences et les compromis. Vous gagnez le réflexe de documenter ce qui compte, sans noyer l'essentiel.",{"type":29,"tag":47,"props":10305,"children":10306},{},[],{"type":29,"tag":51,"props":10308,"children":10310},{"id":10309},"les-3-premières-adrs-à-rédiger",[10311],{"type":34,"value":10312},"Les 3 premières ADRs à rédiger",{"type":29,"tag":30,"props":10314,"children":10315},{},[10316],{"type":34,"value":10317},"Ne commencez pas par les décisions les plus anciennes ni les plus complexes. Commencez par les 3 décisions qui génèrent le plus de questions récurrentes.",{"type":29,"tag":30,"props":10319,"children":10320},{},[10321],{"type":34,"value":10322},"Pour identifier lesquelles, je pose toujours ces questions :",{"type":29,"tag":453,"props":10324,"children":10325},{},[10326,10331,10336],{"type":29,"tag":457,"props":10327,"children":10328},{},[10329],{"type":34,"value":10330},"Quelle décision technique revient en débat à chaque onboarding d'un nouveau développeur ?",{"type":29,"tag":457,"props":10332,"children":10333},{},[10334],{"type":34,"value":10335},"Quelle décision architecturale génère des \"oui mais pourquoi ?\" récurrents en code review ?",{"type":29,"tag":457,"props":10337,"children":10338},{},[10339],{"type":34,"value":10340},"Quelle décision récente mérite d'être documentée pendant que le contexte est encore frais ?",{"type":29,"tag":30,"props":10342,"children":10343},{},[10344,10346,10352],{"type":34,"value":10345},"Pour les décisions prises sans documentation, je recommande d'écrire l'ADR avec ce qu'on sait, même imparfaitement. Un ADR incomplet vaut mieux que pas d'ADR. Le statut ",{"type":29,"tag":84,"props":10347,"children":10349},{"className":10348},[],[10350],{"type":34,"value":10351},"reconstructed",{"type":34,"value":10353}," signale que le document a été rédigé après-coup.",{"type":29,"tag":47,"props":10355,"children":10356},{},[],{"type":29,"tag":51,"props":10358,"children":10360},{"id":10359},"organisation-et-rituels-de-maintenance",[10361],{"type":34,"value":10362},"Organisation et rituels de maintenance",{"type":29,"tag":30,"props":10364,"children":10365},{},[10366],{"type":34,"value":10367},"Je recommande cette structure dans le dépôt Git :",{"type":29,"tag":77,"props":10369,"children":10371},{"code":10370},"docs\u002F\n  architecture\u002F\n    decisions\u002F\n      0001-postgresql-base-de-donnees.md\n      0002-event-driven-architecture.md\n      0003-monorepo-structure.md\n    README.md  ← index des ADRs avec titre et statut\n",[10372],{"type":29,"tag":84,"props":10373,"children":10374},{"__ignoreMap":8},[10375],{"type":34,"value":10370},{"type":29,"tag":30,"props":10377,"children":10378},{},[10379],{"type":34,"value":10380},"Trois règles de maintenance que j'impose à toutes les équipes que j'accompagne :",{"type":29,"tag":30,"props":10382,"children":10383},{},[10384,10389],{"type":29,"tag":447,"props":10385,"children":10386},{},[10387],{"type":34,"value":10388},"Numérotation séquentielle.",{"type":34,"value":10390}," ADR-0001, ADR-0002... La chronologie fait partie de l'information.",{"type":29,"tag":30,"props":10392,"children":10393},{},[10394,10399],{"type":29,"tag":447,"props":10395,"children":10396},{},[10397],{"type":34,"value":10398},"Ne jamais modifier ni supprimer une ADR.",{"type":34,"value":10400}," Seulement la superseder avec une nouvelle. La trace historique a de la valeur : comprendre pourquoi une décision a changé est aussi utile que la décision actuelle.",{"type":29,"tag":30,"props":10402,"children":10403},{},[10404,10409],{"type":29,"tag":447,"props":10405,"children":10406},{},[10407],{"type":34,"value":10408},"Rituel de PR.",{"type":34,"value":10410}," À chaque pull request contenant un changement architectural significatif, vérifier si une ADR doit être créée ou mise à jour. Ce check peut être intégré dans le template de PR.",{"type":29,"tag":30,"props":10412,"children":10413},{},[10414,10416,10422],{"type":34,"value":10415},"L'outil ",{"type":29,"tag":84,"props":10417,"children":10419},{"className":10418},[],[10420],{"type":34,"value":10421},"adr-tools",{"type":34,"value":10423}," (CLI open source) génère et gère les ADRs depuis le terminal. Pour les équipes sur Confluence, l'intégration est possible, mais je garde toujours le dépôt Git comme source de vérité.",{"type":29,"tag":47,"props":10425,"children":10426},{},[],{"type":29,"tag":51,"props":10428,"children":10430},{"id":10429},"le-piège-de-la-rétro-documentation-exhaustive",[10431],{"type":34,"value":10432},"Le piège de la rétro-documentation exhaustive",{"type":29,"tag":7066,"props":10434,"children":10435},{},[10436],{"type":29,"tag":30,"props":10437,"children":10438},{},[10439],{"type":34,"value":10440},"Ne pas essayer de documenter toutes les décisions passées d'un coup. La rétro-documentation exhaustive est un projet qui ne se termine pas et qui décourage l'équipe avant qu'elle prenne le pli.",{"type":29,"tag":30,"props":10442,"children":10443},{},[10444],{"type":34,"value":10445},"Ma recommandation : documenter toutes les nouvelles décisions systématiquement à partir d'aujourd'hui, et rattraper les décisions passées au fil des besoins : lors des onboardings, des débats récurrents, ou des refactorings qui remettent en question des choix passés.",{"type":29,"tag":30,"props":10447,"children":10448},{},[10449],{"type":34,"value":10450},"En 3 mois à ce rythme, les équipes que j'accompagne ont entre 15 et 25 ADRs actives. C'est suffisant pour changer la culture.",{"type":29,"tag":47,"props":10452,"children":10453},{},[],{"type":29,"tag":51,"props":10455,"children":10457},{"id":10456},"ce-que-ça-change-concrètement",[10458],{"type":34,"value":10459},"Ce que ça change concrètement",{"type":29,"tag":10461,"props":10462,"children":10463},"table",{},[10464,10483],{"type":29,"tag":10465,"props":10466,"children":10467},"thead",{},[10468],{"type":29,"tag":10469,"props":10470,"children":10471},"tr",{},[10472,10478],{"type":29,"tag":10473,"props":10474,"children":10475},"th",{},[10476],{"type":34,"value":10477},"Action",{"type":29,"tag":10473,"props":10479,"children":10480},{},[10481],{"type":34,"value":10482},"Résultat",{"type":29,"tag":10484,"props":10485,"children":10486},"tbody",{},[10487,10501,10514,10527],{"type":29,"tag":10469,"props":10488,"children":10489},{},[10490,10496],{"type":29,"tag":10491,"props":10492,"children":10493},"td",{},[10494],{"type":34,"value":10495},"Calculer le coût des décisions non documentées",{"type":29,"tag":10491,"props":10497,"children":10498},{},[10499],{"type":34,"value":10500},"Conviction de l'équipe",{"type":29,"tag":10469,"props":10502,"children":10503},{},[10504,10509],{"type":29,"tag":10491,"props":10505,"children":10506},{},[10507],{"type":34,"value":10508},"Adopter le template en 5 sections",{"type":29,"tag":10491,"props":10510,"children":10511},{},[10512],{"type":34,"value":10513},"Format standardisé",{"type":29,"tag":10469,"props":10515,"children":10516},{},[10517,10522],{"type":29,"tag":10491,"props":10518,"children":10519},{},[10520],{"type":34,"value":10521},"Rédiger les 3 premières ADRs prioritaires",{"type":29,"tag":10491,"props":10523,"children":10524},{},[10525],{"type":34,"value":10526},"Premières ADRs dans le dépôt",{"type":29,"tag":10469,"props":10528,"children":10529},{},[10530,10535],{"type":29,"tag":10491,"props":10531,"children":10532},{},[10533],{"type":34,"value":10534},"Setup le registre et les rituels de PR",{"type":29,"tag":10491,"props":10536,"children":10537},{},[10538],{"type":34,"value":10539},"Processus pérenne",{"type":29,"tag":2288,"props":10541,"children":10543},{"cta":5629,"href":5630,"title":10542,"type":5632},"Documenter ses décisions, c'est une pratique parmi les 100 qui séparent un dev d'un artisan",[10544],{"type":29,"tag":30,"props":10545,"children":10546},{},[10547],{"type":34,"value":10548},"Cet article détaille une seule pratique : tracer ses décisions d'architecture avec des ADRs. Le Craft Bundle réunit les 100 pratiques que j'applique au quotidien pour coder propre et raisonner comme un senior, depuis la conception jusqu'à la maintenance. Ce sont les réflexes qu'on acquiert sur le terrain, ceux que l'IA ne vous apprendra jamais parce qu'elle ne les a jamais vus tourner en prod.",{"type":29,"tag":47,"props":10550,"children":10551},{},[],{"type":29,"tag":51,"props":10553,"children":10555},{"id":10554},"faq-sur-les-adrs",[10556],{"type":34,"value":10557},"FAQ sur les ADRs",{"type":29,"tag":5649,"props":10559,"children":10560},{},[10561,10566],{"type":29,"tag":5653,"props":10562,"children":10563},{},[10564],{"type":34,"value":10565},"1. Où stocker les ADRs : dans le dépôt Git ou dans Confluence\u002FNotion ?",{"type":29,"tag":30,"props":10567,"children":10568},{},[10569],{"type":34,"value":10570},"Dans le dépôt Git, si possible. Les ADRs sont du code de documentation : elles doivent versionner avec le code qu'elles documentent. Une ADR dans Git est visible dans les PR, peut être liée aux commits concernés, et survit aux migrations d'outils. Si votre organisation exige Confluence pour la documentation, utilisez-le en complément, mais gardez le dépôt Git comme source de vérité. J'ai vu trop d'ADRs perdues lors de migrations Confluence.",{"type":29,"tag":5649,"props":10572,"children":10573},{},[10574,10579],{"type":29,"tag":5653,"props":10575,"children":10576},{},[10577],{"type":34,"value":10578},"2. Faut-il un ADR pour chaque décision technique ou seulement les grandes décisions d'architecture ?",{"type":29,"tag":30,"props":10580,"children":10581},{},[10582,10584,10590],{"type":34,"value":10583},"Seulement les décisions significatives : choix de technologie, choix d'architecture (microservices vs monolithe, synchrone vs asynchrone), patterns de design appliqués à l'ensemble du système, décisions de sécurité ou de conformité. Pas besoin d'ADR pour les décisions de code quotidiennes : quel nom de variable, quelle structure de fichier dans un composant. La règle empirique que j'utilise : si la décision fera débat dans 6 mois, elle mérite une ADR. Par exemple, le choix d'adopter un ",{"type":29,"tag":63,"props":10585,"children":10587},{"href":10586},"\u002Ffr\u002Farchitecture-craft\u002Fdatabase-per-service-microservices",[10588],{"type":34,"value":10589},"pattern Database per Service dans une architecture microservices",{"type":34,"value":10591}," est typiquement le genre de décision qui doit être documentée dans une ADR.",{"type":29,"tag":5649,"props":10593,"children":10594},{},[10595,10600],{"type":29,"tag":5653,"props":10596,"children":10597},{},[10598],{"type":34,"value":10599},"3. Que faire quand une ADR ancienne devient obsolète ?",{"type":29,"tag":30,"props":10601,"children":10602},{},[10603,10605,10610,10612,10616],{"type":34,"value":10604},"Créer une nouvelle ADR qui supersede l'ancienne. L'ancienne garde son statut ",{"type":29,"tag":84,"props":10606,"children":10608},{"className":10607},[],[10609],{"type":34,"value":10057},{"type":34,"value":10611}," avec une référence vers la nouvelle. Jamais modifier l'ADR originale : la trace historique des décisions a de la valeur, même quand elles sont remplacées. Comprendre ",{"type":29,"tag":9979,"props":10613,"children":10614},{},[10615],{"type":34,"value":9983},{"type":34,"value":10617}," une décision a changé est souvent aussi utile que comprendre la décision actuelle.",{"type":29,"tag":5649,"props":10619,"children":10620},{},[10621,10626],{"type":29,"tag":5653,"props":10622,"children":10623},{},[10624],{"type":34,"value":10625},"4. Comment introduire les ADRs dans une équipe qui n'a jamais documenté ses décisions ?",{"type":29,"tag":30,"props":10627,"children":10628},{},[10629],{"type":34,"value":10630},"Je commence toujours par l'exemple. Je rédige les 3 premières ADRs moi-même, les présente en réunion d'équipe, et explique la valeur qu'elles auraient eue lors de situations passées concrètes, des situations que l'équipe reconnaît. Ensuite, j'invite les développeurs à rédiger les ADRs pour leurs prochaines décisions avec du support. Après 3 cycles, la pratique s'installe naturellement.",{"type":29,"tag":5649,"props":10632,"children":10633},{},[10634,10639],{"type":29,"tag":5653,"props":10635,"children":10636},{},[10637],{"type":34,"value":10638},"5. Est-ce que les ADRs ralentissent le processus de décision ?",{"type":29,"tag":30,"props":10640,"children":10641},{},[10642,10644,10649],{"type":34,"value":10643},"Non, et c'est le contrepoint que j'entends toujours. Rédiger une ADR prend 30 minutes. Refaire le même débat dans 6 mois prend 3 heures, mobilise 5 personnes, et produit parfois une décision différente de la précédente sans raison valable. Le retour sur investissement est immédiat après la première ADR utilisée pour clore un débat récurrent. C'est d'autant plus vrai pour un CTO en début de mandat : parmi les ",{"type":29,"tag":63,"props":10645,"children":10646},{"href":9852},[10647],{"type":34,"value":10648},"90 premiers jours d'un CTO",{"type":34,"value":10650},", poser les bases de la gouvernance architecturale (dont les ADRs) est l'une des décisions structurantes les plus durables.",{"type":29,"tag":47,"props":10652,"children":10653},{},[],{"type":29,"tag":2288,"props":10655,"children":10656},{"cta":5752,"href":5753,"title":5754,"type":5755},[10657],{"type":29,"tag":30,"props":10658,"children":10659},{},[10660],{"type":34,"value":10661},"L'Engineering Maturity Self-Assessment couvre le domaine Gouvernance & Documentation : évaluez votre maturité sur les pratiques de décision architecturale, la documentation, et la cohérence du système. Score et plan d'action en 10 minutes.",{"type":29,"tag":5763,"props":10663,"children":10664},{},[10665],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":10667},[10668,10669,10670,10671,10672,10673,10674],{"id":9924,"depth":101,"text":9927},{"id":9991,"depth":101,"text":9994},{"id":10309,"depth":101,"text":10312},{"id":10359,"depth":101,"text":10362},{"id":10429,"depth":101,"text":10432},{"id":10456,"depth":101,"text":10459},{"id":10554,"depth":101,"text":10557},"content:fr:architecture-craft:adr-architecture-decision-record.md","fr\u002Farchitecture-craft\u002Fadr-architecture-decision-record.md","fr\u002Farchitecture-craft\u002Fadr-architecture-decision-record",{"_path":10679,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":10680,"description":10681,"id":3470,"date":10682,"listed":13,"nocomments":7,"hidden":7,"categories":10683,"tags":10684,"cover":10686,"readingTime":10687,"body":10692,"_type":5777,"_id":16276,"_source":5779,"_file":16277,"_stem":16278,"_extension":5782},"\u002Ffr\u002Farchitecture-craft\u002Fdecomposer-monolithe-microservices-ddd-api-hexagonal-java","Décomposer un Monolithe en Microservices avec DDD, API First et Architecture Hexagonale","Découvrez comment transformer votre monolithe en microservices grâce au Domain-Driven Design (DDD), à l’approche API First et à l’architecture hexagonale...","2024-08-23",[6],[17,10685],"software-craftsmanship","covers\u002Farticles\u002Fmonolithe-to-microservice.jpg",{"text":10688,"minutes":10689,"time":10690,"words":10691},"14 min read",13.445,806700,2689,{"type":26,"children":10693,"toc":16252},[10694,10703,10708,10720,10746,10758,10761,10770,10804,10813,10825,10830,10863,10874,10918,10927,10939,10944,11281,11286,11302,11305,11319,11328,11345,11354,11366,11400,11462,11471,11483,12001,12006,12034,12045,12061,12066,12077,12080,12089,12106,12118,12127,12132,12164,12174,12179,12212,12221,12232,12244,12538,12550,12934,12946,13265,13295,13298,13307,13319,13328,13339,13357,13367,13788,13797,13808,14617,14626,15055,15067,15076,15962,15985,15988,15997,16020,16028,16068,16078,16111,16114,16123,16126,16135,16159,16185,16205,16224,16237,16248],{"type":29,"tag":51,"props":10695,"children":10697},{"id":10696},"pourquoi-décomposer-un-monolithe",[10698],{"type":29,"tag":447,"props":10699,"children":10700},{},[10701],{"type":34,"value":10702},"Pourquoi décomposer un monolithe",{"type":29,"tag":30,"props":10704,"children":10705},{},[10706],{"type":34,"value":10707},"Une application monolithique de plusieurs centaines de milliers de lignes. Chaque nouvelle fonctionnalité donne des sueurs froides. Chaque déploiement ressemble à une roulette russe. Vous corrigez un bug ici, trois autres apparaissent ailleurs. C’est exactement le scénario rencontré dans plusieurs grandes équipes que j’accompagnais (bancaire et médias notamment) où les lead times de release dépassaient parfois 6 semaines.",{"type":29,"tag":30,"props":10709,"children":10710},{},[10711,10713,10718],{"type":34,"value":10712},"Le diagnostic est connu : l'application est devenue trop couplée, et la cure de ",{"type":29,"tag":447,"props":10714,"children":10715},{},[10716],{"type":34,"value":10717},"microservices",{"type":34,"value":10719}," s'impose. Casser un monolithe en petits services indépendants reste pourtant un exercice risqué. Personne ne veut transformer un système difficile à maintenir en une centaine de services tout aussi instables.",{"type":29,"tag":30,"props":10721,"children":10722},{},[10723,10725,10730,10732,10737,10739,10744],{"type":34,"value":10724},"Avec les bonnes méthodes, ce découpage devient maîtrisable. Le ",{"type":29,"tag":447,"props":10726,"children":10727},{},[10728],{"type":34,"value":10729},"Domain-Driven Design (DDD)",{"type":34,"value":10731},", l’approche ",{"type":29,"tag":447,"props":10733,"children":10734},{},[10735],{"type":34,"value":10736},"API First",{"type":34,"value":10738}," et l’",{"type":29,"tag":447,"props":10740,"children":10741},{},[10742],{"type":34,"value":10743},"architecture hexagonale",{"type":34,"value":10745}," servent justement à ne pas découper au hasard : ils structurent les microservices autour des vrais besoins métier, les exposent proprement et les organisent pour rester maintenables.",{"type":29,"tag":30,"props":10747,"children":10748},{},[10749,10751,10756],{"type":34,"value":10750},"Cet article montre comment articuler ces trois leviers en pratique, avec des exemples concrets en ",{"type":29,"tag":447,"props":10752,"children":10753},{},[10754],{"type":34,"value":10755},"Java",{"type":34,"value":10757},", et comment éviter les pièges récurrents que j’ai vus se répéter sur ce type de migration.",{"type":29,"tag":47,"props":10759,"children":10760},{},[],{"type":29,"tag":51,"props":10762,"children":10764},{"id":10763},"domain-driven-design-ddd-concentrons-nous-sur-les-besoins-métier",[10765],{"type":29,"tag":447,"props":10766,"children":10767},{},[10768],{"type":34,"value":10769},"Domain-Driven Design (DDD) : Concentrons-nous sur les besoins métier",{"type":29,"tag":30,"props":10771,"children":10772},{},[10773,10775,10780,10782,10787,10789,10794,10796,10802],{"type":34,"value":10774},"Le ",{"type":29,"tag":447,"props":10776,"children":10777},{},[10778],{"type":34,"value":10779},"Domain-Driven Design",{"type":34,"value":10781}," (ou DDD pour les intimes, formalisé par Eric Evans dans son ouvrage \"Domain-Driven Design\") est souvent vu comme une approche compliquée, pleine de jargon. Sam Newman, dans ",{"type":29,"tag":9979,"props":10783,"children":10784},{},[10785],{"type":34,"value":10786},"Building Microservices",{"type":34,"value":10788},", complète ce cadre en expliquant comment les Bounded Contexts DDD deviennent les frontières naturelles de vos services. Mais en réalité, c’est un excellent moyen de structurer vos microservices autour des ",{"type":29,"tag":447,"props":10790,"children":10791},{},[10792],{"type":34,"value":10793},"vrais",{"type":34,"value":10795}," besoins métier de votre application. Pour modéliser ces domaines avec les équipes, l’",{"type":29,"tag":63,"props":10797,"children":10799},{"href":10798},"\u002Ffr\u002Farchitecture-craft\u002Fevent-storming-atelier-modelisation",[10800],{"type":34,"value":10801},"atelier Event Storming",{"type":34,"value":10803}," est l’outil le plus efficace que j’aie utilisé en mission. C’est bien mieux que de découper un monolithe au hasard.",{"type":29,"tag":6010,"props":10805,"children":10807},{"id":10806},"le-principe-des-bounded-contexts-où-commencer",[10808],{"type":29,"tag":447,"props":10809,"children":10810},{},[10811],{"type":34,"value":10812},"Le principe des Bounded Contexts : où commencer ?",{"type":29,"tag":30,"props":10814,"children":10815},{},[10816,10818,10823],{"type":34,"value":10817},"Le DDD repose sur une idée simple : votre application représente plusieurs domaines fonctionnels, et chacun de ces domaines peut avoir des règles, des comportements et des modèles de données spécifiques. Pour bien découper votre monolithe, il faut donc commencer par identifier ces ",{"type":29,"tag":447,"props":10819,"children":10820},{},[10821],{"type":34,"value":10822},"Bounded Contexts",{"type":34,"value":10824}," (c'est-à-dire les frontières logiques où chaque microservice va évoluer).",{"type":29,"tag":30,"props":10826,"children":10827},{},[10828],{"type":34,"value":10829},"Par exemple, dans une application de gestion commerciale, vous pourriez avoir plusieurs domaines comme :",{"type":29,"tag":453,"props":10831,"children":10832},{},[10833,10843,10853],{"type":29,"tag":457,"props":10834,"children":10835},{},[10836,10841],{"type":29,"tag":447,"props":10837,"children":10838},{},[10839],{"type":34,"value":10840},"Catalogue produit",{"type":34,"value":10842}," : gérer les produits, les catégories, les descriptions.",{"type":29,"tag":457,"props":10844,"children":10845},{},[10846,10851],{"type":29,"tag":447,"props":10847,"children":10848},{},[10849],{"type":34,"value":10850},"Panier et commande",{"type":34,"value":10852}," : gérer les paniers d’achats, les commandes, les paiements.",{"type":29,"tag":457,"props":10854,"children":10855},{},[10856,10861],{"type":29,"tag":447,"props":10857,"children":10858},{},[10859],{"type":34,"value":10860},"Gestion des utilisateurs",{"type":34,"value":10862}," : gérer les comptes, les profils, les adresses.",{"type":29,"tag":30,"props":10864,"children":10865},{},[10866,10868,10872],{"type":34,"value":10867},"Chaque domaine est indépendant (ou presque) et correspondra à un microservice. Ces ",{"type":29,"tag":447,"props":10869,"children":10870},{},[10871],{"type":34,"value":10822},{"type":34,"value":10873}," définissent les limites de chaque service et empêchent les données de s’entremêler.",{"type":29,"tag":7066,"props":10875,"children":10876},{},[10877,10885],{"type":29,"tag":30,"props":10878,"children":10879},{},[10880],{"type":29,"tag":447,"props":10881,"children":10882},{},[10883],{"type":34,"value":10884},"Tip : Comment bien choisir vos Bounded Contexts ?",{"type":29,"tag":453,"props":10886,"children":10887},{},[10888,10898,10908],{"type":29,"tag":457,"props":10889,"children":10890},{},[10891,10896],{"type":29,"tag":447,"props":10892,"children":10893},{},[10894],{"type":34,"value":10895},"Pensez métier",{"type":34,"value":10897}," : Les développeurs aiment souvent découper en fonction du code, mais pensez avant tout en termes de besoins métier. Quels sont les domaines fonctionnels qui ne se mélangent pas ?",{"type":29,"tag":457,"props":10899,"children":10900},{},[10901,10906],{"type":29,"tag":447,"props":10902,"children":10903},{},[10904],{"type":34,"value":10905},"Évitez la sur-segmentation",{"type":34,"value":10907}," : Si vous découpez trop finement, vous risquez d’avoir des microservices qui font très peu de choses mais dépendent énormément des autres, ce qui est un cauchemar à gérer.",{"type":29,"tag":457,"props":10909,"children":10910},{},[10911,10916],{"type":29,"tag":447,"props":10912,"children":10913},{},[10914],{"type":34,"value":10915},"Testez vos hypothèses",{"type":34,"value":10917}," : Je vous recommande de discuter avec les équipes produit ou métier pour valider vos choix. Si une partie du code concerne des règles spécifiques à un domaine fonctionnel, vous êtes probablement sur la bonne voie.",{"type":29,"tag":6010,"props":10919,"children":10921},{"id":10920},"exemple-en-java-structurer-un-service-autour-dun-bounded-context",[10922],{"type":29,"tag":447,"props":10923,"children":10924},{},[10925],{"type":34,"value":10926},"Exemple en Java : Structurer un service autour d'un Bounded Context",{"type":29,"tag":30,"props":10928,"children":10929},{},[10930,10932,10937],{"type":34,"value":10931},"Prenons l'exemple d'un service de gestion de ",{"type":29,"tag":447,"props":10933,"children":10934},{},[10935],{"type":34,"value":10936},"panier",{"type":34,"value":10938}," dans une application de commande.",{"type":29,"tag":30,"props":10940,"children":10941},{},[10942],{"type":34,"value":10943},"Vous pouvez structurer votre projet Java autour de ce Bounded Context de cette manière :",{"type":29,"tag":77,"props":10945,"children":10947},{"code":10946,"language":80,"meta":8,"className":81,"style":8},"public class Cart {\n    private List\u003CItem> items;\n\n    public void addItem(Item item) {\n        items.add(item);\n    }\n\n    public void removeItem(Item item) {\n        items.remove(item);\n    }\n\n    public double calculateTotal() {\n        return items.stream()\n            .mapToDouble(Item::getPrice)\n            .sum();\n    }\n}\n",[10948],{"type":29,"tag":84,"props":10949,"children":10950},{"__ignoreMap":8},[10951,10971,11003,11010,11047,11076,11083,11090,11126,11154,11161,11168,11193,11217,11251,11267,11274],{"type":29,"tag":88,"props":10952,"children":10953},{"class":90,"line":91},[10954,10958,10962,10967],{"type":29,"tag":88,"props":10955,"children":10956},{"style":105},[10957],{"type":34,"value":108},{"type":29,"tag":88,"props":10959,"children":10960},{"style":105},[10961],{"type":34,"value":113},{"type":29,"tag":88,"props":10963,"children":10964},{"style":116},[10965],{"type":34,"value":10966}," Cart",{"type":29,"tag":88,"props":10968,"children":10969},{"style":122},[10970],{"type":34,"value":125},{"type":29,"tag":88,"props":10972,"children":10973},{"class":90,"line":101},[10974,10978,10982,10986,10991,10995,10999],{"type":29,"tag":88,"props":10975,"children":10976},{"style":105},[10977],{"type":34,"value":143},{"type":29,"tag":88,"props":10979,"children":10980},{"style":151},[10981],{"type":34,"value":5355},{"type":29,"tag":88,"props":10983,"children":10984},{"style":122},[10985],{"type":34,"value":1683},{"type":29,"tag":88,"props":10987,"children":10988},{"style":105},[10989],{"type":34,"value":10990},"Item",{"type":29,"tag":88,"props":10992,"children":10993},{"style":122},[10994],{"type":34,"value":1701},{"type":29,"tag":88,"props":10996,"children":10997},{"style":157},[10998],{"type":34,"value":2173},{"type":29,"tag":88,"props":11000,"children":11001},{"style":122},[11002],{"type":34,"value":424},{"type":29,"tag":88,"props":11004,"children":11005},{"class":90,"line":128},[11006],{"type":29,"tag":88,"props":11007,"children":11008},{"emptyLinePlaceholder":13},[11009],{"type":34,"value":134},{"type":29,"tag":88,"props":11011,"children":11012},{"class":90,"line":137},[11013,11017,11021,11026,11030,11034,11039,11043],{"type":29,"tag":88,"props":11014,"children":11015},{"style":105},[11016],{"type":34,"value":276},{"type":29,"tag":88,"props":11018,"children":11019},{"style":105},[11020],{"type":34,"value":1303},{"type":29,"tag":88,"props":11022,"children":11023},{"style":174},[11024],{"type":34,"value":11025}," addItem",{"type":29,"tag":88,"props":11027,"children":11028},{"style":122},[11029],{"type":34,"value":181},{"type":29,"tag":88,"props":11031,"children":11032},{"style":151},[11033],{"type":34,"value":10990},{"type":29,"tag":88,"props":11035,"children":11036},{"style":298},[11037],{"type":34,"value":11038}," item",{"type":29,"tag":88,"props":11040,"children":11041},{"style":122},[11042],{"type":34,"value":306},{"type":29,"tag":88,"props":11044,"children":11045},{"style":122},[11046],{"type":34,"value":125},{"type":29,"tag":88,"props":11048,"children":11049},{"class":90,"line":211},[11050,11055,11059,11063,11067,11072],{"type":29,"tag":88,"props":11051,"children":11052},{"style":157},[11053],{"type":34,"value":11054},"        items",{"type":29,"tag":88,"props":11056,"children":11057},{"style":122},[11058],{"type":34,"value":338},{"type":29,"tag":88,"props":11060,"children":11061},{"style":174},[11062],{"type":34,"value":5471},{"type":29,"tag":88,"props":11064,"children":11065},{"style":122},[11066],{"type":34,"value":181},{"type":29,"tag":88,"props":11068,"children":11069},{"style":157},[11070],{"type":34,"value":11071},"item",{"type":29,"tag":88,"props":11073,"children":11074},{"style":122},[11075],{"type":34,"value":357},{"type":29,"tag":88,"props":11077,"children":11078},{"class":90,"line":262},[11079],{"type":29,"tag":88,"props":11080,"children":11081},{"style":122},[11082],{"type":34,"value":433},{"type":29,"tag":88,"props":11084,"children":11085},{"class":90,"line":270},[11086],{"type":29,"tag":88,"props":11087,"children":11088},{"emptyLinePlaceholder":13},[11089],{"type":34,"value":134},{"type":29,"tag":88,"props":11091,"children":11092},{"class":90,"line":313},[11093,11097,11101,11106,11110,11114,11118,11122],{"type":29,"tag":88,"props":11094,"children":11095},{"style":105},[11096],{"type":34,"value":276},{"type":29,"tag":88,"props":11098,"children":11099},{"style":105},[11100],{"type":34,"value":1303},{"type":29,"tag":88,"props":11102,"children":11103},{"style":174},[11104],{"type":34,"value":11105}," removeItem",{"type":29,"tag":88,"props":11107,"children":11108},{"style":122},[11109],{"type":34,"value":181},{"type":29,"tag":88,"props":11111,"children":11112},{"style":151},[11113],{"type":34,"value":10990},{"type":29,"tag":88,"props":11115,"children":11116},{"style":298},[11117],{"type":34,"value":11038},{"type":29,"tag":88,"props":11119,"children":11120},{"style":122},[11121],{"type":34,"value":306},{"type":29,"tag":88,"props":11123,"children":11124},{"style":122},[11125],{"type":34,"value":125},{"type":29,"tag":88,"props":11127,"children":11128},{"class":90,"line":360},[11129,11133,11137,11142,11146,11150],{"type":29,"tag":88,"props":11130,"children":11131},{"style":157},[11132],{"type":34,"value":11054},{"type":29,"tag":88,"props":11134,"children":11135},{"style":122},[11136],{"type":34,"value":338},{"type":29,"tag":88,"props":11138,"children":11139},{"style":174},[11140],{"type":34,"value":11141},"remove",{"type":29,"tag":88,"props":11143,"children":11144},{"style":122},[11145],{"type":34,"value":181},{"type":29,"tag":88,"props":11147,"children":11148},{"style":157},[11149],{"type":34,"value":11071},{"type":29,"tag":88,"props":11151,"children":11152},{"style":122},[11153],{"type":34,"value":357},{"type":29,"tag":88,"props":11155,"children":11156},{"class":90,"line":409},[11157],{"type":29,"tag":88,"props":11158,"children":11159},{"style":122},[11160],{"type":34,"value":433},{"type":29,"tag":88,"props":11162,"children":11163},{"class":90,"line":427},[11164],{"type":29,"tag":88,"props":11165,"children":11166},{"emptyLinePlaceholder":13},[11167],{"type":34,"value":134},{"type":29,"tag":88,"props":11169,"children":11170},{"class":90,"line":436},[11171,11175,11180,11185,11189],{"type":29,"tag":88,"props":11172,"children":11173},{"style":105},[11174],{"type":34,"value":276},{"type":29,"tag":88,"props":11176,"children":11177},{"style":105},[11178],{"type":34,"value":11179}," double",{"type":29,"tag":88,"props":11181,"children":11182},{"style":174},[11183],{"type":34,"value":11184}," calculateTotal",{"type":29,"tag":88,"props":11186,"children":11187},{"style":122},[11188],{"type":34,"value":1470},{"type":29,"tag":88,"props":11190,"children":11191},{"style":122},[11192],{"type":34,"value":125},{"type":29,"tag":88,"props":11194,"children":11195},{"class":90,"line":767},[11196,11200,11204,11208,11213],{"type":29,"tag":88,"props":11197,"children":11198},{"style":105},[11199],{"type":34,"value":415},{"type":29,"tag":88,"props":11201,"children":11202},{"style":157},[11203],{"type":34,"value":2173},{"type":29,"tag":88,"props":11205,"children":11206},{"style":122},[11207],{"type":34,"value":338},{"type":29,"tag":88,"props":11209,"children":11210},{"style":174},[11211],{"type":34,"value":11212},"stream",{"type":29,"tag":88,"props":11214,"children":11215},{"style":122},[11216],{"type":34,"value":2863},{"type":29,"tag":88,"props":11218,"children":11219},{"class":90,"line":792},[11220,11224,11229,11233,11237,11242,11247],{"type":29,"tag":88,"props":11221,"children":11222},{"style":122},[11223],{"type":34,"value":3132},{"type":29,"tag":88,"props":11225,"children":11226},{"style":174},[11227],{"type":34,"value":11228},"mapToDouble",{"type":29,"tag":88,"props":11230,"children":11231},{"style":122},[11232],{"type":34,"value":181},{"type":29,"tag":88,"props":11234,"children":11235},{"style":157},[11236],{"type":34,"value":10990},{"type":29,"tag":88,"props":11238,"children":11239},{"style":105},[11240],{"type":34,"value":11241},"::",{"type":29,"tag":88,"props":11243,"children":11244},{"style":157},[11245],{"type":34,"value":11246},"getPrice",{"type":29,"tag":88,"props":11248,"children":11249},{"style":122},[11250],{"type":34,"value":3078},{"type":29,"tag":88,"props":11252,"children":11253},{"class":90,"line":817},[11254,11258,11263],{"type":29,"tag":88,"props":11255,"children":11256},{"style":122},[11257],{"type":34,"value":3132},{"type":29,"tag":88,"props":11259,"children":11260},{"style":174},[11261],{"type":34,"value":11262},"sum",{"type":29,"tag":88,"props":11264,"children":11265},{"style":122},[11266],{"type":34,"value":1810},{"type":29,"tag":88,"props":11268,"children":11269},{"class":90,"line":825},[11270],{"type":29,"tag":88,"props":11271,"children":11272},{"style":122},[11273],{"type":34,"value":433},{"type":29,"tag":88,"props":11275,"children":11276},{"class":90,"line":869},[11277],{"type":29,"tag":88,"props":11278,"children":11279},{"style":122},[11280],{"type":34,"value":442},{"type":29,"tag":30,"props":11282,"children":11283},{},[11284],{"type":34,"value":11285},"Ce service s'occupe exclusivement de la gestion du panier, et ne doit pas se préoccuper des autres parties de l’application comme la gestion des produits ou des utilisateurs. En appliquant ce découpage DDD, on s'assure que chaque service est bien isolé autour d'un besoin métier spécifique.",{"type":29,"tag":7066,"props":11287,"children":11288},{},[11289,11297],{"type":29,"tag":30,"props":11290,"children":11291},{},[11292],{"type":29,"tag":447,"props":11293,"children":11294},{},[11295],{"type":34,"value":11296},"Alerte : Ne vous éparpillez pas !",{"type":29,"tag":30,"props":11298,"children":11299},{},[11300],{"type":34,"value":11301},"Assurez-vous de ne pas découper trop finement, au risque de créer des services trop petits qui multiplient les dépendances entre eux. Restez concentré sur des domaines bien définis.",{"type":29,"tag":47,"props":11303,"children":11304},{},[],{"type":29,"tag":2288,"props":11306,"children":11308},{"cta":2290,"href":2291,"title":11307,"type":2293},"Vous voulez savoir tracer vous-même les frontières de vos Bounded Contexts ?",[11309,11314],{"type":29,"tag":30,"props":11310,"children":11311},{},[11312],{"type":34,"value":11313},"Découper un domaine au bon endroit, ça ne se devine pas dans un article : ça se travaille sur votre code, avec vos vrais cas. En mentoring 1:1, on prend vos modules les plus emmêlés et je vous montre comment isoler un contexte, dessiner ses ports et garder le domaine propre.",{"type":29,"tag":30,"props":11315,"children":11316},{},[11317],{"type":34,"value":11318},"Vous repartez avec le réflexe de structurer un service hexagonal sans le coupler à sa technique, et la confiance pour le refaire seul sur la prochaine migration.",{"type":29,"tag":51,"props":11320,"children":11322},{"id":11321},"api-first-limportance-dexposer-et-de-consommer-correctement-vos-apis",[11323],{"type":29,"tag":447,"props":11324,"children":11325},{},[11326],{"type":34,"value":11327},"API First : L'importance d'exposer et de consommer correctement vos APIs",{"type":29,"tag":30,"props":11329,"children":11330},{},[11331,11333,11337,11339,11343],{"type":34,"value":11332},"Une fois vos ",{"type":29,"tag":447,"props":11334,"children":11335},{},[11336],{"type":34,"value":10822},{"type":34,"value":11338}," identifiés grâce au DDD, la communication entre microservices devient le sujet central. L’approche ",{"type":29,"tag":447,"props":11340,"children":11341},{},[11342],{"type":34,"value":10736},{"type":34,"value":11344}," y répond directement : avant d’écrire la moindre ligne de code, vous concevez et documentez vos API. Cette discipline force à réfléchir aux échanges entre services dès le début, et évite les contrats mal pensés qui se transforment vite en dette technique.",{"type":29,"tag":6010,"props":11346,"children":11348},{"id":11347},"pourquoi-lapproche-api-first-est-cruciale",[11349],{"type":29,"tag":447,"props":11350,"children":11351},{},[11352],{"type":34,"value":11353},"Pourquoi l’approche API First est cruciale ?",{"type":29,"tag":30,"props":11355,"children":11356},{},[11357,11359,11364],{"type":34,"value":11358},"Dans une architecture microservices, chaque service doit pouvoir communiquer avec les autres de manière claire, évolutive, et surtout, ",{"type":29,"tag":447,"props":11360,"children":11361},{},[11362],{"type":34,"value":11363},"prévisible",{"type":34,"value":11365},". Si vos APIs sont mal définies, vous allez créer de la dette technique dès le départ. Voici pourquoi une approche API First est essentielle :",{"type":29,"tag":11367,"props":11368,"children":11369},"ol",{},[11370,11380,11390],{"type":29,"tag":457,"props":11371,"children":11372},{},[11373,11378],{"type":29,"tag":447,"props":11374,"children":11375},{},[11376],{"type":34,"value":11377},"Prévisibilité",{"type":34,"value":11379}," : Quand une API est bien documentée, les équipes qui la consomment savent à quoi s'attendre. Plus de mauvaises surprises en découvrant un champ manquant ou une réponse différente de ce qui était anticipé.",{"type":29,"tag":457,"props":11381,"children":11382},{},[11383,11388],{"type":29,"tag":447,"props":11384,"children":11385},{},[11386],{"type":34,"value":11387},"Évolutivité",{"type":34,"value":11389}," : Une API bien pensée est facile à faire évoluer sans casser les implémentations existantes. Cela vous permet d'ajouter de nouvelles fonctionnalités sans perturber les services qui consomment cette API.",{"type":29,"tag":457,"props":11391,"children":11392},{},[11393,11398],{"type":29,"tag":447,"props":11394,"children":11395},{},[11396],{"type":34,"value":11397},"Dépendances réduites",{"type":34,"value":11399}," : Si chaque service expose une API claire et indépendante, il devient beaucoup plus facile de gérer les dépendances entre les équipes et les services.",{"type":29,"tag":7066,"props":11401,"children":11402},{},[11403,11411,11429],{"type":29,"tag":30,"props":11404,"children":11405},{},[11406],{"type":29,"tag":447,"props":11407,"children":11408},{},[11409],{"type":34,"value":11410},"Tip : La documentation avant l’implémentation",{"type":29,"tag":30,"props":11412,"children":11413},{},[11414,11416,11421,11422,11427],{"type":34,"value":11415},"Utilisez des outils comme ",{"type":29,"tag":447,"props":11417,"children":11418},{},[11419],{"type":34,"value":11420},"Swagger",{"type":34,"value":5730},{"type":29,"tag":447,"props":11423,"children":11424},{},[11425],{"type":34,"value":11426},"OpenAPI",{"type":34,"value":11428}," pour documenter vos APIs avant même de commencer à écrire du code. Cela vous permet de :",{"type":29,"tag":453,"props":11430,"children":11431},{},[11432,11442,11452],{"type":29,"tag":457,"props":11433,"children":11434},{},[11435,11440],{"type":29,"tag":447,"props":11436,"children":11437},{},[11438],{"type":34,"value":11439},"Valider",{"type":34,"value":11441}," l’API avec les autres équipes (back-end, front-end, mobile) pour vous assurer que tout le monde est sur la même longueur d’onde.",{"type":29,"tag":457,"props":11443,"children":11444},{},[11445,11450],{"type":29,"tag":447,"props":11446,"children":11447},{},[11448],{"type":34,"value":11449},"Prototyper",{"type":34,"value":11451}," rapidement les interactions entre services sans attendre l’implémentation complète.",{"type":29,"tag":457,"props":11453,"children":11454},{},[11455,11460],{"type":29,"tag":447,"props":11456,"children":11457},{},[11458],{"type":34,"value":11459},"Tester",{"type":34,"value":11461}," facilement les API avec des outils comme Postman avant d’entrer dans la logique métier plus complexe.",{"type":29,"tag":6010,"props":11463,"children":11465},{"id":11464},"exemple-en-java-avec-spring-boot-définir-une-api-pour-le-service-panier",[11466],{"type":29,"tag":447,"props":11467,"children":11468},{},[11469],{"type":34,"value":11470},"Exemple en Java avec Spring Boot : Définir une API pour le service Panier",{"type":29,"tag":30,"props":11472,"children":11473},{},[11474,11476,11481],{"type":34,"value":11475},"Imaginons que vous ayez un microservice ",{"type":29,"tag":447,"props":11477,"children":11478},{},[11479],{"type":34,"value":11480},"Panier",{"type":34,"value":11482},", qui gère les actions liées au panier d’achats de vos utilisateurs. Voilà à quoi ressemble une API pour ajouter des articles au panier.",{"type":29,"tag":77,"props":11484,"children":11486},{"code":11485,"language":80,"meta":8,"className":81,"style":8},"@RestController\n@RequestMapping(\"\u002Fapi\u002Fcart\")\npublic class CartController {\n\n    private final CartService cartService;\n\n    public CartController(CartService cartService) {\n        this.cartService = cartService;\n    }\n\n    @PostMapping(\"\u002Fadd\")\n    public ResponseEntity\u003CCart> addItemToCart(@RequestBody Item item) {\n        Cart updatedCart = cartService.addItem(item);\n        return ResponseEntity.ok(updatedCart);\n    }\n\n    @GetMapping(\"\u002F{cartId}\")\n    public ResponseEntity\u003CCart> getCart(@PathVariable String cartId) {\n        Cart cart = cartService.getCart(cartId);\n        return ResponseEntity.ok(cart);\n    }\n}\n",[11487],{"type":29,"tag":84,"props":11488,"children":11489},{"__ignoreMap":8},[11490,11501,11525,11545,11552,11577,11584,11616,11644,11651,11658,11683,11741,11783,11816,11823,11830,11855,11913,11955,11987,11994],{"type":29,"tag":88,"props":11491,"children":11492},{"class":90,"line":91},[11493,11497],{"type":29,"tag":88,"props":11494,"children":11495},{"style":1974},[11496],{"type":34,"value":1977},{"type":29,"tag":88,"props":11498,"children":11499},{"style":1980},[11500],{"type":34,"value":9193},{"type":29,"tag":88,"props":11502,"children":11503},{"class":90,"line":101},[11504,11508,11512,11516,11521],{"type":29,"tag":88,"props":11505,"children":11506},{"style":1974},[11507],{"type":34,"value":1977},{"type":29,"tag":88,"props":11509,"children":11510},{"style":1980},[11511],{"type":34,"value":9205},{"type":29,"tag":88,"props":11513,"children":11514},{"style":122},[11515],{"type":34,"value":181},{"type":29,"tag":88,"props":11517,"children":11518},{"style":184},[11519],{"type":34,"value":11520},"\"\u002Fapi\u002Fcart\"",{"type":29,"tag":88,"props":11522,"children":11523},{"style":122},[11524],{"type":34,"value":3078},{"type":29,"tag":88,"props":11526,"children":11527},{"class":90,"line":128},[11528,11532,11536,11541],{"type":29,"tag":88,"props":11529,"children":11530},{"style":105},[11531],{"type":34,"value":108},{"type":29,"tag":88,"props":11533,"children":11534},{"style":105},[11535],{"type":34,"value":113},{"type":29,"tag":88,"props":11537,"children":11538},{"style":116},[11539],{"type":34,"value":11540}," CartController",{"type":29,"tag":88,"props":11542,"children":11543},{"style":122},[11544],{"type":34,"value":125},{"type":29,"tag":88,"props":11546,"children":11547},{"class":90,"line":137},[11548],{"type":29,"tag":88,"props":11549,"children":11550},{"emptyLinePlaceholder":13},[11551],{"type":34,"value":134},{"type":29,"tag":88,"props":11553,"children":11554},{"class":90,"line":211},[11555,11559,11563,11568,11573],{"type":29,"tag":88,"props":11556,"children":11557},{"style":105},[11558],{"type":34,"value":143},{"type":29,"tag":88,"props":11560,"children":11561},{"style":105},[11562],{"type":34,"value":148},{"type":29,"tag":88,"props":11564,"children":11565},{"style":151},[11566],{"type":34,"value":11567}," CartService",{"type":29,"tag":88,"props":11569,"children":11570},{"style":157},[11571],{"type":34,"value":11572}," cartService",{"type":29,"tag":88,"props":11574,"children":11575},{"style":122},[11576],{"type":34,"value":424},{"type":29,"tag":88,"props":11578,"children":11579},{"class":90,"line":262},[11580],{"type":29,"tag":88,"props":11581,"children":11582},{"emptyLinePlaceholder":13},[11583],{"type":34,"value":134},{"type":29,"tag":88,"props":11585,"children":11586},{"class":90,"line":270},[11587,11591,11595,11599,11604,11608,11612],{"type":29,"tag":88,"props":11588,"children":11589},{"style":105},[11590],{"type":34,"value":276},{"type":29,"tag":88,"props":11592,"children":11593},{"style":174},[11594],{"type":34,"value":11540},{"type":29,"tag":88,"props":11596,"children":11597},{"style":122},[11598],{"type":34,"value":181},{"type":29,"tag":88,"props":11600,"children":11601},{"style":151},[11602],{"type":34,"value":11603},"CartService",{"type":29,"tag":88,"props":11605,"children":11606},{"style":298},[11607],{"type":34,"value":11572},{"type":29,"tag":88,"props":11609,"children":11610},{"style":122},[11611],{"type":34,"value":306},{"type":29,"tag":88,"props":11613,"children":11614},{"style":122},[11615],{"type":34,"value":125},{"type":29,"tag":88,"props":11617,"children":11618},{"class":90,"line":313},[11619,11623,11627,11632,11636,11640],{"type":29,"tag":88,"props":11620,"children":11621},{"style":873},[11622],{"type":34,"value":876},{"type":29,"tag":88,"props":11624,"children":11625},{"style":122},[11626],{"type":34,"value":338},{"type":29,"tag":88,"props":11628,"children":11629},{"style":157},[11630],{"type":34,"value":11631},"cartService ",{"type":29,"tag":88,"props":11633,"children":11634},{"style":163},[11635],{"type":34,"value":166},{"type":29,"tag":88,"props":11637,"children":11638},{"style":157},[11639],{"type":34,"value":11572},{"type":29,"tag":88,"props":11641,"children":11642},{"style":122},[11643],{"type":34,"value":424},{"type":29,"tag":88,"props":11645,"children":11646},{"class":90,"line":360},[11647],{"type":29,"tag":88,"props":11648,"children":11649},{"style":122},[11650],{"type":34,"value":433},{"type":29,"tag":88,"props":11652,"children":11653},{"class":90,"line":409},[11654],{"type":29,"tag":88,"props":11655,"children":11656},{"emptyLinePlaceholder":13},[11657],{"type":34,"value":134},{"type":29,"tag":88,"props":11659,"children":11660},{"class":90,"line":427},[11661,11665,11670,11674,11679],{"type":29,"tag":88,"props":11662,"children":11663},{"style":1974},[11664],{"type":34,"value":3302},{"type":29,"tag":88,"props":11666,"children":11667},{"style":1980},[11668],{"type":34,"value":11669},"PostMapping",{"type":29,"tag":88,"props":11671,"children":11672},{"style":122},[11673],{"type":34,"value":181},{"type":29,"tag":88,"props":11675,"children":11676},{"style":184},[11677],{"type":34,"value":11678},"\"\u002Fadd\"",{"type":29,"tag":88,"props":11680,"children":11681},{"style":122},[11682],{"type":34,"value":3078},{"type":29,"tag":88,"props":11684,"children":11685},{"class":90,"line":436},[11686,11690,11694,11698,11703,11707,11712,11716,11720,11724,11729,11733,11737],{"type":29,"tag":88,"props":11687,"children":11688},{"style":105},[11689],{"type":34,"value":276},{"type":29,"tag":88,"props":11691,"children":11692},{"style":151},[11693],{"type":34,"value":9367},{"type":29,"tag":88,"props":11695,"children":11696},{"style":122},[11697],{"type":34,"value":1683},{"type":29,"tag":88,"props":11699,"children":11700},{"style":105},[11701],{"type":34,"value":11702},"Cart",{"type":29,"tag":88,"props":11704,"children":11705},{"style":122},[11706],{"type":34,"value":1701},{"type":29,"tag":88,"props":11708,"children":11709},{"style":174},[11710],{"type":34,"value":11711}," addItemToCart",{"type":29,"tag":88,"props":11713,"children":11714},{"style":122},[11715],{"type":34,"value":181},{"type":29,"tag":88,"props":11717,"children":11718},{"style":1974},[11719],{"type":34,"value":1977},{"type":29,"tag":88,"props":11721,"children":11722},{"style":1980},[11723],{"type":34,"value":9398},{"type":29,"tag":88,"props":11725,"children":11726},{"style":151},[11727],{"type":34,"value":11728}," Item",{"type":29,"tag":88,"props":11730,"children":11731},{"style":298},[11732],{"type":34,"value":11038},{"type":29,"tag":88,"props":11734,"children":11735},{"style":122},[11736],{"type":34,"value":306},{"type":29,"tag":88,"props":11738,"children":11739},{"style":122},[11740],{"type":34,"value":125},{"type":29,"tag":88,"props":11742,"children":11743},{"class":90,"line":767},[11744,11749,11754,11758,11762,11766,11771,11775,11779],{"type":29,"tag":88,"props":11745,"children":11746},{"style":151},[11747],{"type":34,"value":11748},"        Cart",{"type":29,"tag":88,"props":11750,"children":11751},{"style":157},[11752],{"type":34,"value":11753}," updatedCart ",{"type":29,"tag":88,"props":11755,"children":11756},{"style":163},[11757],{"type":34,"value":166},{"type":29,"tag":88,"props":11759,"children":11760},{"style":157},[11761],{"type":34,"value":11572},{"type":29,"tag":88,"props":11763,"children":11764},{"style":122},[11765],{"type":34,"value":338},{"type":29,"tag":88,"props":11767,"children":11768},{"style":174},[11769],{"type":34,"value":11770},"addItem",{"type":29,"tag":88,"props":11772,"children":11773},{"style":122},[11774],{"type":34,"value":181},{"type":29,"tag":88,"props":11776,"children":11777},{"style":157},[11778],{"type":34,"value":11071},{"type":29,"tag":88,"props":11780,"children":11781},{"style":122},[11782],{"type":34,"value":357},{"type":29,"tag":88,"props":11784,"children":11785},{"class":90,"line":792},[11786,11790,11794,11798,11803,11807,11812],{"type":29,"tag":88,"props":11787,"children":11788},{"style":105},[11789],{"type":34,"value":415},{"type":29,"tag":88,"props":11791,"children":11792},{"style":157},[11793],{"type":34,"value":9367},{"type":29,"tag":88,"props":11795,"children":11796},{"style":122},[11797],{"type":34,"value":338},{"type":29,"tag":88,"props":11799,"children":11800},{"style":174},[11801],{"type":34,"value":11802},"ok",{"type":29,"tag":88,"props":11804,"children":11805},{"style":122},[11806],{"type":34,"value":181},{"type":29,"tag":88,"props":11808,"children":11809},{"style":157},[11810],{"type":34,"value":11811},"updatedCart",{"type":29,"tag":88,"props":11813,"children":11814},{"style":122},[11815],{"type":34,"value":357},{"type":29,"tag":88,"props":11817,"children":11818},{"class":90,"line":817},[11819],{"type":29,"tag":88,"props":11820,"children":11821},{"style":122},[11822],{"type":34,"value":433},{"type":29,"tag":88,"props":11824,"children":11825},{"class":90,"line":825},[11826],{"type":29,"tag":88,"props":11827,"children":11828},{"emptyLinePlaceholder":13},[11829],{"type":34,"value":134},{"type":29,"tag":88,"props":11831,"children":11832},{"class":90,"line":869},[11833,11837,11842,11846,11851],{"type":29,"tag":88,"props":11834,"children":11835},{"style":1974},[11836],{"type":34,"value":3302},{"type":29,"tag":88,"props":11838,"children":11839},{"style":1980},[11840],{"type":34,"value":11841},"GetMapping",{"type":29,"tag":88,"props":11843,"children":11844},{"style":122},[11845],{"type":34,"value":181},{"type":29,"tag":88,"props":11847,"children":11848},{"style":184},[11849],{"type":34,"value":11850},"\"\u002F{cartId}\"",{"type":29,"tag":88,"props":11852,"children":11853},{"style":122},[11854],{"type":34,"value":3078},{"type":29,"tag":88,"props":11856,"children":11857},{"class":90,"line":900},[11858,11862,11866,11870,11874,11878,11883,11887,11891,11896,11900,11905,11909],{"type":29,"tag":88,"props":11859,"children":11860},{"style":105},[11861],{"type":34,"value":276},{"type":29,"tag":88,"props":11863,"children":11864},{"style":151},[11865],{"type":34,"value":9367},{"type":29,"tag":88,"props":11867,"children":11868},{"style":122},[11869],{"type":34,"value":1683},{"type":29,"tag":88,"props":11871,"children":11872},{"style":105},[11873],{"type":34,"value":11702},{"type":29,"tag":88,"props":11875,"children":11876},{"style":122},[11877],{"type":34,"value":1701},{"type":29,"tag":88,"props":11879,"children":11880},{"style":174},[11881],{"type":34,"value":11882}," getCart",{"type":29,"tag":88,"props":11884,"children":11885},{"style":122},[11886],{"type":34,"value":181},{"type":29,"tag":88,"props":11888,"children":11889},{"style":1974},[11890],{"type":34,"value":1977},{"type":29,"tag":88,"props":11892,"children":11893},{"style":1980},[11894],{"type":34,"value":11895},"PathVariable",{"type":29,"tag":88,"props":11897,"children":11898},{"style":151},[11899],{"type":34,"value":281},{"type":29,"tag":88,"props":11901,"children":11902},{"style":298},[11903],{"type":34,"value":11904}," cartId",{"type":29,"tag":88,"props":11906,"children":11907},{"style":122},[11908],{"type":34,"value":306},{"type":29,"tag":88,"props":11910,"children":11911},{"style":122},[11912],{"type":34,"value":125},{"type":29,"tag":88,"props":11914,"children":11915},{"class":90,"line":929},[11916,11920,11925,11929,11933,11937,11942,11946,11951],{"type":29,"tag":88,"props":11917,"children":11918},{"style":151},[11919],{"type":34,"value":11748},{"type":29,"tag":88,"props":11921,"children":11922},{"style":157},[11923],{"type":34,"value":11924}," cart ",{"type":29,"tag":88,"props":11926,"children":11927},{"style":163},[11928],{"type":34,"value":166},{"type":29,"tag":88,"props":11930,"children":11931},{"style":157},[11932],{"type":34,"value":11572},{"type":29,"tag":88,"props":11934,"children":11935},{"style":122},[11936],{"type":34,"value":338},{"type":29,"tag":88,"props":11938,"children":11939},{"style":174},[11940],{"type":34,"value":11941},"getCart",{"type":29,"tag":88,"props":11943,"children":11944},{"style":122},[11945],{"type":34,"value":181},{"type":29,"tag":88,"props":11947,"children":11948},{"style":157},[11949],{"type":34,"value":11950},"cartId",{"type":29,"tag":88,"props":11952,"children":11953},{"style":122},[11954],{"type":34,"value":357},{"type":29,"tag":88,"props":11956,"children":11957},{"class":90,"line":937},[11958,11962,11966,11970,11974,11978,11983],{"type":29,"tag":88,"props":11959,"children":11960},{"style":105},[11961],{"type":34,"value":415},{"type":29,"tag":88,"props":11963,"children":11964},{"style":157},[11965],{"type":34,"value":9367},{"type":29,"tag":88,"props":11967,"children":11968},{"style":122},[11969],{"type":34,"value":338},{"type":29,"tag":88,"props":11971,"children":11972},{"style":174},[11973],{"type":34,"value":11802},{"type":29,"tag":88,"props":11975,"children":11976},{"style":122},[11977],{"type":34,"value":181},{"type":29,"tag":88,"props":11979,"children":11980},{"style":157},[11981],{"type":34,"value":11982},"cart",{"type":29,"tag":88,"props":11984,"children":11985},{"style":122},[11986],{"type":34,"value":357},{"type":29,"tag":88,"props":11988,"children":11989},{"class":90,"line":945},[11990],{"type":29,"tag":88,"props":11991,"children":11992},{"style":122},[11993],{"type":34,"value":433},{"type":29,"tag":88,"props":11995,"children":11996},{"class":90,"line":981},[11997],{"type":29,"tag":88,"props":11998,"children":11999},{"style":122},[12000],{"type":34,"value":442},{"type":29,"tag":30,"props":12002,"children":12003},{},[12004],{"type":34,"value":12005},"Ici, on expose deux endpoints simples :",{"type":29,"tag":453,"props":12007,"children":12008},{},[12009,12022],{"type":29,"tag":457,"props":12010,"children":12011},{},[12012,12014,12020],{"type":34,"value":12013},"Un endpoint ",{"type":29,"tag":84,"props":12015,"children":12017},{"className":12016},[],[12018],{"type":34,"value":12019},"POST \u002Fapi\u002Fcart\u002Fadd",{"type":34,"value":12021}," pour ajouter un item au panier.",{"type":29,"tag":457,"props":12023,"children":12024},{},[12025,12026,12032],{"type":34,"value":12013},{"type":29,"tag":84,"props":12027,"children":12029},{"className":12028},[],[12030],{"type":34,"value":12031},"GET \u002Fapi\u002Fcart\u002F{cartId}",{"type":34,"value":12033}," pour récupérer l’état du panier.",{"type":29,"tag":30,"props":12035,"children":12036},{},[12037,12039,12043],{"type":34,"value":12038},"Avant même de coder cela, vous pourriez déjà définir ces endpoints avec ",{"type":29,"tag":447,"props":12040,"children":12041},{},[12042],{"type":34,"value":11420},{"type":34,"value":12044}," afin que les équipes consommatrices puissent tester et donner leur feedback.",{"type":29,"tag":7066,"props":12046,"children":12047},{},[12048,12056],{"type":29,"tag":30,"props":12049,"children":12050},{},[12051],{"type":29,"tag":447,"props":12052,"children":12053},{},[12054],{"type":34,"value":12055},"Alerte : Ne sous-estimez pas le versionnage d'API",{"type":29,"tag":30,"props":12057,"children":12058},{},[12059],{"type":34,"value":12060},"Pensez à versionner vos APIs dès le départ.",{"type":29,"tag":30,"props":12062,"children":12063},{},[12064],{"type":34,"value":12065},"Cela vous permet de déployer de nouvelles fonctionnalités sans casser les anciennes. Un exemple de structure d'URL :",{"type":29,"tag":7066,"props":12067,"children":12068},{},[12069],{"type":29,"tag":77,"props":12070,"children":12072},{"code":12071},"\u002Fapi\u002Fv1\u002Fcart\u002Fadd\n",[12073],{"type":29,"tag":84,"props":12074,"children":12075},{"__ignoreMap":8},[12076],{"type":34,"value":12071},{"type":29,"tag":47,"props":12078,"children":12079},{},[],{"type":29,"tag":51,"props":12081,"children":12083},{"id":12082},"architecture-hexagonale-structurer-le-projet-avec-application-domaine-et-infrastructure",[12084],{"type":29,"tag":447,"props":12085,"children":12086},{},[12087],{"type":34,"value":12088},"Architecture Hexagonale : Structurer le projet avec Application, Domaine et Infrastructure",{"type":29,"tag":30,"props":12090,"children":12091},{},[12092,12094,12098,12100,12104],{"type":34,"value":12093},"L'",{"type":29,"tag":447,"props":12095,"children":12096},{},[12097],{"type":34,"value":10743},{"type":34,"value":12099}," (ou architecture en ports et adaptateurs) est un modèle qui vise à séparer clairement les différentes couches de votre application pour la rendre plus modulaire et maintenable. Elle partage avec la ",{"type":29,"tag":63,"props":12101,"children":12102},{"href":65},[12103],{"type":34,"value":68},{"type":34,"value":12105}," le même principe fondamental : les dépendances pointent vers l'intérieur, vers le domaine métier. Dans le cadre d'une transition vers des microservices, elle permet de structurer vos services de manière à ce que le domaine métier reste au cœur de l'implémentation, tandis que les détails techniques (comme les bases de données, les APIs externes, etc.) soient placés en périphérie.",{"type":29,"tag":30,"props":12107,"children":12108},{},[12109,12111,12116],{"type":34,"value":12110},"Le concept est simple : votre application est comme un hexagone, où chaque côté représente une interface qui connecte le cœur de l’application (la ",{"type":29,"tag":447,"props":12112,"children":12113},{},[12114],{"type":34,"value":12115},"logique métier",{"type":34,"value":12117},") à ses dépendances extérieures (base de données, APIs, interface utilisateur). Alistair Cockburn, qui a formalisé ce pattern sous le nom \"Ports and Adapters\", en décrit l’essence dans ses écrits : protéger le domaine de tout changement technologique périphérique.",{"type":29,"tag":6010,"props":12119,"children":12121},{"id":12120},"pourquoi-adopter-larchitecture-hexagonale-pour-vos-microservices",[12122],{"type":29,"tag":447,"props":12123,"children":12124},{},[12125],{"type":34,"value":12126},"Pourquoi adopter l’architecture hexagonale pour vos microservices ?",{"type":29,"tag":30,"props":12128,"children":12129},{},[12130],{"type":34,"value":12131},"Voici trois avantages principaux de l'architecture hexagonale :",{"type":29,"tag":11367,"props":12133,"children":12134},{},[12135,12145,12155],{"type":29,"tag":457,"props":12136,"children":12137},{},[12138,12143],{"type":29,"tag":447,"props":12139,"children":12140},{},[12141],{"type":34,"value":12142},"Séparation claire des préoccupations",{"type":34,"value":12144}," : En plaçant la logique métier au centre, vous assurez que vos règles de gestion ne sont pas affectées par la manière dont les données sont stockées ou envoyées. Cela rend votre code plus facile à maintenir et à tester.",{"type":29,"tag":457,"props":12146,"children":12147},{},[12148,12153],{"type":29,"tag":447,"props":12149,"children":12150},{},[12151],{"type":34,"value":12152},"Facilité de test",{"type":34,"value":12154}," : En isolant les dépendances extérieures (comme la base de données ou les appels d’API), il devient plus facile de tester vos services avec des tests unitaires et d’intégration.",{"type":29,"tag":457,"props":12156,"children":12157},{},[12158,12162],{"type":29,"tag":447,"props":12159,"children":12160},{},[12161],{"type":34,"value":11387},{"type":34,"value":12163}," : Vous pouvez changer les technologies sous-jacentes (par exemple, passer d'une base SQL à NoSQL) sans impacter le cœur de votre application, car tout est isolé par des ports (interfaces).",{"type":29,"tag":12165,"props":12166,"children":12168},"h4",{"id":12167},"les-trois-couches-principales",[12169],{"type":29,"tag":447,"props":12170,"children":12171},{},[12172],{"type":34,"value":12173},"Les trois couches principales",{"type":29,"tag":30,"props":12175,"children":12176},{},[12177],{"type":34,"value":12178},"L'architecture hexagonale se décompose en trois grandes couches :",{"type":29,"tag":453,"props":12180,"children":12181},{},[12182,12192,12202],{"type":29,"tag":457,"props":12183,"children":12184},{},[12185,12190],{"type":29,"tag":447,"props":12186,"children":12187},{},[12188],{"type":34,"value":12189},"Domaine",{"type":34,"value":12191}," : C’est ici que se trouve toute la logique métier. Cette couche est totalement indépendante de la technologie utilisée.",{"type":29,"tag":457,"props":12193,"children":12194},{},[12195,12200],{"type":29,"tag":447,"props":12196,"children":12197},{},[12198],{"type":34,"value":12199},"Application",{"type":34,"value":12201}," : Elle orchestre les actions à réaliser et gère les cas d’utilisation. Elle appelle les services du domaine.",{"type":29,"tag":457,"props":12203,"children":12204},{},[12205,12210],{"type":29,"tag":447,"props":12206,"children":12207},{},[12208],{"type":34,"value":12209},"Infrastructure",{"type":34,"value":12211}," : Cette couche gère tout ce qui est technique, comme les interactions avec les bases de données, les APIs externes, etc. Elle s’adapte aux besoins du domaine via des interfaces.",{"type":29,"tag":6010,"props":12213,"children":12215},{"id":12214},"exemple-dimplémentation-en-java",[12216],{"type":29,"tag":447,"props":12217,"children":12218},{},[12219],{"type":34,"value":12220},"Exemple d'implémentation en Java",{"type":29,"tag":30,"props":12222,"children":12223},{},[12224,12226,12230],{"type":34,"value":12225},"Prenons l'exemple de notre service ",{"type":29,"tag":447,"props":12227,"children":12228},{},[12229],{"type":34,"value":11480},{"type":34,"value":12231}," (Cart). Nous allons structurer le code en suivant les principes de l'architecture hexagonale.",{"type":29,"tag":11367,"props":12233,"children":12234},{},[12235],{"type":29,"tag":457,"props":12236,"children":12237},{},[12238,12242],{"type":29,"tag":447,"props":12239,"children":12240},{},[12241],{"type":34,"value":12189},{"type":34,"value":12243}," : La couche qui gère les règles métiers. Elle est totalement indépendante de la base de données ou de toute autre technologie.",{"type":29,"tag":77,"props":12245,"children":12247},{"code":12246,"language":80,"meta":8,"className":81,"style":8},"public class Cart {\n    private List\u003CItem> items = new ArrayList\u003C>();\n\n    public void addItem(Item item) {\n        items.add(item);\n    }\n\n    public void removeItem(Item item) {\n        items.remove(item);\n    }\n\n    public List\u003CItem> getItems() {\n        return items;\n    }\n}\n",[12248],{"type":29,"tag":84,"props":12249,"children":12250},{"__ignoreMap":8},[12251,12270,12314,12321,12356,12383,12390,12397,12432,12459,12466,12473,12509,12524,12531],{"type":29,"tag":88,"props":12252,"children":12253},{"class":90,"line":91},[12254,12258,12262,12266],{"type":29,"tag":88,"props":12255,"children":12256},{"style":105},[12257],{"type":34,"value":108},{"type":29,"tag":88,"props":12259,"children":12260},{"style":105},[12261],{"type":34,"value":113},{"type":29,"tag":88,"props":12263,"children":12264},{"style":116},[12265],{"type":34,"value":10966},{"type":29,"tag":88,"props":12267,"children":12268},{"style":122},[12269],{"type":34,"value":125},{"type":29,"tag":88,"props":12271,"children":12272},{"class":90,"line":101},[12273,12277,12281,12285,12289,12293,12298,12302,12306,12310],{"type":29,"tag":88,"props":12274,"children":12275},{"style":105},[12276],{"type":34,"value":143},{"type":29,"tag":88,"props":12278,"children":12279},{"style":151},[12280],{"type":34,"value":5355},{"type":29,"tag":88,"props":12282,"children":12283},{"style":122},[12284],{"type":34,"value":1683},{"type":29,"tag":88,"props":12286,"children":12287},{"style":105},[12288],{"type":34,"value":10990},{"type":29,"tag":88,"props":12290,"children":12291},{"style":122},[12292],{"type":34,"value":1701},{"type":29,"tag":88,"props":12294,"children":12295},{"style":157},[12296],{"type":34,"value":12297}," items ",{"type":29,"tag":88,"props":12299,"children":12300},{"style":163},[12301],{"type":34,"value":166},{"type":29,"tag":88,"props":12303,"children":12304},{"style":105},[12305],{"type":34,"value":171},{"type":29,"tag":88,"props":12307,"children":12308},{"style":151},[12309],{"type":34,"value":5385},{"type":29,"tag":88,"props":12311,"children":12312},{"style":122},[12313],{"type":34,"value":1724},{"type":29,"tag":88,"props":12315,"children":12316},{"class":90,"line":128},[12317],{"type":29,"tag":88,"props":12318,"children":12319},{"emptyLinePlaceholder":13},[12320],{"type":34,"value":134},{"type":29,"tag":88,"props":12322,"children":12323},{"class":90,"line":137},[12324,12328,12332,12336,12340,12344,12348,12352],{"type":29,"tag":88,"props":12325,"children":12326},{"style":105},[12327],{"type":34,"value":276},{"type":29,"tag":88,"props":12329,"children":12330},{"style":105},[12331],{"type":34,"value":1303},{"type":29,"tag":88,"props":12333,"children":12334},{"style":174},[12335],{"type":34,"value":11025},{"type":29,"tag":88,"props":12337,"children":12338},{"style":122},[12339],{"type":34,"value":181},{"type":29,"tag":88,"props":12341,"children":12342},{"style":151},[12343],{"type":34,"value":10990},{"type":29,"tag":88,"props":12345,"children":12346},{"style":298},[12347],{"type":34,"value":11038},{"type":29,"tag":88,"props":12349,"children":12350},{"style":122},[12351],{"type":34,"value":306},{"type":29,"tag":88,"props":12353,"children":12354},{"style":122},[12355],{"type":34,"value":125},{"type":29,"tag":88,"props":12357,"children":12358},{"class":90,"line":211},[12359,12363,12367,12371,12375,12379],{"type":29,"tag":88,"props":12360,"children":12361},{"style":157},[12362],{"type":34,"value":11054},{"type":29,"tag":88,"props":12364,"children":12365},{"style":122},[12366],{"type":34,"value":338},{"type":29,"tag":88,"props":12368,"children":12369},{"style":174},[12370],{"type":34,"value":5471},{"type":29,"tag":88,"props":12372,"children":12373},{"style":122},[12374],{"type":34,"value":181},{"type":29,"tag":88,"props":12376,"children":12377},{"style":157},[12378],{"type":34,"value":11071},{"type":29,"tag":88,"props":12380,"children":12381},{"style":122},[12382],{"type":34,"value":357},{"type":29,"tag":88,"props":12384,"children":12385},{"class":90,"line":262},[12386],{"type":29,"tag":88,"props":12387,"children":12388},{"style":122},[12389],{"type":34,"value":433},{"type":29,"tag":88,"props":12391,"children":12392},{"class":90,"line":270},[12393],{"type":29,"tag":88,"props":12394,"children":12395},{"emptyLinePlaceholder":13},[12396],{"type":34,"value":134},{"type":29,"tag":88,"props":12398,"children":12399},{"class":90,"line":313},[12400,12404,12408,12412,12416,12420,12424,12428],{"type":29,"tag":88,"props":12401,"children":12402},{"style":105},[12403],{"type":34,"value":276},{"type":29,"tag":88,"props":12405,"children":12406},{"style":105},[12407],{"type":34,"value":1303},{"type":29,"tag":88,"props":12409,"children":12410},{"style":174},[12411],{"type":34,"value":11105},{"type":29,"tag":88,"props":12413,"children":12414},{"style":122},[12415],{"type":34,"value":181},{"type":29,"tag":88,"props":12417,"children":12418},{"style":151},[12419],{"type":34,"value":10990},{"type":29,"tag":88,"props":12421,"children":12422},{"style":298},[12423],{"type":34,"value":11038},{"type":29,"tag":88,"props":12425,"children":12426},{"style":122},[12427],{"type":34,"value":306},{"type":29,"tag":88,"props":12429,"children":12430},{"style":122},[12431],{"type":34,"value":125},{"type":29,"tag":88,"props":12433,"children":12434},{"class":90,"line":360},[12435,12439,12443,12447,12451,12455],{"type":29,"tag":88,"props":12436,"children":12437},{"style":157},[12438],{"type":34,"value":11054},{"type":29,"tag":88,"props":12440,"children":12441},{"style":122},[12442],{"type":34,"value":338},{"type":29,"tag":88,"props":12444,"children":12445},{"style":174},[12446],{"type":34,"value":11141},{"type":29,"tag":88,"props":12448,"children":12449},{"style":122},[12450],{"type":34,"value":181},{"type":29,"tag":88,"props":12452,"children":12453},{"style":157},[12454],{"type":34,"value":11071},{"type":29,"tag":88,"props":12456,"children":12457},{"style":122},[12458],{"type":34,"value":357},{"type":29,"tag":88,"props":12460,"children":12461},{"class":90,"line":409},[12462],{"type":29,"tag":88,"props":12463,"children":12464},{"style":122},[12465],{"type":34,"value":433},{"type":29,"tag":88,"props":12467,"children":12468},{"class":90,"line":427},[12469],{"type":29,"tag":88,"props":12470,"children":12471},{"emptyLinePlaceholder":13},[12472],{"type":34,"value":134},{"type":29,"tag":88,"props":12474,"children":12475},{"class":90,"line":436},[12476,12480,12484,12488,12492,12496,12501,12505],{"type":29,"tag":88,"props":12477,"children":12478},{"style":105},[12479],{"type":34,"value":276},{"type":29,"tag":88,"props":12481,"children":12482},{"style":151},[12483],{"type":34,"value":5355},{"type":29,"tag":88,"props":12485,"children":12486},{"style":122},[12487],{"type":34,"value":1683},{"type":29,"tag":88,"props":12489,"children":12490},{"style":105},[12491],{"type":34,"value":10990},{"type":29,"tag":88,"props":12493,"children":12494},{"style":122},[12495],{"type":34,"value":1701},{"type":29,"tag":88,"props":12497,"children":12498},{"style":174},[12499],{"type":34,"value":12500}," getItems",{"type":29,"tag":88,"props":12502,"children":12503},{"style":122},[12504],{"type":34,"value":1470},{"type":29,"tag":88,"props":12506,"children":12507},{"style":122},[12508],{"type":34,"value":125},{"type":29,"tag":88,"props":12510,"children":12511},{"class":90,"line":767},[12512,12516,12520],{"type":29,"tag":88,"props":12513,"children":12514},{"style":105},[12515],{"type":34,"value":415},{"type":29,"tag":88,"props":12517,"children":12518},{"style":157},[12519],{"type":34,"value":2173},{"type":29,"tag":88,"props":12521,"children":12522},{"style":122},[12523],{"type":34,"value":424},{"type":29,"tag":88,"props":12525,"children":12526},{"class":90,"line":792},[12527],{"type":29,"tag":88,"props":12528,"children":12529},{"style":122},[12530],{"type":34,"value":433},{"type":29,"tag":88,"props":12532,"children":12533},{"class":90,"line":817},[12534],{"type":29,"tag":88,"props":12535,"children":12536},{"style":122},[12537],{"type":34,"value":442},{"type":29,"tag":11367,"props":12539,"children":12540},{"start":101},[12541],{"type":29,"tag":457,"props":12542,"children":12543},{},[12544,12548],{"type":29,"tag":447,"props":12545,"children":12546},{},[12547],{"type":34,"value":12199},{"type":34,"value":12549}," : La couche qui orchestre les actions, comme ajouter un produit au panier.",{"type":29,"tag":77,"props":12551,"children":12553},{"code":12552,"language":80,"meta":8,"className":81,"style":8},"public class CartService {\n    private final CartRepository cartRepository;\n\n    public CartService(CartRepository cartRepository) {\n        this.cartRepository = cartRepository;\n    }\n\n    public Cart addItemToCart(String cartId, Item item) {\n        Cart cart = cartRepository.findById(cartId);\n        cart.addItem(item);\n        cartRepository.save(cart);\n        return cart;\n    }\n\n    public Cart getCart(String cartId) {\n        return cartRepository.findById(cartId);\n    }\n}\n",[12554],{"type":29,"tag":84,"props":12555,"children":12556},{"__ignoreMap":8},[12557,12576,12601,12608,12640,12668,12675,12682,12729,12768,12796,12824,12840,12847,12854,12889,12920,12927],{"type":29,"tag":88,"props":12558,"children":12559},{"class":90,"line":91},[12560,12564,12568,12572],{"type":29,"tag":88,"props":12561,"children":12562},{"style":105},[12563],{"type":34,"value":108},{"type":29,"tag":88,"props":12565,"children":12566},{"style":105},[12567],{"type":34,"value":113},{"type":29,"tag":88,"props":12569,"children":12570},{"style":116},[12571],{"type":34,"value":11567},{"type":29,"tag":88,"props":12573,"children":12574},{"style":122},[12575],{"type":34,"value":125},{"type":29,"tag":88,"props":12577,"children":12578},{"class":90,"line":101},[12579,12583,12587,12592,12597],{"type":29,"tag":88,"props":12580,"children":12581},{"style":105},[12582],{"type":34,"value":143},{"type":29,"tag":88,"props":12584,"children":12585},{"style":105},[12586],{"type":34,"value":148},{"type":29,"tag":88,"props":12588,"children":12589},{"style":151},[12590],{"type":34,"value":12591}," CartRepository",{"type":29,"tag":88,"props":12593,"children":12594},{"style":157},[12595],{"type":34,"value":12596}," cartRepository",{"type":29,"tag":88,"props":12598,"children":12599},{"style":122},[12600],{"type":34,"value":424},{"type":29,"tag":88,"props":12602,"children":12603},{"class":90,"line":128},[12604],{"type":29,"tag":88,"props":12605,"children":12606},{"emptyLinePlaceholder":13},[12607],{"type":34,"value":134},{"type":29,"tag":88,"props":12609,"children":12610},{"class":90,"line":137},[12611,12615,12619,12623,12628,12632,12636],{"type":29,"tag":88,"props":12612,"children":12613},{"style":105},[12614],{"type":34,"value":276},{"type":29,"tag":88,"props":12616,"children":12617},{"style":174},[12618],{"type":34,"value":11567},{"type":29,"tag":88,"props":12620,"children":12621},{"style":122},[12622],{"type":34,"value":181},{"type":29,"tag":88,"props":12624,"children":12625},{"style":151},[12626],{"type":34,"value":12627},"CartRepository",{"type":29,"tag":88,"props":12629,"children":12630},{"style":298},[12631],{"type":34,"value":12596},{"type":29,"tag":88,"props":12633,"children":12634},{"style":122},[12635],{"type":34,"value":306},{"type":29,"tag":88,"props":12637,"children":12638},{"style":122},[12639],{"type":34,"value":125},{"type":29,"tag":88,"props":12641,"children":12642},{"class":90,"line":211},[12643,12647,12651,12656,12660,12664],{"type":29,"tag":88,"props":12644,"children":12645},{"style":873},[12646],{"type":34,"value":876},{"type":29,"tag":88,"props":12648,"children":12649},{"style":122},[12650],{"type":34,"value":338},{"type":29,"tag":88,"props":12652,"children":12653},{"style":157},[12654],{"type":34,"value":12655},"cartRepository ",{"type":29,"tag":88,"props":12657,"children":12658},{"style":163},[12659],{"type":34,"value":166},{"type":29,"tag":88,"props":12661,"children":12662},{"style":157},[12663],{"type":34,"value":12596},{"type":29,"tag":88,"props":12665,"children":12666},{"style":122},[12667],{"type":34,"value":424},{"type":29,"tag":88,"props":12669,"children":12670},{"class":90,"line":262},[12671],{"type":29,"tag":88,"props":12672,"children":12673},{"style":122},[12674],{"type":34,"value":433},{"type":29,"tag":88,"props":12676,"children":12677},{"class":90,"line":270},[12678],{"type":29,"tag":88,"props":12679,"children":12680},{"emptyLinePlaceholder":13},[12681],{"type":34,"value":134},{"type":29,"tag":88,"props":12683,"children":12684},{"class":90,"line":313},[12685,12689,12693,12697,12701,12705,12709,12713,12717,12721,12725],{"type":29,"tag":88,"props":12686,"children":12687},{"style":105},[12688],{"type":34,"value":276},{"type":29,"tag":88,"props":12690,"children":12691},{"style":151},[12692],{"type":34,"value":10966},{"type":29,"tag":88,"props":12694,"children":12695},{"style":174},[12696],{"type":34,"value":11711},{"type":29,"tag":88,"props":12698,"children":12699},{"style":122},[12700],{"type":34,"value":181},{"type":29,"tag":88,"props":12702,"children":12703},{"style":151},[12704],{"type":34,"value":695},{"type":29,"tag":88,"props":12706,"children":12707},{"style":298},[12708],{"type":34,"value":11904},{"type":29,"tag":88,"props":12710,"children":12711},{"style":122},[12712],{"type":34,"value":192},{"type":29,"tag":88,"props":12714,"children":12715},{"style":151},[12716],{"type":34,"value":11728},{"type":29,"tag":88,"props":12718,"children":12719},{"style":298},[12720],{"type":34,"value":11038},{"type":29,"tag":88,"props":12722,"children":12723},{"style":122},[12724],{"type":34,"value":306},{"type":29,"tag":88,"props":12726,"children":12727},{"style":122},[12728],{"type":34,"value":125},{"type":29,"tag":88,"props":12730,"children":12731},{"class":90,"line":360},[12732,12736,12740,12744,12748,12752,12756,12760,12764],{"type":29,"tag":88,"props":12733,"children":12734},{"style":151},[12735],{"type":34,"value":11748},{"type":29,"tag":88,"props":12737,"children":12738},{"style":157},[12739],{"type":34,"value":11924},{"type":29,"tag":88,"props":12741,"children":12742},{"style":163},[12743],{"type":34,"value":166},{"type":29,"tag":88,"props":12745,"children":12746},{"style":157},[12747],{"type":34,"value":12596},{"type":29,"tag":88,"props":12749,"children":12750},{"style":122},[12751],{"type":34,"value":338},{"type":29,"tag":88,"props":12753,"children":12754},{"style":174},[12755],{"type":34,"value":3112},{"type":29,"tag":88,"props":12757,"children":12758},{"style":122},[12759],{"type":34,"value":181},{"type":29,"tag":88,"props":12761,"children":12762},{"style":157},[12763],{"type":34,"value":11950},{"type":29,"tag":88,"props":12765,"children":12766},{"style":122},[12767],{"type":34,"value":357},{"type":29,"tag":88,"props":12769,"children":12770},{"class":90,"line":409},[12771,12776,12780,12784,12788,12792],{"type":29,"tag":88,"props":12772,"children":12773},{"style":157},[12774],{"type":34,"value":12775},"        cart",{"type":29,"tag":88,"props":12777,"children":12778},{"style":122},[12779],{"type":34,"value":338},{"type":29,"tag":88,"props":12781,"children":12782},{"style":174},[12783],{"type":34,"value":11770},{"type":29,"tag":88,"props":12785,"children":12786},{"style":122},[12787],{"type":34,"value":181},{"type":29,"tag":88,"props":12789,"children":12790},{"style":157},[12791],{"type":34,"value":11071},{"type":29,"tag":88,"props":12793,"children":12794},{"style":122},[12795],{"type":34,"value":357},{"type":29,"tag":88,"props":12797,"children":12798},{"class":90,"line":427},[12799,12804,12808,12812,12816,12820],{"type":29,"tag":88,"props":12800,"children":12801},{"style":157},[12802],{"type":34,"value":12803},"        cartRepository",{"type":29,"tag":88,"props":12805,"children":12806},{"style":122},[12807],{"type":34,"value":338},{"type":29,"tag":88,"props":12809,"children":12810},{"style":174},[12811],{"type":34,"value":343},{"type":29,"tag":88,"props":12813,"children":12814},{"style":122},[12815],{"type":34,"value":181},{"type":29,"tag":88,"props":12817,"children":12818},{"style":157},[12819],{"type":34,"value":11982},{"type":29,"tag":88,"props":12821,"children":12822},{"style":122},[12823],{"type":34,"value":357},{"type":29,"tag":88,"props":12825,"children":12826},{"class":90,"line":436},[12827,12831,12836],{"type":29,"tag":88,"props":12828,"children":12829},{"style":105},[12830],{"type":34,"value":415},{"type":29,"tag":88,"props":12832,"children":12833},{"style":157},[12834],{"type":34,"value":12835}," cart",{"type":29,"tag":88,"props":12837,"children":12838},{"style":122},[12839],{"type":34,"value":424},{"type":29,"tag":88,"props":12841,"children":12842},{"class":90,"line":767},[12843],{"type":29,"tag":88,"props":12844,"children":12845},{"style":122},[12846],{"type":34,"value":433},{"type":29,"tag":88,"props":12848,"children":12849},{"class":90,"line":792},[12850],{"type":29,"tag":88,"props":12851,"children":12852},{"emptyLinePlaceholder":13},[12853],{"type":34,"value":134},{"type":29,"tag":88,"props":12855,"children":12856},{"class":90,"line":817},[12857,12861,12865,12869,12873,12877,12881,12885],{"type":29,"tag":88,"props":12858,"children":12859},{"style":105},[12860],{"type":34,"value":276},{"type":29,"tag":88,"props":12862,"children":12863},{"style":151},[12864],{"type":34,"value":10966},{"type":29,"tag":88,"props":12866,"children":12867},{"style":174},[12868],{"type":34,"value":11882},{"type":29,"tag":88,"props":12870,"children":12871},{"style":122},[12872],{"type":34,"value":181},{"type":29,"tag":88,"props":12874,"children":12875},{"style":151},[12876],{"type":34,"value":695},{"type":29,"tag":88,"props":12878,"children":12879},{"style":298},[12880],{"type":34,"value":11904},{"type":29,"tag":88,"props":12882,"children":12883},{"style":122},[12884],{"type":34,"value":306},{"type":29,"tag":88,"props":12886,"children":12887},{"style":122},[12888],{"type":34,"value":125},{"type":29,"tag":88,"props":12890,"children":12891},{"class":90,"line":825},[12892,12896,12900,12904,12908,12912,12916],{"type":29,"tag":88,"props":12893,"children":12894},{"style":105},[12895],{"type":34,"value":415},{"type":29,"tag":88,"props":12897,"children":12898},{"style":157},[12899],{"type":34,"value":12596},{"type":29,"tag":88,"props":12901,"children":12902},{"style":122},[12903],{"type":34,"value":338},{"type":29,"tag":88,"props":12905,"children":12906},{"style":174},[12907],{"type":34,"value":3112},{"type":29,"tag":88,"props":12909,"children":12910},{"style":122},[12911],{"type":34,"value":181},{"type":29,"tag":88,"props":12913,"children":12914},{"style":157},[12915],{"type":34,"value":11950},{"type":29,"tag":88,"props":12917,"children":12918},{"style":122},[12919],{"type":34,"value":357},{"type":29,"tag":88,"props":12921,"children":12922},{"class":90,"line":869},[12923],{"type":29,"tag":88,"props":12924,"children":12925},{"style":122},[12926],{"type":34,"value":433},{"type":29,"tag":88,"props":12928,"children":12929},{"class":90,"line":900},[12930],{"type":29,"tag":88,"props":12931,"children":12932},{"style":122},[12933],{"type":34,"value":442},{"type":29,"tag":11367,"props":12935,"children":12936},{"start":128},[12937],{"type":29,"tag":457,"props":12938,"children":12939},{},[12940,12944],{"type":29,"tag":447,"props":12941,"children":12942},{},[12943],{"type":34,"value":12209},{"type":34,"value":12945}," : Ici, nous implémentons les détails techniques, comme le stockage des données.",{"type":29,"tag":77,"props":12947,"children":12949},{"code":12948,"language":80,"meta":8,"className":81,"style":8},"@Repository\npublic class CartRepositoryImpl implements CartRepository {\n\n    private final Map\u003CString, Cart> database = new HashMap\u003C>();\n\n    @Override\n    public Cart findById(String cartId) {\n        return database.getOrDefault(cartId, new Cart());\n    }\n\n    @Override\n    public void save(Cart cart) {\n        database.put(\"cartId\", cart);\n    }\n}\n",[12950],{"type":29,"tag":84,"props":12951,"children":12952},{"__ignoreMap":8},[12953,12965,12993,13000,13056,13063,13074,13109,13154,13161,13168,13179,13214,13251,13258],{"type":29,"tag":88,"props":12954,"children":12955},{"class":90,"line":91},[12956,12960],{"type":29,"tag":88,"props":12957,"children":12958},{"style":1974},[12959],{"type":34,"value":1977},{"type":29,"tag":88,"props":12961,"children":12962},{"style":1980},[12963],{"type":34,"value":12964},"Repository\n",{"type":29,"tag":88,"props":12966,"children":12967},{"class":90,"line":101},[12968,12972,12976,12981,12985,12989],{"type":29,"tag":88,"props":12969,"children":12970},{"style":105},[12971],{"type":34,"value":108},{"type":29,"tag":88,"props":12973,"children":12974},{"style":105},[12975],{"type":34,"value":113},{"type":29,"tag":88,"props":12977,"children":12978},{"style":116},[12979],{"type":34,"value":12980}," CartRepositoryImpl",{"type":29,"tag":88,"props":12982,"children":12983},{"style":105},[12984],{"type":34,"value":1134},{"type":29,"tag":88,"props":12986,"children":12987},{"style":116},[12988],{"type":34,"value":12591},{"type":29,"tag":88,"props":12990,"children":12991},{"style":122},[12992],{"type":34,"value":125},{"type":29,"tag":88,"props":12994,"children":12995},{"class":90,"line":128},[12996],{"type":29,"tag":88,"props":12997,"children":12998},{"emptyLinePlaceholder":13},[12999],{"type":34,"value":134},{"type":29,"tag":88,"props":13001,"children":13002},{"class":90,"line":137},[13003,13007,13011,13015,13019,13023,13027,13031,13035,13040,13044,13048,13052],{"type":29,"tag":88,"props":13004,"children":13005},{"style":105},[13006],{"type":34,"value":143},{"type":29,"tag":88,"props":13008,"children":13009},{"style":105},[13010],{"type":34,"value":148},{"type":29,"tag":88,"props":13012,"children":13013},{"style":151},[13014],{"type":34,"value":1384},{"type":29,"tag":88,"props":13016,"children":13017},{"style":122},[13018],{"type":34,"value":1683},{"type":29,"tag":88,"props":13020,"children":13021},{"style":105},[13022],{"type":34,"value":695},{"type":29,"tag":88,"props":13024,"children":13025},{"style":122},[13026],{"type":34,"value":192},{"type":29,"tag":88,"props":13028,"children":13029},{"style":105},[13030],{"type":34,"value":10966},{"type":29,"tag":88,"props":13032,"children":13033},{"style":122},[13034],{"type":34,"value":1701},{"type":29,"tag":88,"props":13036,"children":13037},{"style":157},[13038],{"type":34,"value":13039}," database ",{"type":29,"tag":88,"props":13041,"children":13042},{"style":163},[13043],{"type":34,"value":166},{"type":29,"tag":88,"props":13045,"children":13046},{"style":105},[13047],{"type":34,"value":171},{"type":29,"tag":88,"props":13049,"children":13050},{"style":151},[13051],{"type":34,"value":1719},{"type":29,"tag":88,"props":13053,"children":13054},{"style":122},[13055],{"type":34,"value":1724},{"type":29,"tag":88,"props":13057,"children":13058},{"class":90,"line":211},[13059],{"type":29,"tag":88,"props":13060,"children":13061},{"emptyLinePlaceholder":13},[13062],{"type":34,"value":134},{"type":29,"tag":88,"props":13064,"children":13065},{"class":90,"line":262},[13066,13070],{"type":29,"tag":88,"props":13067,"children":13068},{"style":1974},[13069],{"type":34,"value":3302},{"type":29,"tag":88,"props":13071,"children":13072},{"style":1980},[13073],{"type":34,"value":3307},{"type":29,"tag":88,"props":13075,"children":13076},{"class":90,"line":270},[13077,13081,13085,13089,13093,13097,13101,13105],{"type":29,"tag":88,"props":13078,"children":13079},{"style":105},[13080],{"type":34,"value":276},{"type":29,"tag":88,"props":13082,"children":13083},{"style":151},[13084],{"type":34,"value":10966},{"type":29,"tag":88,"props":13086,"children":13087},{"style":174},[13088],{"type":34,"value":2395},{"type":29,"tag":88,"props":13090,"children":13091},{"style":122},[13092],{"type":34,"value":181},{"type":29,"tag":88,"props":13094,"children":13095},{"style":151},[13096],{"type":34,"value":695},{"type":29,"tag":88,"props":13098,"children":13099},{"style":298},[13100],{"type":34,"value":11904},{"type":29,"tag":88,"props":13102,"children":13103},{"style":122},[13104],{"type":34,"value":306},{"type":29,"tag":88,"props":13106,"children":13107},{"style":122},[13108],{"type":34,"value":125},{"type":29,"tag":88,"props":13110,"children":13111},{"class":90,"line":313},[13112,13116,13121,13125,13130,13134,13138,13142,13146,13150],{"type":29,"tag":88,"props":13113,"children":13114},{"style":105},[13115],{"type":34,"value":415},{"type":29,"tag":88,"props":13117,"children":13118},{"style":157},[13119],{"type":34,"value":13120}," database",{"type":29,"tag":88,"props":13122,"children":13123},{"style":122},[13124],{"type":34,"value":338},{"type":29,"tag":88,"props":13126,"children":13127},{"style":174},[13128],{"type":34,"value":13129},"getOrDefault",{"type":29,"tag":88,"props":13131,"children":13132},{"style":122},[13133],{"type":34,"value":181},{"type":29,"tag":88,"props":13135,"children":13136},{"style":157},[13137],{"type":34,"value":11950},{"type":29,"tag":88,"props":13139,"children":13140},{"style":122},[13141],{"type":34,"value":192},{"type":29,"tag":88,"props":13143,"children":13144},{"style":105},[13145],{"type":34,"value":171},{"type":29,"tag":88,"props":13147,"children":13148},{"style":174},[13149],{"type":34,"value":10966},{"type":29,"tag":88,"props":13151,"children":13152},{"style":122},[13153],{"type":34,"value":2958},{"type":29,"tag":88,"props":13155,"children":13156},{"class":90,"line":360},[13157],{"type":29,"tag":88,"props":13158,"children":13159},{"style":122},[13160],{"type":34,"value":433},{"type":29,"tag":88,"props":13162,"children":13163},{"class":90,"line":409},[13164],{"type":29,"tag":88,"props":13165,"children":13166},{"emptyLinePlaceholder":13},[13167],{"type":34,"value":134},{"type":29,"tag":88,"props":13169,"children":13170},{"class":90,"line":427},[13171,13175],{"type":29,"tag":88,"props":13172,"children":13173},{"style":1974},[13174],{"type":34,"value":3302},{"type":29,"tag":88,"props":13176,"children":13177},{"style":1980},[13178],{"type":34,"value":3307},{"type":29,"tag":88,"props":13180,"children":13181},{"class":90,"line":436},[13182,13186,13190,13194,13198,13202,13206,13210],{"type":29,"tag":88,"props":13183,"children":13184},{"style":105},[13185],{"type":34,"value":276},{"type":29,"tag":88,"props":13187,"children":13188},{"style":105},[13189],{"type":34,"value":1303},{"type":29,"tag":88,"props":13191,"children":13192},{"style":174},[13193],{"type":34,"value":623},{"type":29,"tag":88,"props":13195,"children":13196},{"style":122},[13197],{"type":34,"value":181},{"type":29,"tag":88,"props":13199,"children":13200},{"style":151},[13201],{"type":34,"value":11702},{"type":29,"tag":88,"props":13203,"children":13204},{"style":298},[13205],{"type":34,"value":12835},{"type":29,"tag":88,"props":13207,"children":13208},{"style":122},[13209],{"type":34,"value":306},{"type":29,"tag":88,"props":13211,"children":13212},{"style":122},[13213],{"type":34,"value":125},{"type":29,"tag":88,"props":13215,"children":13216},{"class":90,"line":767},[13217,13222,13226,13230,13234,13239,13243,13247],{"type":29,"tag":88,"props":13218,"children":13219},{"style":157},[13220],{"type":34,"value":13221},"        database",{"type":29,"tag":88,"props":13223,"children":13224},{"style":122},[13225],{"type":34,"value":338},{"type":29,"tag":88,"props":13227,"children":13228},{"style":174},[13229],{"type":34,"value":1827},{"type":29,"tag":88,"props":13231,"children":13232},{"style":122},[13233],{"type":34,"value":181},{"type":29,"tag":88,"props":13235,"children":13236},{"style":184},[13237],{"type":34,"value":13238},"\"cartId\"",{"type":29,"tag":88,"props":13240,"children":13241},{"style":122},[13242],{"type":34,"value":192},{"type":29,"tag":88,"props":13244,"children":13245},{"style":157},[13246],{"type":34,"value":12835},{"type":29,"tag":88,"props":13248,"children":13249},{"style":122},[13250],{"type":34,"value":357},{"type":29,"tag":88,"props":13252,"children":13253},{"class":90,"line":792},[13254],{"type":29,"tag":88,"props":13255,"children":13256},{"style":122},[13257],{"type":34,"value":433},{"type":29,"tag":88,"props":13259,"children":13260},{"class":90,"line":817},[13261],{"type":29,"tag":88,"props":13262,"children":13263},{"style":122},[13264],{"type":34,"value":442},{"type":29,"tag":7066,"props":13266,"children":13267},{},[13268,13276],{"type":29,"tag":30,"props":13269,"children":13270},{},[13271],{"type":29,"tag":447,"props":13272,"children":13273},{},[13274],{"type":34,"value":13275},"Tip : Utiliser des Adapters pour faciliter les tests",{"type":29,"tag":30,"props":13277,"children":13278},{},[13279,13281,13286,13288,13293],{"type":34,"value":13280},"Une des forces de l'architecture hexagonale est de permettre un ",{"type":29,"tag":447,"props":13282,"children":13283},{},[13284],{"type":34,"value":13285},"découplage fort",{"type":34,"value":13287}," entre la logique métier et les aspects techniques. En implémentant des ",{"type":29,"tag":447,"props":13289,"children":13290},{},[13291],{"type":34,"value":13292},"adapters",{"type":34,"value":13294}," dans la couche infrastructure, vous pouvez facilement substituer des dépendances pour les tests.",{"type":29,"tag":47,"props":13296,"children":13297},{},[],{"type":29,"tag":51,"props":13299,"children":13301},{"id":13300},"exemples-en-java-de-la-théorie-à-la-pratique",[13302],{"type":29,"tag":447,"props":13303,"children":13304},{},[13305],{"type":34,"value":13306},"Exemples en Java : De la théorie à la pratique",{"type":29,"tag":30,"props":13308,"children":13309},{},[13310,13312,13317],{"type":34,"value":13311},"Nous allons créer un microservice qui gère un ",{"type":29,"tag":447,"props":13313,"children":13314},{},[13315],{"type":34,"value":13316},"Panier d’achat",{"type":34,"value":13318}," dans une application de gestion de commandes. Ce service illustrera comment utiliser les trois concepts (DDD, API First et architecture hexagonale) pour structurer un service solide, maintenable et facilement testable. C’est un pattern que j’ai appliqué dans plusieurs missions de refactorisation d’applications métier, notamment dans le secteur financier : la clarté des couches se traduit directement par une réduction du lead time de correction des bugs.",{"type":29,"tag":6010,"props":13320,"children":13322},{"id":13321},"étape-1-définir-le-domaine-métier-avec-ddd",[13323],{"type":29,"tag":447,"props":13324,"children":13325},{},[13326],{"type":34,"value":13327},"Étape 1 : Définir le domaine métier avec DDD",{"type":29,"tag":30,"props":13329,"children":13330},{},[13331,13333,13337],{"type":34,"value":13332},"Notre service ",{"type":29,"tag":447,"props":13334,"children":13335},{},[13336],{"type":34,"value":11480},{"type":34,"value":13338}," (Cart) doit gérer les actions principales suivantes :",{"type":29,"tag":453,"props":13340,"children":13341},{},[13342,13347,13352],{"type":29,"tag":457,"props":13343,"children":13344},{},[13345],{"type":34,"value":13346},"Ajouter un article au panier",{"type":29,"tag":457,"props":13348,"children":13349},{},[13350],{"type":34,"value":13351},"Supprimer un article",{"type":29,"tag":457,"props":13353,"children":13354},{},[13355],{"type":34,"value":13356},"Calculer le total des articles dans le panier",{"type":29,"tag":30,"props":13358,"children":13359},{},[13360,13362,13366],{"type":34,"value":13361},"Commençons par définir la logique métier de base dans la couche ",{"type":29,"tag":447,"props":13363,"children":13364},{},[13365],{"type":34,"value":12189},{"type":34,"value":338},{"type":29,"tag":77,"props":13368,"children":13370},{"code":13369,"language":80,"meta":8,"className":81,"style":8},"public class Cart {\n    private final List\u003CItem> items = new ArrayList\u003C>();\n\n    public void addItem(Item item) {\n        items.add(item);\n    }\n\n    public void removeItem(Item item) {\n        items.remove(item);\n    }\n\n    public double calculateTotal() {\n        return items.stream()\n            .mapToDouble(Item::getPrice)\n            .sum();\n    }\n\n    public List\u003CItem> getItems() {\n        return new ArrayList\u003C>(items); \u002F\u002F retour d'une copie pour éviter les modifications extérieures\n    }\n}\n",[13371],{"type":29,"tag":84,"props":13372,"children":13373},{"__ignoreMap":8},[13374,13393,13440,13447,13482,13509,13516,13523,13558,13585,13592,13599,13622,13645,13676,13691,13698,13705,13740,13774,13781],{"type":29,"tag":88,"props":13375,"children":13376},{"class":90,"line":91},[13377,13381,13385,13389],{"type":29,"tag":88,"props":13378,"children":13379},{"style":105},[13380],{"type":34,"value":108},{"type":29,"tag":88,"props":13382,"children":13383},{"style":105},[13384],{"type":34,"value":113},{"type":29,"tag":88,"props":13386,"children":13387},{"style":116},[13388],{"type":34,"value":10966},{"type":29,"tag":88,"props":13390,"children":13391},{"style":122},[13392],{"type":34,"value":125},{"type":29,"tag":88,"props":13394,"children":13395},{"class":90,"line":101},[13396,13400,13404,13408,13412,13416,13420,13424,13428,13432,13436],{"type":29,"tag":88,"props":13397,"children":13398},{"style":105},[13399],{"type":34,"value":143},{"type":29,"tag":88,"props":13401,"children":13402},{"style":105},[13403],{"type":34,"value":148},{"type":29,"tag":88,"props":13405,"children":13406},{"style":151},[13407],{"type":34,"value":5355},{"type":29,"tag":88,"props":13409,"children":13410},{"style":122},[13411],{"type":34,"value":1683},{"type":29,"tag":88,"props":13413,"children":13414},{"style":105},[13415],{"type":34,"value":10990},{"type":29,"tag":88,"props":13417,"children":13418},{"style":122},[13419],{"type":34,"value":1701},{"type":29,"tag":88,"props":13421,"children":13422},{"style":157},[13423],{"type":34,"value":12297},{"type":29,"tag":88,"props":13425,"children":13426},{"style":163},[13427],{"type":34,"value":166},{"type":29,"tag":88,"props":13429,"children":13430},{"style":105},[13431],{"type":34,"value":171},{"type":29,"tag":88,"props":13433,"children":13434},{"style":151},[13435],{"type":34,"value":5385},{"type":29,"tag":88,"props":13437,"children":13438},{"style":122},[13439],{"type":34,"value":1724},{"type":29,"tag":88,"props":13441,"children":13442},{"class":90,"line":128},[13443],{"type":29,"tag":88,"props":13444,"children":13445},{"emptyLinePlaceholder":13},[13446],{"type":34,"value":134},{"type":29,"tag":88,"props":13448,"children":13449},{"class":90,"line":137},[13450,13454,13458,13462,13466,13470,13474,13478],{"type":29,"tag":88,"props":13451,"children":13452},{"style":105},[13453],{"type":34,"value":276},{"type":29,"tag":88,"props":13455,"children":13456},{"style":105},[13457],{"type":34,"value":1303},{"type":29,"tag":88,"props":13459,"children":13460},{"style":174},[13461],{"type":34,"value":11025},{"type":29,"tag":88,"props":13463,"children":13464},{"style":122},[13465],{"type":34,"value":181},{"type":29,"tag":88,"props":13467,"children":13468},{"style":151},[13469],{"type":34,"value":10990},{"type":29,"tag":88,"props":13471,"children":13472},{"style":298},[13473],{"type":34,"value":11038},{"type":29,"tag":88,"props":13475,"children":13476},{"style":122},[13477],{"type":34,"value":306},{"type":29,"tag":88,"props":13479,"children":13480},{"style":122},[13481],{"type":34,"value":125},{"type":29,"tag":88,"props":13483,"children":13484},{"class":90,"line":211},[13485,13489,13493,13497,13501,13505],{"type":29,"tag":88,"props":13486,"children":13487},{"style":157},[13488],{"type":34,"value":11054},{"type":29,"tag":88,"props":13490,"children":13491},{"style":122},[13492],{"type":34,"value":338},{"type":29,"tag":88,"props":13494,"children":13495},{"style":174},[13496],{"type":34,"value":5471},{"type":29,"tag":88,"props":13498,"children":13499},{"style":122},[13500],{"type":34,"value":181},{"type":29,"tag":88,"props":13502,"children":13503},{"style":157},[13504],{"type":34,"value":11071},{"type":29,"tag":88,"props":13506,"children":13507},{"style":122},[13508],{"type":34,"value":357},{"type":29,"tag":88,"props":13510,"children":13511},{"class":90,"line":262},[13512],{"type":29,"tag":88,"props":13513,"children":13514},{"style":122},[13515],{"type":34,"value":433},{"type":29,"tag":88,"props":13517,"children":13518},{"class":90,"line":270},[13519],{"type":29,"tag":88,"props":13520,"children":13521},{"emptyLinePlaceholder":13},[13522],{"type":34,"value":134},{"type":29,"tag":88,"props":13524,"children":13525},{"class":90,"line":313},[13526,13530,13534,13538,13542,13546,13550,13554],{"type":29,"tag":88,"props":13527,"children":13528},{"style":105},[13529],{"type":34,"value":276},{"type":29,"tag":88,"props":13531,"children":13532},{"style":105},[13533],{"type":34,"value":1303},{"type":29,"tag":88,"props":13535,"children":13536},{"style":174},[13537],{"type":34,"value":11105},{"type":29,"tag":88,"props":13539,"children":13540},{"style":122},[13541],{"type":34,"value":181},{"type":29,"tag":88,"props":13543,"children":13544},{"style":151},[13545],{"type":34,"value":10990},{"type":29,"tag":88,"props":13547,"children":13548},{"style":298},[13549],{"type":34,"value":11038},{"type":29,"tag":88,"props":13551,"children":13552},{"style":122},[13553],{"type":34,"value":306},{"type":29,"tag":88,"props":13555,"children":13556},{"style":122},[13557],{"type":34,"value":125},{"type":29,"tag":88,"props":13559,"children":13560},{"class":90,"line":360},[13561,13565,13569,13573,13577,13581],{"type":29,"tag":88,"props":13562,"children":13563},{"style":157},[13564],{"type":34,"value":11054},{"type":29,"tag":88,"props":13566,"children":13567},{"style":122},[13568],{"type":34,"value":338},{"type":29,"tag":88,"props":13570,"children":13571},{"style":174},[13572],{"type":34,"value":11141},{"type":29,"tag":88,"props":13574,"children":13575},{"style":122},[13576],{"type":34,"value":181},{"type":29,"tag":88,"props":13578,"children":13579},{"style":157},[13580],{"type":34,"value":11071},{"type":29,"tag":88,"props":13582,"children":13583},{"style":122},[13584],{"type":34,"value":357},{"type":29,"tag":88,"props":13586,"children":13587},{"class":90,"line":409},[13588],{"type":29,"tag":88,"props":13589,"children":13590},{"style":122},[13591],{"type":34,"value":433},{"type":29,"tag":88,"props":13593,"children":13594},{"class":90,"line":427},[13595],{"type":29,"tag":88,"props":13596,"children":13597},{"emptyLinePlaceholder":13},[13598],{"type":34,"value":134},{"type":29,"tag":88,"props":13600,"children":13601},{"class":90,"line":436},[13602,13606,13610,13614,13618],{"type":29,"tag":88,"props":13603,"children":13604},{"style":105},[13605],{"type":34,"value":276},{"type":29,"tag":88,"props":13607,"children":13608},{"style":105},[13609],{"type":34,"value":11179},{"type":29,"tag":88,"props":13611,"children":13612},{"style":174},[13613],{"type":34,"value":11184},{"type":29,"tag":88,"props":13615,"children":13616},{"style":122},[13617],{"type":34,"value":1470},{"type":29,"tag":88,"props":13619,"children":13620},{"style":122},[13621],{"type":34,"value":125},{"type":29,"tag":88,"props":13623,"children":13624},{"class":90,"line":767},[13625,13629,13633,13637,13641],{"type":29,"tag":88,"props":13626,"children":13627},{"style":105},[13628],{"type":34,"value":415},{"type":29,"tag":88,"props":13630,"children":13631},{"style":157},[13632],{"type":34,"value":2173},{"type":29,"tag":88,"props":13634,"children":13635},{"style":122},[13636],{"type":34,"value":338},{"type":29,"tag":88,"props":13638,"children":13639},{"style":174},[13640],{"type":34,"value":11212},{"type":29,"tag":88,"props":13642,"children":13643},{"style":122},[13644],{"type":34,"value":2863},{"type":29,"tag":88,"props":13646,"children":13647},{"class":90,"line":792},[13648,13652,13656,13660,13664,13668,13672],{"type":29,"tag":88,"props":13649,"children":13650},{"style":122},[13651],{"type":34,"value":3132},{"type":29,"tag":88,"props":13653,"children":13654},{"style":174},[13655],{"type":34,"value":11228},{"type":29,"tag":88,"props":13657,"children":13658},{"style":122},[13659],{"type":34,"value":181},{"type":29,"tag":88,"props":13661,"children":13662},{"style":157},[13663],{"type":34,"value":10990},{"type":29,"tag":88,"props":13665,"children":13666},{"style":105},[13667],{"type":34,"value":11241},{"type":29,"tag":88,"props":13669,"children":13670},{"style":157},[13671],{"type":34,"value":11246},{"type":29,"tag":88,"props":13673,"children":13674},{"style":122},[13675],{"type":34,"value":3078},{"type":29,"tag":88,"props":13677,"children":13678},{"class":90,"line":817},[13679,13683,13687],{"type":29,"tag":88,"props":13680,"children":13681},{"style":122},[13682],{"type":34,"value":3132},{"type":29,"tag":88,"props":13684,"children":13685},{"style":174},[13686],{"type":34,"value":11262},{"type":29,"tag":88,"props":13688,"children":13689},{"style":122},[13690],{"type":34,"value":1810},{"type":29,"tag":88,"props":13692,"children":13693},{"class":90,"line":825},[13694],{"type":29,"tag":88,"props":13695,"children":13696},{"style":122},[13697],{"type":34,"value":433},{"type":29,"tag":88,"props":13699,"children":13700},{"class":90,"line":869},[13701],{"type":29,"tag":88,"props":13702,"children":13703},{"emptyLinePlaceholder":13},[13704],{"type":34,"value":134},{"type":29,"tag":88,"props":13706,"children":13707},{"class":90,"line":900},[13708,13712,13716,13720,13724,13728,13732,13736],{"type":29,"tag":88,"props":13709,"children":13710},{"style":105},[13711],{"type":34,"value":276},{"type":29,"tag":88,"props":13713,"children":13714},{"style":151},[13715],{"type":34,"value":5355},{"type":29,"tag":88,"props":13717,"children":13718},{"style":122},[13719],{"type":34,"value":1683},{"type":29,"tag":88,"props":13721,"children":13722},{"style":105},[13723],{"type":34,"value":10990},{"type":29,"tag":88,"props":13725,"children":13726},{"style":122},[13727],{"type":34,"value":1701},{"type":29,"tag":88,"props":13729,"children":13730},{"style":174},[13731],{"type":34,"value":12500},{"type":29,"tag":88,"props":13733,"children":13734},{"style":122},[13735],{"type":34,"value":1470},{"type":29,"tag":88,"props":13737,"children":13738},{"style":122},[13739],{"type":34,"value":125},{"type":29,"tag":88,"props":13741,"children":13742},{"class":90,"line":929},[13743,13747,13751,13755,13760,13765,13769],{"type":29,"tag":88,"props":13744,"children":13745},{"style":105},[13746],{"type":34,"value":415},{"type":29,"tag":88,"props":13748,"children":13749},{"style":105},[13750],{"type":34,"value":171},{"type":29,"tag":88,"props":13752,"children":13753},{"style":151},[13754],{"type":34,"value":5385},{"type":29,"tag":88,"props":13756,"children":13757},{"style":122},[13758],{"type":34,"value":13759},"\u003C>(",{"type":29,"tag":88,"props":13761,"children":13762},{"style":157},[13763],{"type":34,"value":13764},"items",{"type":29,"tag":88,"props":13766,"children":13767},{"style":122},[13768],{"type":34,"value":203},{"type":29,"tag":88,"props":13770,"children":13771},{"style":95},[13772],{"type":34,"value":13773}," \u002F\u002F retour d'une copie pour éviter les modifications extérieures\n",{"type":29,"tag":88,"props":13775,"children":13776},{"class":90,"line":937},[13777],{"type":29,"tag":88,"props":13778,"children":13779},{"style":122},[13780],{"type":34,"value":433},{"type":29,"tag":88,"props":13782,"children":13783},{"class":90,"line":945},[13784],{"type":29,"tag":88,"props":13785,"children":13786},{"style":122},[13787],{"type":34,"value":442},{"type":29,"tag":6010,"props":13789,"children":13791},{"id":13790},"étape-2-orchestrer-les-cas-dutilisation-dans-la-couche-application",[13792],{"type":29,"tag":447,"props":13793,"children":13794},{},[13795],{"type":34,"value":13796},"Étape 2 : Orchestrer les cas d’utilisation dans la couche Application",{"type":29,"tag":30,"props":13798,"children":13799},{},[13800,13802,13806],{"type":34,"value":13801},"La couche ",{"type":29,"tag":447,"props":13803,"children":13804},{},[13805],{"type":34,"value":12199},{"type":34,"value":13807}," orchestre ensuite les interactions avec ce domaine.",{"type":29,"tag":77,"props":13809,"children":13811},{"code":13810,"language":80,"meta":8,"className":81,"style":8},"public class CartService {\n    private final CartRepository cartRepository;\n\n    public CartService(CartRepository cartRepository) {\n        this.cartRepository = cartRepository;\n    }\n\n    public Cart addItemToCart(String cartId, Item item) {\n        Cart cart = cartRepository.findById(cartId)\n                .orElse(new Cart());\n        cart.addItem(item);\n        cartRepository.save(cart);\n        return cart;\n    }\n\n    public Cart removeItemFromCart(String cartId, Item item) {\n        Cart cart = cartRepository.findById(cartId)\n                .orElseThrow(() -> new IllegalArgumentException(\"Panier introuvable\"));\n        cart.removeItem(item);\n        cartRepository.save(cart);\n        return cart;\n    }\n\n    public double getCartTotal(String cartId) {\n        Cart cart = cartRepository.findById(cartId)\n                .orElseThrow(() -> new IllegalArgumentException(\"Panier introuvable\"));\n        return cart.calculateTotal();\n    }\n\n    public Cart getCart(String cartId) {\n        return cartRepository.findById(cartId)\n                .orElseThrow(() -> new IllegalArgumentException(\"Panier introuvable\"));\n    }\n}\n",[13812],{"type":29,"tag":84,"props":13813,"children":13814},{"__ignoreMap":8},[13815,13834,13857,13864,13895,13922,13929,13936,13983,14022,14051,14078,14105,14120,14127,14134,14182,14221,14262,14290,14317,14332,14339,14346,14382,14421,14460,14484,14491,14498,14533,14564,14603,14610],{"type":29,"tag":88,"props":13816,"children":13817},{"class":90,"line":91},[13818,13822,13826,13830],{"type":29,"tag":88,"props":13819,"children":13820},{"style":105},[13821],{"type":34,"value":108},{"type":29,"tag":88,"props":13823,"children":13824},{"style":105},[13825],{"type":34,"value":113},{"type":29,"tag":88,"props":13827,"children":13828},{"style":116},[13829],{"type":34,"value":11567},{"type":29,"tag":88,"props":13831,"children":13832},{"style":122},[13833],{"type":34,"value":125},{"type":29,"tag":88,"props":13835,"children":13836},{"class":90,"line":101},[13837,13841,13845,13849,13853],{"type":29,"tag":88,"props":13838,"children":13839},{"style":105},[13840],{"type":34,"value":143},{"type":29,"tag":88,"props":13842,"children":13843},{"style":105},[13844],{"type":34,"value":148},{"type":29,"tag":88,"props":13846,"children":13847},{"style":151},[13848],{"type":34,"value":12591},{"type":29,"tag":88,"props":13850,"children":13851},{"style":157},[13852],{"type":34,"value":12596},{"type":29,"tag":88,"props":13854,"children":13855},{"style":122},[13856],{"type":34,"value":424},{"type":29,"tag":88,"props":13858,"children":13859},{"class":90,"line":128},[13860],{"type":29,"tag":88,"props":13861,"children":13862},{"emptyLinePlaceholder":13},[13863],{"type":34,"value":134},{"type":29,"tag":88,"props":13865,"children":13866},{"class":90,"line":137},[13867,13871,13875,13879,13883,13887,13891],{"type":29,"tag":88,"props":13868,"children":13869},{"style":105},[13870],{"type":34,"value":276},{"type":29,"tag":88,"props":13872,"children":13873},{"style":174},[13874],{"type":34,"value":11567},{"type":29,"tag":88,"props":13876,"children":13877},{"style":122},[13878],{"type":34,"value":181},{"type":29,"tag":88,"props":13880,"children":13881},{"style":151},[13882],{"type":34,"value":12627},{"type":29,"tag":88,"props":13884,"children":13885},{"style":298},[13886],{"type":34,"value":12596},{"type":29,"tag":88,"props":13888,"children":13889},{"style":122},[13890],{"type":34,"value":306},{"type":29,"tag":88,"props":13892,"children":13893},{"style":122},[13894],{"type":34,"value":125},{"type":29,"tag":88,"props":13896,"children":13897},{"class":90,"line":211},[13898,13902,13906,13910,13914,13918],{"type":29,"tag":88,"props":13899,"children":13900},{"style":873},[13901],{"type":34,"value":876},{"type":29,"tag":88,"props":13903,"children":13904},{"style":122},[13905],{"type":34,"value":338},{"type":29,"tag":88,"props":13907,"children":13908},{"style":157},[13909],{"type":34,"value":12655},{"type":29,"tag":88,"props":13911,"children":13912},{"style":163},[13913],{"type":34,"value":166},{"type":29,"tag":88,"props":13915,"children":13916},{"style":157},[13917],{"type":34,"value":12596},{"type":29,"tag":88,"props":13919,"children":13920},{"style":122},[13921],{"type":34,"value":424},{"type":29,"tag":88,"props":13923,"children":13924},{"class":90,"line":262},[13925],{"type":29,"tag":88,"props":13926,"children":13927},{"style":122},[13928],{"type":34,"value":433},{"type":29,"tag":88,"props":13930,"children":13931},{"class":90,"line":270},[13932],{"type":29,"tag":88,"props":13933,"children":13934},{"emptyLinePlaceholder":13},[13935],{"type":34,"value":134},{"type":29,"tag":88,"props":13937,"children":13938},{"class":90,"line":313},[13939,13943,13947,13951,13955,13959,13963,13967,13971,13975,13979],{"type":29,"tag":88,"props":13940,"children":13941},{"style":105},[13942],{"type":34,"value":276},{"type":29,"tag":88,"props":13944,"children":13945},{"style":151},[13946],{"type":34,"value":10966},{"type":29,"tag":88,"props":13948,"children":13949},{"style":174},[13950],{"type":34,"value":11711},{"type":29,"tag":88,"props":13952,"children":13953},{"style":122},[13954],{"type":34,"value":181},{"type":29,"tag":88,"props":13956,"children":13957},{"style":151},[13958],{"type":34,"value":695},{"type":29,"tag":88,"props":13960,"children":13961},{"style":298},[13962],{"type":34,"value":11904},{"type":29,"tag":88,"props":13964,"children":13965},{"style":122},[13966],{"type":34,"value":192},{"type":29,"tag":88,"props":13968,"children":13969},{"style":151},[13970],{"type":34,"value":11728},{"type":29,"tag":88,"props":13972,"children":13973},{"style":298},[13974],{"type":34,"value":11038},{"type":29,"tag":88,"props":13976,"children":13977},{"style":122},[13978],{"type":34,"value":306},{"type":29,"tag":88,"props":13980,"children":13981},{"style":122},[13982],{"type":34,"value":125},{"type":29,"tag":88,"props":13984,"children":13985},{"class":90,"line":360},[13986,13990,13994,13998,14002,14006,14010,14014,14018],{"type":29,"tag":88,"props":13987,"children":13988},{"style":151},[13989],{"type":34,"value":11748},{"type":29,"tag":88,"props":13991,"children":13992},{"style":157},[13993],{"type":34,"value":11924},{"type":29,"tag":88,"props":13995,"children":13996},{"style":163},[13997],{"type":34,"value":166},{"type":29,"tag":88,"props":13999,"children":14000},{"style":157},[14001],{"type":34,"value":12596},{"type":29,"tag":88,"props":14003,"children":14004},{"style":122},[14005],{"type":34,"value":338},{"type":29,"tag":88,"props":14007,"children":14008},{"style":174},[14009],{"type":34,"value":3112},{"type":29,"tag":88,"props":14011,"children":14012},{"style":122},[14013],{"type":34,"value":181},{"type":29,"tag":88,"props":14015,"children":14016},{"style":157},[14017],{"type":34,"value":11950},{"type":29,"tag":88,"props":14019,"children":14020},{"style":122},[14021],{"type":34,"value":3078},{"type":29,"tag":88,"props":14023,"children":14024},{"class":90,"line":409},[14025,14030,14035,14039,14043,14047],{"type":29,"tag":88,"props":14026,"children":14027},{"style":122},[14028],{"type":34,"value":14029},"                .",{"type":29,"tag":88,"props":14031,"children":14032},{"style":174},[14033],{"type":34,"value":14034},"orElse",{"type":29,"tag":88,"props":14036,"children":14037},{"style":122},[14038],{"type":34,"value":181},{"type":29,"tag":88,"props":14040,"children":14041},{"style":105},[14042],{"type":34,"value":2151},{"type":29,"tag":88,"props":14044,"children":14045},{"style":174},[14046],{"type":34,"value":10966},{"type":29,"tag":88,"props":14048,"children":14049},{"style":122},[14050],{"type":34,"value":2958},{"type":29,"tag":88,"props":14052,"children":14053},{"class":90,"line":427},[14054,14058,14062,14066,14070,14074],{"type":29,"tag":88,"props":14055,"children":14056},{"style":157},[14057],{"type":34,"value":12775},{"type":29,"tag":88,"props":14059,"children":14060},{"style":122},[14061],{"type":34,"value":338},{"type":29,"tag":88,"props":14063,"children":14064},{"style":174},[14065],{"type":34,"value":11770},{"type":29,"tag":88,"props":14067,"children":14068},{"style":122},[14069],{"type":34,"value":181},{"type":29,"tag":88,"props":14071,"children":14072},{"style":157},[14073],{"type":34,"value":11071},{"type":29,"tag":88,"props":14075,"children":14076},{"style":122},[14077],{"type":34,"value":357},{"type":29,"tag":88,"props":14079,"children":14080},{"class":90,"line":436},[14081,14085,14089,14093,14097,14101],{"type":29,"tag":88,"props":14082,"children":14083},{"style":157},[14084],{"type":34,"value":12803},{"type":29,"tag":88,"props":14086,"children":14087},{"style":122},[14088],{"type":34,"value":338},{"type":29,"tag":88,"props":14090,"children":14091},{"style":174},[14092],{"type":34,"value":343},{"type":29,"tag":88,"props":14094,"children":14095},{"style":122},[14096],{"type":34,"value":181},{"type":29,"tag":88,"props":14098,"children":14099},{"style":157},[14100],{"type":34,"value":11982},{"type":29,"tag":88,"props":14102,"children":14103},{"style":122},[14104],{"type":34,"value":357},{"type":29,"tag":88,"props":14106,"children":14107},{"class":90,"line":767},[14108,14112,14116],{"type":29,"tag":88,"props":14109,"children":14110},{"style":105},[14111],{"type":34,"value":415},{"type":29,"tag":88,"props":14113,"children":14114},{"style":157},[14115],{"type":34,"value":12835},{"type":29,"tag":88,"props":14117,"children":14118},{"style":122},[14119],{"type":34,"value":424},{"type":29,"tag":88,"props":14121,"children":14122},{"class":90,"line":792},[14123],{"type":29,"tag":88,"props":14124,"children":14125},{"style":122},[14126],{"type":34,"value":433},{"type":29,"tag":88,"props":14128,"children":14129},{"class":90,"line":817},[14130],{"type":29,"tag":88,"props":14131,"children":14132},{"emptyLinePlaceholder":13},[14133],{"type":34,"value":134},{"type":29,"tag":88,"props":14135,"children":14136},{"class":90,"line":825},[14137,14141,14145,14150,14154,14158,14162,14166,14170,14174,14178],{"type":29,"tag":88,"props":14138,"children":14139},{"style":105},[14140],{"type":34,"value":276},{"type":29,"tag":88,"props":14142,"children":14143},{"style":151},[14144],{"type":34,"value":10966},{"type":29,"tag":88,"props":14146,"children":14147},{"style":174},[14148],{"type":34,"value":14149}," removeItemFromCart",{"type":29,"tag":88,"props":14151,"children":14152},{"style":122},[14153],{"type":34,"value":181},{"type":29,"tag":88,"props":14155,"children":14156},{"style":151},[14157],{"type":34,"value":695},{"type":29,"tag":88,"props":14159,"children":14160},{"style":298},[14161],{"type":34,"value":11904},{"type":29,"tag":88,"props":14163,"children":14164},{"style":122},[14165],{"type":34,"value":192},{"type":29,"tag":88,"props":14167,"children":14168},{"style":151},[14169],{"type":34,"value":11728},{"type":29,"tag":88,"props":14171,"children":14172},{"style":298},[14173],{"type":34,"value":11038},{"type":29,"tag":88,"props":14175,"children":14176},{"style":122},[14177],{"type":34,"value":306},{"type":29,"tag":88,"props":14179,"children":14180},{"style":122},[14181],{"type":34,"value":125},{"type":29,"tag":88,"props":14183,"children":14184},{"class":90,"line":869},[14185,14189,14193,14197,14201,14205,14209,14213,14217],{"type":29,"tag":88,"props":14186,"children":14187},{"style":151},[14188],{"type":34,"value":11748},{"type":29,"tag":88,"props":14190,"children":14191},{"style":157},[14192],{"type":34,"value":11924},{"type":29,"tag":88,"props":14194,"children":14195},{"style":163},[14196],{"type":34,"value":166},{"type":29,"tag":88,"props":14198,"children":14199},{"style":157},[14200],{"type":34,"value":12596},{"type":29,"tag":88,"props":14202,"children":14203},{"style":122},[14204],{"type":34,"value":338},{"type":29,"tag":88,"props":14206,"children":14207},{"style":174},[14208],{"type":34,"value":3112},{"type":29,"tag":88,"props":14210,"children":14211},{"style":122},[14212],{"type":34,"value":181},{"type":29,"tag":88,"props":14214,"children":14215},{"style":157},[14216],{"type":34,"value":11950},{"type":29,"tag":88,"props":14218,"children":14219},{"style":122},[14220],{"type":34,"value":3078},{"type":29,"tag":88,"props":14222,"children":14223},{"class":90,"line":900},[14224,14228,14232,14236,14240,14244,14249,14253,14258],{"type":29,"tag":88,"props":14225,"children":14226},{"style":122},[14227],{"type":34,"value":14029},{"type":29,"tag":88,"props":14229,"children":14230},{"style":174},[14231],{"type":34,"value":3137},{"type":29,"tag":88,"props":14233,"children":14234},{"style":122},[14235],{"type":34,"value":3142},{"type":29,"tag":88,"props":14237,"children":14238},{"style":105},[14239],{"type":34,"value":3147},{"type":29,"tag":88,"props":14241,"children":14242},{"style":105},[14243],{"type":34,"value":171},{"type":29,"tag":88,"props":14245,"children":14246},{"style":174},[14247],{"type":34,"value":14248}," IllegalArgumentException",{"type":29,"tag":88,"props":14250,"children":14251},{"style":122},[14252],{"type":34,"value":181},{"type":29,"tag":88,"props":14254,"children":14255},{"style":184},[14256],{"type":34,"value":14257},"\"Panier introuvable\"",{"type":29,"tag":88,"props":14259,"children":14260},{"style":122},[14261],{"type":34,"value":1415},{"type":29,"tag":88,"props":14263,"children":14264},{"class":90,"line":929},[14265,14269,14273,14278,14282,14286],{"type":29,"tag":88,"props":14266,"children":14267},{"style":157},[14268],{"type":34,"value":12775},{"type":29,"tag":88,"props":14270,"children":14271},{"style":122},[14272],{"type":34,"value":338},{"type":29,"tag":88,"props":14274,"children":14275},{"style":174},[14276],{"type":34,"value":14277},"removeItem",{"type":29,"tag":88,"props":14279,"children":14280},{"style":122},[14281],{"type":34,"value":181},{"type":29,"tag":88,"props":14283,"children":14284},{"style":157},[14285],{"type":34,"value":11071},{"type":29,"tag":88,"props":14287,"children":14288},{"style":122},[14289],{"type":34,"value":357},{"type":29,"tag":88,"props":14291,"children":14292},{"class":90,"line":937},[14293,14297,14301,14305,14309,14313],{"type":29,"tag":88,"props":14294,"children":14295},{"style":157},[14296],{"type":34,"value":12803},{"type":29,"tag":88,"props":14298,"children":14299},{"style":122},[14300],{"type":34,"value":338},{"type":29,"tag":88,"props":14302,"children":14303},{"style":174},[14304],{"type":34,"value":343},{"type":29,"tag":88,"props":14306,"children":14307},{"style":122},[14308],{"type":34,"value":181},{"type":29,"tag":88,"props":14310,"children":14311},{"style":157},[14312],{"type":34,"value":11982},{"type":29,"tag":88,"props":14314,"children":14315},{"style":122},[14316],{"type":34,"value":357},{"type":29,"tag":88,"props":14318,"children":14319},{"class":90,"line":945},[14320,14324,14328],{"type":29,"tag":88,"props":14321,"children":14322},{"style":105},[14323],{"type":34,"value":415},{"type":29,"tag":88,"props":14325,"children":14326},{"style":157},[14327],{"type":34,"value":12835},{"type":29,"tag":88,"props":14329,"children":14330},{"style":122},[14331],{"type":34,"value":424},{"type":29,"tag":88,"props":14333,"children":14334},{"class":90,"line":981},[14335],{"type":29,"tag":88,"props":14336,"children":14337},{"style":122},[14338],{"type":34,"value":433},{"type":29,"tag":88,"props":14340,"children":14341},{"class":90,"line":1021},[14342],{"type":29,"tag":88,"props":14343,"children":14344},{"emptyLinePlaceholder":13},[14345],{"type":34,"value":134},{"type":29,"tag":88,"props":14347,"children":14348},{"class":90,"line":1066},[14349,14353,14357,14362,14366,14370,14374,14378],{"type":29,"tag":88,"props":14350,"children":14351},{"style":105},[14352],{"type":34,"value":276},{"type":29,"tag":88,"props":14354,"children":14355},{"style":105},[14356],{"type":34,"value":11179},{"type":29,"tag":88,"props":14358,"children":14359},{"style":174},[14360],{"type":34,"value":14361}," getCartTotal",{"type":29,"tag":88,"props":14363,"children":14364},{"style":122},[14365],{"type":34,"value":181},{"type":29,"tag":88,"props":14367,"children":14368},{"style":151},[14369],{"type":34,"value":695},{"type":29,"tag":88,"props":14371,"children":14372},{"style":298},[14373],{"type":34,"value":11904},{"type":29,"tag":88,"props":14375,"children":14376},{"style":122},[14377],{"type":34,"value":306},{"type":29,"tag":88,"props":14379,"children":14380},{"style":122},[14381],{"type":34,"value":125},{"type":29,"tag":88,"props":14383,"children":14384},{"class":90,"line":1082},[14385,14389,14393,14397,14401,14405,14409,14413,14417],{"type":29,"tag":88,"props":14386,"children":14387},{"style":151},[14388],{"type":34,"value":11748},{"type":29,"tag":88,"props":14390,"children":14391},{"style":157},[14392],{"type":34,"value":11924},{"type":29,"tag":88,"props":14394,"children":14395},{"style":163},[14396],{"type":34,"value":166},{"type":29,"tag":88,"props":14398,"children":14399},{"style":157},[14400],{"type":34,"value":12596},{"type":29,"tag":88,"props":14402,"children":14403},{"style":122},[14404],{"type":34,"value":338},{"type":29,"tag":88,"props":14406,"children":14407},{"style":174},[14408],{"type":34,"value":3112},{"type":29,"tag":88,"props":14410,"children":14411},{"style":122},[14412],{"type":34,"value":181},{"type":29,"tag":88,"props":14414,"children":14415},{"style":157},[14416],{"type":34,"value":11950},{"type":29,"tag":88,"props":14418,"children":14419},{"style":122},[14420],{"type":34,"value":3078},{"type":29,"tag":88,"props":14422,"children":14423},{"class":90,"line":1090},[14424,14428,14432,14436,14440,14444,14448,14452,14456],{"type":29,"tag":88,"props":14425,"children":14426},{"style":122},[14427],{"type":34,"value":14029},{"type":29,"tag":88,"props":14429,"children":14430},{"style":174},[14431],{"type":34,"value":3137},{"type":29,"tag":88,"props":14433,"children":14434},{"style":122},[14435],{"type":34,"value":3142},{"type":29,"tag":88,"props":14437,"children":14438},{"style":105},[14439],{"type":34,"value":3147},{"type":29,"tag":88,"props":14441,"children":14442},{"style":105},[14443],{"type":34,"value":171},{"type":29,"tag":88,"props":14445,"children":14446},{"style":174},[14447],{"type":34,"value":14248},{"type":29,"tag":88,"props":14449,"children":14450},{"style":122},[14451],{"type":34,"value":181},{"type":29,"tag":88,"props":14453,"children":14454},{"style":184},[14455],{"type":34,"value":14257},{"type":29,"tag":88,"props":14457,"children":14458},{"style":122},[14459],{"type":34,"value":1415},{"type":29,"tag":88,"props":14461,"children":14462},{"class":90,"line":1098},[14463,14467,14471,14475,14480],{"type":29,"tag":88,"props":14464,"children":14465},{"style":105},[14466],{"type":34,"value":415},{"type":29,"tag":88,"props":14468,"children":14469},{"style":157},[14470],{"type":34,"value":12835},{"type":29,"tag":88,"props":14472,"children":14473},{"style":122},[14474],{"type":34,"value":338},{"type":29,"tag":88,"props":14476,"children":14477},{"style":174},[14478],{"type":34,"value":14479},"calculateTotal",{"type":29,"tag":88,"props":14481,"children":14482},{"style":122},[14483],{"type":34,"value":1810},{"type":29,"tag":88,"props":14485,"children":14486},{"class":90,"line":1106},[14487],{"type":29,"tag":88,"props":14488,"children":14489},{"style":122},[14490],{"type":34,"value":433},{"type":29,"tag":88,"props":14492,"children":14493},{"class":90,"line":1115},[14494],{"type":29,"tag":88,"props":14495,"children":14496},{"emptyLinePlaceholder":13},[14497],{"type":34,"value":134},{"type":29,"tag":88,"props":14499,"children":14500},{"class":90,"line":11},[14501,14505,14509,14513,14517,14521,14525,14529],{"type":29,"tag":88,"props":14502,"children":14503},{"style":105},[14504],{"type":34,"value":276},{"type":29,"tag":88,"props":14506,"children":14507},{"style":151},[14508],{"type":34,"value":10966},{"type":29,"tag":88,"props":14510,"children":14511},{"style":174},[14512],{"type":34,"value":11882},{"type":29,"tag":88,"props":14514,"children":14515},{"style":122},[14516],{"type":34,"value":181},{"type":29,"tag":88,"props":14518,"children":14519},{"style":151},[14520],{"type":34,"value":695},{"type":29,"tag":88,"props":14522,"children":14523},{"style":298},[14524],{"type":34,"value":11904},{"type":29,"tag":88,"props":14526,"children":14527},{"style":122},[14528],{"type":34,"value":306},{"type":29,"tag":88,"props":14530,"children":14531},{"style":122},[14532],{"type":34,"value":125},{"type":29,"tag":88,"props":14534,"children":14535},{"class":90,"line":1180},[14536,14540,14544,14548,14552,14556,14560],{"type":29,"tag":88,"props":14537,"children":14538},{"style":105},[14539],{"type":34,"value":415},{"type":29,"tag":88,"props":14541,"children":14542},{"style":157},[14543],{"type":34,"value":12596},{"type":29,"tag":88,"props":14545,"children":14546},{"style":122},[14547],{"type":34,"value":338},{"type":29,"tag":88,"props":14549,"children":14550},{"style":174},[14551],{"type":34,"value":3112},{"type":29,"tag":88,"props":14553,"children":14554},{"style":122},[14555],{"type":34,"value":181},{"type":29,"tag":88,"props":14557,"children":14558},{"style":157},[14559],{"type":34,"value":11950},{"type":29,"tag":88,"props":14561,"children":14562},{"style":122},[14563],{"type":34,"value":3078},{"type":29,"tag":88,"props":14565,"children":14566},{"class":90,"line":1240},[14567,14571,14575,14579,14583,14587,14591,14595,14599],{"type":29,"tag":88,"props":14568,"children":14569},{"style":122},[14570],{"type":34,"value":14029},{"type":29,"tag":88,"props":14572,"children":14573},{"style":174},[14574],{"type":34,"value":3137},{"type":29,"tag":88,"props":14576,"children":14577},{"style":122},[14578],{"type":34,"value":3142},{"type":29,"tag":88,"props":14580,"children":14581},{"style":105},[14582],{"type":34,"value":3147},{"type":29,"tag":88,"props":14584,"children":14585},{"style":105},[14586],{"type":34,"value":171},{"type":29,"tag":88,"props":14588,"children":14589},{"style":174},[14590],{"type":34,"value":14248},{"type":29,"tag":88,"props":14592,"children":14593},{"style":122},[14594],{"type":34,"value":181},{"type":29,"tag":88,"props":14596,"children":14597},{"style":184},[14598],{"type":34,"value":14257},{"type":29,"tag":88,"props":14600,"children":14601},{"style":122},[14602],{"type":34,"value":1415},{"type":29,"tag":88,"props":14604,"children":14605},{"class":90,"line":1248},[14606],{"type":29,"tag":88,"props":14607,"children":14608},{"style":122},[14609],{"type":34,"value":433},{"type":29,"tag":88,"props":14611,"children":14612},{"class":90,"line":1256},[14613],{"type":29,"tag":88,"props":14614,"children":14615},{"style":122},[14616],{"type":34,"value":442},{"type":29,"tag":6010,"props":14618,"children":14620},{"id":14619},"étape-3-implémenter-la-couche-infrastructure",[14621],{"type":29,"tag":447,"props":14622,"children":14623},{},[14624],{"type":34,"value":14625},"Étape 3 : Implémenter la couche Infrastructure",{"type":29,"tag":77,"props":14627,"children":14629},{"code":14628,"language":80,"meta":8,"className":81,"style":8},"public interface CartRepository {\n    Optional\u003CCart> findById(String cartId);\n    void save(Cart cart);\n}\n\n@Repository\npublic class InMemoryCartRepository implements CartRepository {\n\n    private final Map\u003CString, Cart> database = new HashMap\u003C>();\n\n    @Override\n    public Optional\u003CCart> findById(String cartId) {\n        return Optional.ofNullable(database.get(cartId));\n    }\n\n    @Override\n    public void save(Cart cart) {\n        database.put(\"cartId\", cart);\n    }\n}\n",[14630],{"type":29,"tag":84,"props":14631,"children":14632},{"__ignoreMap":8},[14633,14652,14691,14718,14725,14732,14743,14771,14778,14833,14840,14851,14898,14946,14953,14960,14971,15006,15041,15048],{"type":29,"tag":88,"props":14634,"children":14635},{"class":90,"line":91},[14636,14640,14644,14648],{"type":29,"tag":88,"props":14637,"children":14638},{"style":105},[14639],{"type":34,"value":108},{"type":29,"tag":88,"props":14641,"children":14642},{"style":105},[14643],{"type":34,"value":601},{"type":29,"tag":88,"props":14645,"children":14646},{"style":116},[14647],{"type":34,"value":12591},{"type":29,"tag":88,"props":14649,"children":14650},{"style":122},[14651],{"type":34,"value":125},{"type":29,"tag":88,"props":14653,"children":14654},{"class":90,"line":101},[14655,14659,14663,14667,14671,14675,14679,14683,14687],{"type":29,"tag":88,"props":14656,"children":14657},{"style":151},[14658],{"type":34,"value":2377},{"type":29,"tag":88,"props":14660,"children":14661},{"style":122},[14662],{"type":34,"value":1683},{"type":29,"tag":88,"props":14664,"children":14665},{"style":105},[14666],{"type":34,"value":11702},{"type":29,"tag":88,"props":14668,"children":14669},{"style":122},[14670],{"type":34,"value":1701},{"type":29,"tag":88,"props":14672,"children":14673},{"style":174},[14674],{"type":34,"value":2395},{"type":29,"tag":88,"props":14676,"children":14677},{"style":122},[14678],{"type":34,"value":181},{"type":29,"tag":88,"props":14680,"children":14681},{"style":151},[14682],{"type":34,"value":695},{"type":29,"tag":88,"props":14684,"children":14685},{"style":298},[14686],{"type":34,"value":11904},{"type":29,"tag":88,"props":14688,"children":14689},{"style":122},[14690],{"type":34,"value":357},{"type":29,"tag":88,"props":14692,"children":14693},{"class":90,"line":128},[14694,14698,14702,14706,14710,14714],{"type":29,"tag":88,"props":14695,"children":14696},{"style":105},[14697],{"type":34,"value":681},{"type":29,"tag":88,"props":14699,"children":14700},{"style":174},[14701],{"type":34,"value":623},{"type":29,"tag":88,"props":14703,"children":14704},{"style":122},[14705],{"type":34,"value":181},{"type":29,"tag":88,"props":14707,"children":14708},{"style":151},[14709],{"type":34,"value":11702},{"type":29,"tag":88,"props":14711,"children":14712},{"style":298},[14713],{"type":34,"value":12835},{"type":29,"tag":88,"props":14715,"children":14716},{"style":122},[14717],{"type":34,"value":357},{"type":29,"tag":88,"props":14719,"children":14720},{"class":90,"line":137},[14721],{"type":29,"tag":88,"props":14722,"children":14723},{"style":122},[14724],{"type":34,"value":442},{"type":29,"tag":88,"props":14726,"children":14727},{"class":90,"line":211},[14728],{"type":29,"tag":88,"props":14729,"children":14730},{"emptyLinePlaceholder":13},[14731],{"type":34,"value":134},{"type":29,"tag":88,"props":14733,"children":14734},{"class":90,"line":262},[14735,14739],{"type":29,"tag":88,"props":14736,"children":14737},{"style":1974},[14738],{"type":34,"value":1977},{"type":29,"tag":88,"props":14740,"children":14741},{"style":1980},[14742],{"type":34,"value":12964},{"type":29,"tag":88,"props":14744,"children":14745},{"class":90,"line":270},[14746,14750,14754,14759,14763,14767],{"type":29,"tag":88,"props":14747,"children":14748},{"style":105},[14749],{"type":34,"value":108},{"type":29,"tag":88,"props":14751,"children":14752},{"style":105},[14753],{"type":34,"value":113},{"type":29,"tag":88,"props":14755,"children":14756},{"style":116},[14757],{"type":34,"value":14758}," InMemoryCartRepository",{"type":29,"tag":88,"props":14760,"children":14761},{"style":105},[14762],{"type":34,"value":1134},{"type":29,"tag":88,"props":14764,"children":14765},{"style":116},[14766],{"type":34,"value":12591},{"type":29,"tag":88,"props":14768,"children":14769},{"style":122},[14770],{"type":34,"value":125},{"type":29,"tag":88,"props":14772,"children":14773},{"class":90,"line":313},[14774],{"type":29,"tag":88,"props":14775,"children":14776},{"emptyLinePlaceholder":13},[14777],{"type":34,"value":134},{"type":29,"tag":88,"props":14779,"children":14780},{"class":90,"line":360},[14781,14785,14789,14793,14797,14801,14805,14809,14813,14817,14821,14825,14829],{"type":29,"tag":88,"props":14782,"children":14783},{"style":105},[14784],{"type":34,"value":143},{"type":29,"tag":88,"props":14786,"children":14787},{"style":105},[14788],{"type":34,"value":148},{"type":29,"tag":88,"props":14790,"children":14791},{"style":151},[14792],{"type":34,"value":1384},{"type":29,"tag":88,"props":14794,"children":14795},{"style":122},[14796],{"type":34,"value":1683},{"type":29,"tag":88,"props":14798,"children":14799},{"style":105},[14800],{"type":34,"value":695},{"type":29,"tag":88,"props":14802,"children":14803},{"style":122},[14804],{"type":34,"value":192},{"type":29,"tag":88,"props":14806,"children":14807},{"style":105},[14808],{"type":34,"value":10966},{"type":29,"tag":88,"props":14810,"children":14811},{"style":122},[14812],{"type":34,"value":1701},{"type":29,"tag":88,"props":14814,"children":14815},{"style":157},[14816],{"type":34,"value":13039},{"type":29,"tag":88,"props":14818,"children":14819},{"style":163},[14820],{"type":34,"value":166},{"type":29,"tag":88,"props":14822,"children":14823},{"style":105},[14824],{"type":34,"value":171},{"type":29,"tag":88,"props":14826,"children":14827},{"style":151},[14828],{"type":34,"value":1719},{"type":29,"tag":88,"props":14830,"children":14831},{"style":122},[14832],{"type":34,"value":1724},{"type":29,"tag":88,"props":14834,"children":14835},{"class":90,"line":409},[14836],{"type":29,"tag":88,"props":14837,"children":14838},{"emptyLinePlaceholder":13},[14839],{"type":34,"value":134},{"type":29,"tag":88,"props":14841,"children":14842},{"class":90,"line":427},[14843,14847],{"type":29,"tag":88,"props":14844,"children":14845},{"style":1974},[14846],{"type":34,"value":3302},{"type":29,"tag":88,"props":14848,"children":14849},{"style":1980},[14850],{"type":34,"value":3307},{"type":29,"tag":88,"props":14852,"children":14853},{"class":90,"line":436},[14854,14858,14862,14866,14870,14874,14878,14882,14886,14890,14894],{"type":29,"tag":88,"props":14855,"children":14856},{"style":105},[14857],{"type":34,"value":276},{"type":29,"tag":88,"props":14859,"children":14860},{"style":151},[14861],{"type":34,"value":3480},{"type":29,"tag":88,"props":14863,"children":14864},{"style":122},[14865],{"type":34,"value":1683},{"type":29,"tag":88,"props":14867,"children":14868},{"style":105},[14869],{"type":34,"value":11702},{"type":29,"tag":88,"props":14871,"children":14872},{"style":122},[14873],{"type":34,"value":1701},{"type":29,"tag":88,"props":14875,"children":14876},{"style":174},[14877],{"type":34,"value":2395},{"type":29,"tag":88,"props":14879,"children":14880},{"style":122},[14881],{"type":34,"value":181},{"type":29,"tag":88,"props":14883,"children":14884},{"style":151},[14885],{"type":34,"value":695},{"type":29,"tag":88,"props":14887,"children":14888},{"style":298},[14889],{"type":34,"value":11904},{"type":29,"tag":88,"props":14891,"children":14892},{"style":122},[14893],{"type":34,"value":306},{"type":29,"tag":88,"props":14895,"children":14896},{"style":122},[14897],{"type":34,"value":125},{"type":29,"tag":88,"props":14899,"children":14900},{"class":90,"line":767},[14901,14905,14909,14913,14917,14921,14926,14930,14934,14938,14942],{"type":29,"tag":88,"props":14902,"children":14903},{"style":105},[14904],{"type":34,"value":415},{"type":29,"tag":88,"props":14906,"children":14907},{"style":157},[14908],{"type":34,"value":3480},{"type":29,"tag":88,"props":14910,"children":14911},{"style":122},[14912],{"type":34,"value":338},{"type":29,"tag":88,"props":14914,"children":14915},{"style":174},[14916],{"type":34,"value":3537},{"type":29,"tag":88,"props":14918,"children":14919},{"style":122},[14920],{"type":34,"value":181},{"type":29,"tag":88,"props":14922,"children":14923},{"style":157},[14924],{"type":34,"value":14925},"database",{"type":29,"tag":88,"props":14927,"children":14928},{"style":122},[14929],{"type":34,"value":338},{"type":29,"tag":88,"props":14931,"children":14932},{"style":174},[14933],{"type":34,"value":3555},{"type":29,"tag":88,"props":14935,"children":14936},{"style":122},[14937],{"type":34,"value":181},{"type":29,"tag":88,"props":14939,"children":14940},{"style":157},[14941],{"type":34,"value":11950},{"type":29,"tag":88,"props":14943,"children":14944},{"style":122},[14945],{"type":34,"value":1415},{"type":29,"tag":88,"props":14947,"children":14948},{"class":90,"line":792},[14949],{"type":29,"tag":88,"props":14950,"children":14951},{"style":122},[14952],{"type":34,"value":433},{"type":29,"tag":88,"props":14954,"children":14955},{"class":90,"line":817},[14956],{"type":29,"tag":88,"props":14957,"children":14958},{"emptyLinePlaceholder":13},[14959],{"type":34,"value":134},{"type":29,"tag":88,"props":14961,"children":14962},{"class":90,"line":825},[14963,14967],{"type":29,"tag":88,"props":14964,"children":14965},{"style":1974},[14966],{"type":34,"value":3302},{"type":29,"tag":88,"props":14968,"children":14969},{"style":1980},[14970],{"type":34,"value":3307},{"type":29,"tag":88,"props":14972,"children":14973},{"class":90,"line":869},[14974,14978,14982,14986,14990,14994,14998,15002],{"type":29,"tag":88,"props":14975,"children":14976},{"style":105},[14977],{"type":34,"value":276},{"type":29,"tag":88,"props":14979,"children":14980},{"style":105},[14981],{"type":34,"value":1303},{"type":29,"tag":88,"props":14983,"children":14984},{"style":174},[14985],{"type":34,"value":623},{"type":29,"tag":88,"props":14987,"children":14988},{"style":122},[14989],{"type":34,"value":181},{"type":29,"tag":88,"props":14991,"children":14992},{"style":151},[14993],{"type":34,"value":11702},{"type":29,"tag":88,"props":14995,"children":14996},{"style":298},[14997],{"type":34,"value":12835},{"type":29,"tag":88,"props":14999,"children":15000},{"style":122},[15001],{"type":34,"value":306},{"type":29,"tag":88,"props":15003,"children":15004},{"style":122},[15005],{"type":34,"value":125},{"type":29,"tag":88,"props":15007,"children":15008},{"class":90,"line":900},[15009,15013,15017,15021,15025,15029,15033,15037],{"type":29,"tag":88,"props":15010,"children":15011},{"style":157},[15012],{"type":34,"value":13221},{"type":29,"tag":88,"props":15014,"children":15015},{"style":122},[15016],{"type":34,"value":338},{"type":29,"tag":88,"props":15018,"children":15019},{"style":174},[15020],{"type":34,"value":1827},{"type":29,"tag":88,"props":15022,"children":15023},{"style":122},[15024],{"type":34,"value":181},{"type":29,"tag":88,"props":15026,"children":15027},{"style":184},[15028],{"type":34,"value":13238},{"type":29,"tag":88,"props":15030,"children":15031},{"style":122},[15032],{"type":34,"value":192},{"type":29,"tag":88,"props":15034,"children":15035},{"style":157},[15036],{"type":34,"value":12835},{"type":29,"tag":88,"props":15038,"children":15039},{"style":122},[15040],{"type":34,"value":357},{"type":29,"tag":88,"props":15042,"children":15043},{"class":90,"line":929},[15044],{"type":29,"tag":88,"props":15045,"children":15046},{"style":122},[15047],{"type":34,"value":433},{"type":29,"tag":88,"props":15049,"children":15050},{"class":90,"line":937},[15051],{"type":29,"tag":88,"props":15052,"children":15053},{"style":122},[15054],{"type":34,"value":442},{"type":29,"tag":30,"props":15056,"children":15057},{},[15058,15060,15065],{"type":34,"value":15059},"Cet exemple stocke les paniers dans une simple ",{"type":29,"tag":447,"props":15061,"children":15062},{},[15063],{"type":34,"value":15064},"HashMap",{"type":34,"value":15066}," pour simuler une base de données en mémoire.",{"type":29,"tag":12165,"props":15068,"children":15070},{"id":15069},"étape-4-exposer-lapi-avec-spring-boot-et-lapproche-api-first",[15071],{"type":29,"tag":447,"props":15072,"children":15073},{},[15074],{"type":34,"value":15075},"Étape 4 : Exposer l’API avec Spring Boot et l’approche API First",{"type":29,"tag":77,"props":15077,"children":15079},{"code":15078,"language":80,"meta":8,"className":81,"style":8},"@RestController\n@RequestMapping(\"\u002Fapi\u002Fv1\u002Fcart\")\npublic class CartController {\n\n    private final CartService cartService;\n\n    public CartController(CartService cartService) {\n        this.cartService = cartService;\n    }\n\n    @PostMapping(\"\u002F{cartId}\u002Fadd\")\n    public ResponseEntity\u003CCart> addItem(@PathVariable String cartId, @RequestBody Item item) {\n        Cart updatedCart = cartService.addItemToCart(cartId, item);\n        return ResponseEntity.ok(updatedCart);\n    }\n\n    @DeleteMapping(\"\u002F{cartId}\u002Fremove\")\n    public ResponseEntity\u003CCart> removeItem(@PathVariable String cartId, @RequestBody Item item) {\n        Cart updatedCart = cartService.removeItemFromCart(cartId, item);\n        return ResponseEntity.ok(updatedCart);\n    }\n\n    @GetMapping(\"\u002F{cartId}\u002Ftotal\")\n    public ResponseEntity\u003CDouble> getCartTotal(@PathVariable String cartId) {\n        double total = cartService.getCartTotal(cartId);\n        return ResponseEntity.ok(total);\n    }\n\n    @GetMapping(\"\u002F{cartId}\")\n    public ResponseEntity\u003CCart> getCart(@PathVariable String cartId) {\n        Cart cart = cartService.getCart(cartId);\n        return ResponseEntity.ok(cart);\n    }\n}\n",[15080],{"type":29,"tag":84,"props":15081,"children":15082},{"__ignoreMap":8},[15083,15094,15118,15137,15144,15167,15174,15205,15232,15239,15246,15270,15346,15394,15425,15432,15439,15464,15539,15587,15618,15625,15632,15656,15712,15754,15786,15793,15800,15823,15878,15917,15948,15955],{"type":29,"tag":88,"props":15084,"children":15085},{"class":90,"line":91},[15086,15090],{"type":29,"tag":88,"props":15087,"children":15088},{"style":1974},[15089],{"type":34,"value":1977},{"type":29,"tag":88,"props":15091,"children":15092},{"style":1980},[15093],{"type":34,"value":9193},{"type":29,"tag":88,"props":15095,"children":15096},{"class":90,"line":101},[15097,15101,15105,15109,15114],{"type":29,"tag":88,"props":15098,"children":15099},{"style":1974},[15100],{"type":34,"value":1977},{"type":29,"tag":88,"props":15102,"children":15103},{"style":1980},[15104],{"type":34,"value":9205},{"type":29,"tag":88,"props":15106,"children":15107},{"style":122},[15108],{"type":34,"value":181},{"type":29,"tag":88,"props":15110,"children":15111},{"style":184},[15112],{"type":34,"value":15113},"\"\u002Fapi\u002Fv1\u002Fcart\"",{"type":29,"tag":88,"props":15115,"children":15116},{"style":122},[15117],{"type":34,"value":3078},{"type":29,"tag":88,"props":15119,"children":15120},{"class":90,"line":128},[15121,15125,15129,15133],{"type":29,"tag":88,"props":15122,"children":15123},{"style":105},[15124],{"type":34,"value":108},{"type":29,"tag":88,"props":15126,"children":15127},{"style":105},[15128],{"type":34,"value":113},{"type":29,"tag":88,"props":15130,"children":15131},{"style":116},[15132],{"type":34,"value":11540},{"type":29,"tag":88,"props":15134,"children":15135},{"style":122},[15136],{"type":34,"value":125},{"type":29,"tag":88,"props":15138,"children":15139},{"class":90,"line":137},[15140],{"type":29,"tag":88,"props":15141,"children":15142},{"emptyLinePlaceholder":13},[15143],{"type":34,"value":134},{"type":29,"tag":88,"props":15145,"children":15146},{"class":90,"line":211},[15147,15151,15155,15159,15163],{"type":29,"tag":88,"props":15148,"children":15149},{"style":105},[15150],{"type":34,"value":143},{"type":29,"tag":88,"props":15152,"children":15153},{"style":105},[15154],{"type":34,"value":148},{"type":29,"tag":88,"props":15156,"children":15157},{"style":151},[15158],{"type":34,"value":11567},{"type":29,"tag":88,"props":15160,"children":15161},{"style":157},[15162],{"type":34,"value":11572},{"type":29,"tag":88,"props":15164,"children":15165},{"style":122},[15166],{"type":34,"value":424},{"type":29,"tag":88,"props":15168,"children":15169},{"class":90,"line":262},[15170],{"type":29,"tag":88,"props":15171,"children":15172},{"emptyLinePlaceholder":13},[15173],{"type":34,"value":134},{"type":29,"tag":88,"props":15175,"children":15176},{"class":90,"line":270},[15177,15181,15185,15189,15193,15197,15201],{"type":29,"tag":88,"props":15178,"children":15179},{"style":105},[15180],{"type":34,"value":276},{"type":29,"tag":88,"props":15182,"children":15183},{"style":174},[15184],{"type":34,"value":11540},{"type":29,"tag":88,"props":15186,"children":15187},{"style":122},[15188],{"type":34,"value":181},{"type":29,"tag":88,"props":15190,"children":15191},{"style":151},[15192],{"type":34,"value":11603},{"type":29,"tag":88,"props":15194,"children":15195},{"style":298},[15196],{"type":34,"value":11572},{"type":29,"tag":88,"props":15198,"children":15199},{"style":122},[15200],{"type":34,"value":306},{"type":29,"tag":88,"props":15202,"children":15203},{"style":122},[15204],{"type":34,"value":125},{"type":29,"tag":88,"props":15206,"children":15207},{"class":90,"line":313},[15208,15212,15216,15220,15224,15228],{"type":29,"tag":88,"props":15209,"children":15210},{"style":873},[15211],{"type":34,"value":876},{"type":29,"tag":88,"props":15213,"children":15214},{"style":122},[15215],{"type":34,"value":338},{"type":29,"tag":88,"props":15217,"children":15218},{"style":157},[15219],{"type":34,"value":11631},{"type":29,"tag":88,"props":15221,"children":15222},{"style":163},[15223],{"type":34,"value":166},{"type":29,"tag":88,"props":15225,"children":15226},{"style":157},[15227],{"type":34,"value":11572},{"type":29,"tag":88,"props":15229,"children":15230},{"style":122},[15231],{"type":34,"value":424},{"type":29,"tag":88,"props":15233,"children":15234},{"class":90,"line":360},[15235],{"type":29,"tag":88,"props":15236,"children":15237},{"style":122},[15238],{"type":34,"value":433},{"type":29,"tag":88,"props":15240,"children":15241},{"class":90,"line":409},[15242],{"type":29,"tag":88,"props":15243,"children":15244},{"emptyLinePlaceholder":13},[15245],{"type":34,"value":134},{"type":29,"tag":88,"props":15247,"children":15248},{"class":90,"line":427},[15249,15253,15257,15261,15266],{"type":29,"tag":88,"props":15250,"children":15251},{"style":1974},[15252],{"type":34,"value":3302},{"type":29,"tag":88,"props":15254,"children":15255},{"style":1980},[15256],{"type":34,"value":11669},{"type":29,"tag":88,"props":15258,"children":15259},{"style":122},[15260],{"type":34,"value":181},{"type":29,"tag":88,"props":15262,"children":15263},{"style":184},[15264],{"type":34,"value":15265},"\"\u002F{cartId}\u002Fadd\"",{"type":29,"tag":88,"props":15267,"children":15268},{"style":122},[15269],{"type":34,"value":3078},{"type":29,"tag":88,"props":15271,"children":15272},{"class":90,"line":436},[15273,15277,15281,15285,15289,15293,15297,15301,15305,15309,15313,15317,15321,15326,15330,15334,15338,15342],{"type":29,"tag":88,"props":15274,"children":15275},{"style":105},[15276],{"type":34,"value":276},{"type":29,"tag":88,"props":15278,"children":15279},{"style":151},[15280],{"type":34,"value":9367},{"type":29,"tag":88,"props":15282,"children":15283},{"style":122},[15284],{"type":34,"value":1683},{"type":29,"tag":88,"props":15286,"children":15287},{"style":105},[15288],{"type":34,"value":11702},{"type":29,"tag":88,"props":15290,"children":15291},{"style":122},[15292],{"type":34,"value":1701},{"type":29,"tag":88,"props":15294,"children":15295},{"style":174},[15296],{"type":34,"value":11025},{"type":29,"tag":88,"props":15298,"children":15299},{"style":122},[15300],{"type":34,"value":181},{"type":29,"tag":88,"props":15302,"children":15303},{"style":1974},[15304],{"type":34,"value":1977},{"type":29,"tag":88,"props":15306,"children":15307},{"style":1980},[15308],{"type":34,"value":11895},{"type":29,"tag":88,"props":15310,"children":15311},{"style":151},[15312],{"type":34,"value":281},{"type":29,"tag":88,"props":15314,"children":15315},{"style":298},[15316],{"type":34,"value":11904},{"type":29,"tag":88,"props":15318,"children":15319},{"style":122},[15320],{"type":34,"value":192},{"type":29,"tag":88,"props":15322,"children":15323},{"style":1974},[15324],{"type":34,"value":15325}," @",{"type":29,"tag":88,"props":15327,"children":15328},{"style":1980},[15329],{"type":34,"value":9398},{"type":29,"tag":88,"props":15331,"children":15332},{"style":151},[15333],{"type":34,"value":11728},{"type":29,"tag":88,"props":15335,"children":15336},{"style":298},[15337],{"type":34,"value":11038},{"type":29,"tag":88,"props":15339,"children":15340},{"style":122},[15341],{"type":34,"value":306},{"type":29,"tag":88,"props":15343,"children":15344},{"style":122},[15345],{"type":34,"value":125},{"type":29,"tag":88,"props":15347,"children":15348},{"class":90,"line":767},[15349,15353,15357,15361,15365,15369,15374,15378,15382,15386,15390],{"type":29,"tag":88,"props":15350,"children":15351},{"style":151},[15352],{"type":34,"value":11748},{"type":29,"tag":88,"props":15354,"children":15355},{"style":157},[15356],{"type":34,"value":11753},{"type":29,"tag":88,"props":15358,"children":15359},{"style":163},[15360],{"type":34,"value":166},{"type":29,"tag":88,"props":15362,"children":15363},{"style":157},[15364],{"type":34,"value":11572},{"type":29,"tag":88,"props":15366,"children":15367},{"style":122},[15368],{"type":34,"value":338},{"type":29,"tag":88,"props":15370,"children":15371},{"style":174},[15372],{"type":34,"value":15373},"addItemToCart",{"type":29,"tag":88,"props":15375,"children":15376},{"style":122},[15377],{"type":34,"value":181},{"type":29,"tag":88,"props":15379,"children":15380},{"style":157},[15381],{"type":34,"value":11950},{"type":29,"tag":88,"props":15383,"children":15384},{"style":122},[15385],{"type":34,"value":192},{"type":29,"tag":88,"props":15387,"children":15388},{"style":157},[15389],{"type":34,"value":11038},{"type":29,"tag":88,"props":15391,"children":15392},{"style":122},[15393],{"type":34,"value":357},{"type":29,"tag":88,"props":15395,"children":15396},{"class":90,"line":792},[15397,15401,15405,15409,15413,15417,15421],{"type":29,"tag":88,"props":15398,"children":15399},{"style":105},[15400],{"type":34,"value":415},{"type":29,"tag":88,"props":15402,"children":15403},{"style":157},[15404],{"type":34,"value":9367},{"type":29,"tag":88,"props":15406,"children":15407},{"style":122},[15408],{"type":34,"value":338},{"type":29,"tag":88,"props":15410,"children":15411},{"style":174},[15412],{"type":34,"value":11802},{"type":29,"tag":88,"props":15414,"children":15415},{"style":122},[15416],{"type":34,"value":181},{"type":29,"tag":88,"props":15418,"children":15419},{"style":157},[15420],{"type":34,"value":11811},{"type":29,"tag":88,"props":15422,"children":15423},{"style":122},[15424],{"type":34,"value":357},{"type":29,"tag":88,"props":15426,"children":15427},{"class":90,"line":817},[15428],{"type":29,"tag":88,"props":15429,"children":15430},{"style":122},[15431],{"type":34,"value":433},{"type":29,"tag":88,"props":15433,"children":15434},{"class":90,"line":825},[15435],{"type":29,"tag":88,"props":15436,"children":15437},{"emptyLinePlaceholder":13},[15438],{"type":34,"value":134},{"type":29,"tag":88,"props":15440,"children":15441},{"class":90,"line":869},[15442,15446,15451,15455,15460],{"type":29,"tag":88,"props":15443,"children":15444},{"style":1974},[15445],{"type":34,"value":3302},{"type":29,"tag":88,"props":15447,"children":15448},{"style":1980},[15449],{"type":34,"value":15450},"DeleteMapping",{"type":29,"tag":88,"props":15452,"children":15453},{"style":122},[15454],{"type":34,"value":181},{"type":29,"tag":88,"props":15456,"children":15457},{"style":184},[15458],{"type":34,"value":15459},"\"\u002F{cartId}\u002Fremove\"",{"type":29,"tag":88,"props":15461,"children":15462},{"style":122},[15463],{"type":34,"value":3078},{"type":29,"tag":88,"props":15465,"children":15466},{"class":90,"line":900},[15467,15471,15475,15479,15483,15487,15491,15495,15499,15503,15507,15511,15515,15519,15523,15527,15531,15535],{"type":29,"tag":88,"props":15468,"children":15469},{"style":105},[15470],{"type":34,"value":276},{"type":29,"tag":88,"props":15472,"children":15473},{"style":151},[15474],{"type":34,"value":9367},{"type":29,"tag":88,"props":15476,"children":15477},{"style":122},[15478],{"type":34,"value":1683},{"type":29,"tag":88,"props":15480,"children":15481},{"style":105},[15482],{"type":34,"value":11702},{"type":29,"tag":88,"props":15484,"children":15485},{"style":122},[15486],{"type":34,"value":1701},{"type":29,"tag":88,"props":15488,"children":15489},{"style":174},[15490],{"type":34,"value":11105},{"type":29,"tag":88,"props":15492,"children":15493},{"style":122},[15494],{"type":34,"value":181},{"type":29,"tag":88,"props":15496,"children":15497},{"style":1974},[15498],{"type":34,"value":1977},{"type":29,"tag":88,"props":15500,"children":15501},{"style":1980},[15502],{"type":34,"value":11895},{"type":29,"tag":88,"props":15504,"children":15505},{"style":151},[15506],{"type":34,"value":281},{"type":29,"tag":88,"props":15508,"children":15509},{"style":298},[15510],{"type":34,"value":11904},{"type":29,"tag":88,"props":15512,"children":15513},{"style":122},[15514],{"type":34,"value":192},{"type":29,"tag":88,"props":15516,"children":15517},{"style":1974},[15518],{"type":34,"value":15325},{"type":29,"tag":88,"props":15520,"children":15521},{"style":1980},[15522],{"type":34,"value":9398},{"type":29,"tag":88,"props":15524,"children":15525},{"style":151},[15526],{"type":34,"value":11728},{"type":29,"tag":88,"props":15528,"children":15529},{"style":298},[15530],{"type":34,"value":11038},{"type":29,"tag":88,"props":15532,"children":15533},{"style":122},[15534],{"type":34,"value":306},{"type":29,"tag":88,"props":15536,"children":15537},{"style":122},[15538],{"type":34,"value":125},{"type":29,"tag":88,"props":15540,"children":15541},{"class":90,"line":929},[15542,15546,15550,15554,15558,15562,15567,15571,15575,15579,15583],{"type":29,"tag":88,"props":15543,"children":15544},{"style":151},[15545],{"type":34,"value":11748},{"type":29,"tag":88,"props":15547,"children":15548},{"style":157},[15549],{"type":34,"value":11753},{"type":29,"tag":88,"props":15551,"children":15552},{"style":163},[15553],{"type":34,"value":166},{"type":29,"tag":88,"props":15555,"children":15556},{"style":157},[15557],{"type":34,"value":11572},{"type":29,"tag":88,"props":15559,"children":15560},{"style":122},[15561],{"type":34,"value":338},{"type":29,"tag":88,"props":15563,"children":15564},{"style":174},[15565],{"type":34,"value":15566},"removeItemFromCart",{"type":29,"tag":88,"props":15568,"children":15569},{"style":122},[15570],{"type":34,"value":181},{"type":29,"tag":88,"props":15572,"children":15573},{"style":157},[15574],{"type":34,"value":11950},{"type":29,"tag":88,"props":15576,"children":15577},{"style":122},[15578],{"type":34,"value":192},{"type":29,"tag":88,"props":15580,"children":15581},{"style":157},[15582],{"type":34,"value":11038},{"type":29,"tag":88,"props":15584,"children":15585},{"style":122},[15586],{"type":34,"value":357},{"type":29,"tag":88,"props":15588,"children":15589},{"class":90,"line":937},[15590,15594,15598,15602,15606,15610,15614],{"type":29,"tag":88,"props":15591,"children":15592},{"style":105},[15593],{"type":34,"value":415},{"type":29,"tag":88,"props":15595,"children":15596},{"style":157},[15597],{"type":34,"value":9367},{"type":29,"tag":88,"props":15599,"children":15600},{"style":122},[15601],{"type":34,"value":338},{"type":29,"tag":88,"props":15603,"children":15604},{"style":174},[15605],{"type":34,"value":11802},{"type":29,"tag":88,"props":15607,"children":15608},{"style":122},[15609],{"type":34,"value":181},{"type":29,"tag":88,"props":15611,"children":15612},{"style":157},[15613],{"type":34,"value":11811},{"type":29,"tag":88,"props":15615,"children":15616},{"style":122},[15617],{"type":34,"value":357},{"type":29,"tag":88,"props":15619,"children":15620},{"class":90,"line":945},[15621],{"type":29,"tag":88,"props":15622,"children":15623},{"style":122},[15624],{"type":34,"value":433},{"type":29,"tag":88,"props":15626,"children":15627},{"class":90,"line":981},[15628],{"type":29,"tag":88,"props":15629,"children":15630},{"emptyLinePlaceholder":13},[15631],{"type":34,"value":134},{"type":29,"tag":88,"props":15633,"children":15634},{"class":90,"line":1021},[15635,15639,15643,15647,15652],{"type":29,"tag":88,"props":15636,"children":15637},{"style":1974},[15638],{"type":34,"value":3302},{"type":29,"tag":88,"props":15640,"children":15641},{"style":1980},[15642],{"type":34,"value":11841},{"type":29,"tag":88,"props":15644,"children":15645},{"style":122},[15646],{"type":34,"value":181},{"type":29,"tag":88,"props":15648,"children":15649},{"style":184},[15650],{"type":34,"value":15651},"\"\u002F{cartId}\u002Ftotal\"",{"type":29,"tag":88,"props":15653,"children":15654},{"style":122},[15655],{"type":34,"value":3078},{"type":29,"tag":88,"props":15657,"children":15658},{"class":90,"line":1066},[15659,15663,15667,15671,15676,15680,15684,15688,15692,15696,15700,15704,15708],{"type":29,"tag":88,"props":15660,"children":15661},{"style":105},[15662],{"type":34,"value":276},{"type":29,"tag":88,"props":15664,"children":15665},{"style":151},[15666],{"type":34,"value":9367},{"type":29,"tag":88,"props":15668,"children":15669},{"style":122},[15670],{"type":34,"value":1683},{"type":29,"tag":88,"props":15672,"children":15673},{"style":105},[15674],{"type":34,"value":15675},"Double",{"type":29,"tag":88,"props":15677,"children":15678},{"style":122},[15679],{"type":34,"value":1701},{"type":29,"tag":88,"props":15681,"children":15682},{"style":174},[15683],{"type":34,"value":14361},{"type":29,"tag":88,"props":15685,"children":15686},{"style":122},[15687],{"type":34,"value":181},{"type":29,"tag":88,"props":15689,"children":15690},{"style":1974},[15691],{"type":34,"value":1977},{"type":29,"tag":88,"props":15693,"children":15694},{"style":1980},[15695],{"type":34,"value":11895},{"type":29,"tag":88,"props":15697,"children":15698},{"style":151},[15699],{"type":34,"value":281},{"type":29,"tag":88,"props":15701,"children":15702},{"style":298},[15703],{"type":34,"value":11904},{"type":29,"tag":88,"props":15705,"children":15706},{"style":122},[15707],{"type":34,"value":306},{"type":29,"tag":88,"props":15709,"children":15710},{"style":122},[15711],{"type":34,"value":125},{"type":29,"tag":88,"props":15713,"children":15714},{"class":90,"line":1082},[15715,15720,15725,15729,15733,15737,15742,15746,15750],{"type":29,"tag":88,"props":15716,"children":15717},{"style":105},[15718],{"type":34,"value":15719},"        double",{"type":29,"tag":88,"props":15721,"children":15722},{"style":157},[15723],{"type":34,"value":15724}," total ",{"type":29,"tag":88,"props":15726,"children":15727},{"style":163},[15728],{"type":34,"value":166},{"type":29,"tag":88,"props":15730,"children":15731},{"style":157},[15732],{"type":34,"value":11572},{"type":29,"tag":88,"props":15734,"children":15735},{"style":122},[15736],{"type":34,"value":338},{"type":29,"tag":88,"props":15738,"children":15739},{"style":174},[15740],{"type":34,"value":15741},"getCartTotal",{"type":29,"tag":88,"props":15743,"children":15744},{"style":122},[15745],{"type":34,"value":181},{"type":29,"tag":88,"props":15747,"children":15748},{"style":157},[15749],{"type":34,"value":11950},{"type":29,"tag":88,"props":15751,"children":15752},{"style":122},[15753],{"type":34,"value":357},{"type":29,"tag":88,"props":15755,"children":15756},{"class":90,"line":1090},[15757,15761,15765,15769,15773,15777,15782],{"type":29,"tag":88,"props":15758,"children":15759},{"style":105},[15760],{"type":34,"value":415},{"type":29,"tag":88,"props":15762,"children":15763},{"style":157},[15764],{"type":34,"value":9367},{"type":29,"tag":88,"props":15766,"children":15767},{"style":122},[15768],{"type":34,"value":338},{"type":29,"tag":88,"props":15770,"children":15771},{"style":174},[15772],{"type":34,"value":11802},{"type":29,"tag":88,"props":15774,"children":15775},{"style":122},[15776],{"type":34,"value":181},{"type":29,"tag":88,"props":15778,"children":15779},{"style":157},[15780],{"type":34,"value":15781},"total",{"type":29,"tag":88,"props":15783,"children":15784},{"style":122},[15785],{"type":34,"value":357},{"type":29,"tag":88,"props":15787,"children":15788},{"class":90,"line":1098},[15789],{"type":29,"tag":88,"props":15790,"children":15791},{"style":122},[15792],{"type":34,"value":433},{"type":29,"tag":88,"props":15794,"children":15795},{"class":90,"line":1106},[15796],{"type":29,"tag":88,"props":15797,"children":15798},{"emptyLinePlaceholder":13},[15799],{"type":34,"value":134},{"type":29,"tag":88,"props":15801,"children":15802},{"class":90,"line":1115},[15803,15807,15811,15815,15819],{"type":29,"tag":88,"props":15804,"children":15805},{"style":1974},[15806],{"type":34,"value":3302},{"type":29,"tag":88,"props":15808,"children":15809},{"style":1980},[15810],{"type":34,"value":11841},{"type":29,"tag":88,"props":15812,"children":15813},{"style":122},[15814],{"type":34,"value":181},{"type":29,"tag":88,"props":15816,"children":15817},{"style":184},[15818],{"type":34,"value":11850},{"type":29,"tag":88,"props":15820,"children":15821},{"style":122},[15822],{"type":34,"value":3078},{"type":29,"tag":88,"props":15824,"children":15825},{"class":90,"line":11},[15826,15830,15834,15838,15842,15846,15850,15854,15858,15862,15866,15870,15874],{"type":29,"tag":88,"props":15827,"children":15828},{"style":105},[15829],{"type":34,"value":276},{"type":29,"tag":88,"props":15831,"children":15832},{"style":151},[15833],{"type":34,"value":9367},{"type":29,"tag":88,"props":15835,"children":15836},{"style":122},[15837],{"type":34,"value":1683},{"type":29,"tag":88,"props":15839,"children":15840},{"style":105},[15841],{"type":34,"value":11702},{"type":29,"tag":88,"props":15843,"children":15844},{"style":122},[15845],{"type":34,"value":1701},{"type":29,"tag":88,"props":15847,"children":15848},{"style":174},[15849],{"type":34,"value":11882},{"type":29,"tag":88,"props":15851,"children":15852},{"style":122},[15853],{"type":34,"value":181},{"type":29,"tag":88,"props":15855,"children":15856},{"style":1974},[15857],{"type":34,"value":1977},{"type":29,"tag":88,"props":15859,"children":15860},{"style":1980},[15861],{"type":34,"value":11895},{"type":29,"tag":88,"props":15863,"children":15864},{"style":151},[15865],{"type":34,"value":281},{"type":29,"tag":88,"props":15867,"children":15868},{"style":298},[15869],{"type":34,"value":11904},{"type":29,"tag":88,"props":15871,"children":15872},{"style":122},[15873],{"type":34,"value":306},{"type":29,"tag":88,"props":15875,"children":15876},{"style":122},[15877],{"type":34,"value":125},{"type":29,"tag":88,"props":15879,"children":15880},{"class":90,"line":1180},[15881,15885,15889,15893,15897,15901,15905,15909,15913],{"type":29,"tag":88,"props":15882,"children":15883},{"style":151},[15884],{"type":34,"value":11748},{"type":29,"tag":88,"props":15886,"children":15887},{"style":157},[15888],{"type":34,"value":11924},{"type":29,"tag":88,"props":15890,"children":15891},{"style":163},[15892],{"type":34,"value":166},{"type":29,"tag":88,"props":15894,"children":15895},{"style":157},[15896],{"type":34,"value":11572},{"type":29,"tag":88,"props":15898,"children":15899},{"style":122},[15900],{"type":34,"value":338},{"type":29,"tag":88,"props":15902,"children":15903},{"style":174},[15904],{"type":34,"value":11941},{"type":29,"tag":88,"props":15906,"children":15907},{"style":122},[15908],{"type":34,"value":181},{"type":29,"tag":88,"props":15910,"children":15911},{"style":157},[15912],{"type":34,"value":11950},{"type":29,"tag":88,"props":15914,"children":15915},{"style":122},[15916],{"type":34,"value":357},{"type":29,"tag":88,"props":15918,"children":15919},{"class":90,"line":1240},[15920,15924,15928,15932,15936,15940,15944],{"type":29,"tag":88,"props":15921,"children":15922},{"style":105},[15923],{"type":34,"value":415},{"type":29,"tag":88,"props":15925,"children":15926},{"style":157},[15927],{"type":34,"value":9367},{"type":29,"tag":88,"props":15929,"children":15930},{"style":122},[15931],{"type":34,"value":338},{"type":29,"tag":88,"props":15933,"children":15934},{"style":174},[15935],{"type":34,"value":11802},{"type":29,"tag":88,"props":15937,"children":15938},{"style":122},[15939],{"type":34,"value":181},{"type":29,"tag":88,"props":15941,"children":15942},{"style":157},[15943],{"type":34,"value":11982},{"type":29,"tag":88,"props":15945,"children":15946},{"style":122},[15947],{"type":34,"value":357},{"type":29,"tag":88,"props":15949,"children":15950},{"class":90,"line":1248},[15951],{"type":29,"tag":88,"props":15952,"children":15953},{"style":122},[15954],{"type":34,"value":433},{"type":29,"tag":88,"props":15956,"children":15957},{"class":90,"line":1256},[15958],{"type":29,"tag":88,"props":15959,"children":15960},{"style":122},[15961],{"type":34,"value":442},{"type":29,"tag":7066,"props":15963,"children":15964},{},[15965,15973],{"type":29,"tag":30,"props":15966,"children":15967},{},[15968],{"type":29,"tag":447,"props":15969,"children":15970},{},[15971],{"type":34,"value":15972},"Tips : Gérer les transactions distribuées",{"type":29,"tag":30,"props":15974,"children":15975},{},[15976,15978,15983],{"type":34,"value":15977},"Dans une architecture microservices, une transaction peut impliquer plusieurs services. Utilisez le ",{"type":29,"tag":447,"props":15979,"children":15980},{},[15981],{"type":34,"value":15982},"pattern de la cohérence éventuelle",{"type":34,"value":15984}," pour synchroniser les services plutôt que de tenter une transaction distribuée complexe.",{"type":29,"tag":47,"props":15986,"children":15987},{},[],{"type":29,"tag":51,"props":15989,"children":15991},{"id":15990},"conclusion-récapitulatif-et-pièges-à-éviter",[15992],{"type":29,"tag":447,"props":15993,"children":15994},{},[15995],{"type":34,"value":15996},"Conclusion : Récapitulatif et pièges à éviter",{"type":29,"tag":30,"props":15998,"children":15999},{},[16000,16002,16006,16008,16012,16014,16018],{"type":34,"value":16001},"Décomposer un monolithe en microservices reste un chantier exigeant. Avec la bonne méthode, il devient gérable. Le ",{"type":29,"tag":447,"props":16003,"children":16004},{},[16005],{"type":34,"value":10729},{"type":34,"value":16007}," structure les besoins métier, l'approche ",{"type":29,"tag":447,"props":16009,"children":16010},{},[16011],{"type":34,"value":10736},{"type":34,"value":16013}," expose les services proprement, et l'",{"type":29,"tag":447,"props":16015,"children":16016},{},[16017],{"type":34,"value":10743},{"type":34,"value":16019}," organise le code de façon modulaire et évolutive. Trois leviers complémentaires pour réussir cette transition.",{"type":29,"tag":30,"props":16021,"children":16022},{},[16023],{"type":29,"tag":447,"props":16024,"children":16025},{},[16026],{"type":34,"value":16027},"Points clés à retenir :",{"type":29,"tag":11367,"props":16029,"children":16030},{},[16031,16047,16058],{"type":29,"tag":457,"props":16032,"children":16033},{},[16034,16039,16041,16045],{"type":29,"tag":447,"props":16035,"children":16036},{},[16037],{"type":34,"value":16038},"DDD",{"type":34,"value":16040}," vous aide à découper vos services en fonction des besoins métier, grâce à des ",{"type":29,"tag":447,"props":16042,"children":16043},{},[16044],{"type":34,"value":10822},{"type":34,"value":16046}," bien définis.",{"type":29,"tag":457,"props":16048,"children":16049},{},[16050,16052,16056],{"type":34,"value":16051},"L'approche ",{"type":29,"tag":447,"props":16053,"children":16054},{},[16055],{"type":34,"value":10736},{"type":34,"value":16057}," permet de bien réfléchir à la communication entre vos microservices dès le début, en exposant des interfaces claires et documentées.",{"type":29,"tag":457,"props":16059,"children":16060},{},[16061,16062,16066],{"type":34,"value":12093},{"type":29,"tag":447,"props":16063,"children":16064},{},[16065],{"type":34,"value":10743},{"type":34,"value":16067}," structure votre projet en trois couches (domaine, application, infrastructure), facilitant la maintenabilité et les tests.",{"type":29,"tag":51,"props":16069,"children":16071},{"id":16070},"les-pièges-à-éviter",[16072,16077],{"type":29,"tag":447,"props":16073,"children":16074},{},[16075],{"type":34,"value":16076},"Les pièges à éviter",{"type":34,"value":5854},{"type":29,"tag":453,"props":16079,"children":16080},{},[16081,16091,16101],{"type":29,"tag":457,"props":16082,"children":16083},{},[16084,16089],{"type":29,"tag":447,"props":16085,"children":16086},{},[16087],{"type":34,"value":16088},"Ne pas découper trop finement",{"type":34,"value":16090}," : Vous ne voulez pas que vos services deviennent tellement petits qu'ils dépendent les uns des autres en permanence, créant un chaos ingérable.",{"type":29,"tag":457,"props":16092,"children":16093},{},[16094,16099],{"type":29,"tag":447,"props":16095,"children":16096},{},[16097],{"type":34,"value":16098},"Oublier la documentation d’API",{"type":34,"value":16100}," : Si vos APIs ne sont pas bien pensées et bien documentées, vous risquez de ralentir toute l’équipe.",{"type":29,"tag":457,"props":16102,"children":16103},{},[16104,16109],{"type":29,"tag":447,"props":16105,"children":16106},{},[16107],{"type":34,"value":16108},"Sous-estimer les dépendances entre services",{"type":34,"value":16110}," : Assurez-vous de bien gérer les transactions entre services, notamment en utilisant des événements ou des mécanismes de compensation pour éviter des incohérences.",{"type":29,"tag":47,"props":16112,"children":16113},{},[],{"type":29,"tag":2288,"props":16115,"children":16117},{"cta":5629,"href":5630,"title":16116,"type":5632},"Découper proprement n'est qu'une pratique parmi les 100 du métier",[16118],{"type":29,"tag":30,"props":16119,"children":16120},{},[16121],{"type":34,"value":16122},"Cet article isole une seule pratique : structurer un service autour de son domaine au lieu de sa technique. Le Craft Bundle réunit les 100 pratiques que j'applique pour coder propre, du découpage en Bounded Contexts à la conception des ports hexagonaux. Celles que l'IA ne vous apprendra jamais parce qu'elle ne les a jamais vues survivre à une vraie migration de monolithe.",{"type":29,"tag":47,"props":16124,"children":16125},{},[],{"type":29,"tag":51,"props":16127,"children":16129},{"id":16128},"faq-réponses-aux-questions-fréquentes",[16130],{"type":29,"tag":447,"props":16131,"children":16132},{},[16133],{"type":34,"value":16134},"FAQ : Réponses aux questions fréquentes",{"type":29,"tag":5649,"props":16136,"children":16137},{},[16138,16143],{"type":29,"tag":5653,"props":16139,"children":16140},{},[16141],{"type":34,"value":16142},"1. Comment savoir si un microservice est trop petit ou trop gros ?",{"type":29,"tag":30,"props":16144,"children":16145},{},[16146,16148,16152,16154,16158],{"type":34,"value":16147},"Un bon microservice doit avoir une responsabilité claire et isolée. S’il doit constamment interagir avec d’autres services pour accomplir une tâche, il est probablement trop petit. À l’inverse, s’il englobe plusieurs domaines fonctionnels, il est probablement trop gros. Le ",{"type":29,"tag":447,"props":16149,"children":16150},{},[16151],{"type":34,"value":16038},{"type":34,"value":16153}," aide à déterminer la bonne taille grâce aux ",{"type":29,"tag":447,"props":16155,"children":16156},{},[16157],{"type":34,"value":10822},{"type":34,"value":338},{"type":29,"tag":5649,"props":16160,"children":16161},{},[16162,16167],{"type":29,"tag":5653,"props":16163,"children":16164},{},[16165],{"type":34,"value":16166},"2. Est-ce que l’architecture hexagonale n’ajoute pas trop de complexité ?",{"type":29,"tag":30,"props":16168,"children":16169},{},[16170,16172,16177,16179,16184],{"type":34,"value":16171},"Au début, cela peut sembler ajouter quelques couches supplémentaires, mais à long terme, cela simplifie grandement la maintenabilité de votre code. L’idée est de séparer les préoccupations métiers (le ",{"type":29,"tag":447,"props":16173,"children":16174},{},[16175],{"type":34,"value":16176},"domaine",{"type":34,"value":16178},") des détails techniques (l’",{"type":29,"tag":447,"props":16180,"children":16181},{},[16182],{"type":34,"value":16183},"infrastructure",{"type":34,"value":9567},{"type":29,"tag":5649,"props":16186,"children":16187},{},[16188,16193],{"type":29,"tag":5653,"props":16189,"children":16190},{},[16191],{"type":34,"value":16192},"3. Comment gérer les transactions distribuées dans une architecture microservices ?",{"type":29,"tag":30,"props":16194,"children":16195},{},[16196,16198,16203],{"type":34,"value":16197},"Les transactions distribuées peuvent être complexes. Une solution est d’utiliser le principe de ",{"type":29,"tag":447,"props":16199,"children":16200},{},[16201],{"type":34,"value":16202},"cohérence éventuelle",{"type":34,"value":16204},". Par exemple, utilisez des événements pour notifier les services et effectuer des ajustements en asynchrone.",{"type":29,"tag":5649,"props":16206,"children":16207},{},[16208,16213],{"type":29,"tag":5653,"props":16209,"children":16210},{},[16211],{"type":34,"value":16212},"4. L’API First, ça paraît beaucoup de documentation, est-ce vraiment nécessaire ?",{"type":29,"tag":30,"props":16214,"children":16215},{},[16216,16218,16222],{"type":34,"value":16217},"Oui, absolument. Bien documenter vos APIs avant de coder vous fait gagner un temps précieux à long terme. Utilisez ",{"type":29,"tag":447,"props":16219,"children":16220},{},[16221],{"type":34,"value":11420},{"type":34,"value":16223}," pour générer la documentation automatiquement.",{"type":29,"tag":5649,"props":16225,"children":16226},{},[16227,16232],{"type":29,"tag":5653,"props":16228,"children":16229},{},[16230],{"type":34,"value":16231},"5. Quand faut-il envisager de décomposer un monolithe en microservices ?",{"type":29,"tag":30,"props":16233,"children":16234},{},[16235],{"type":34,"value":16236},"Quand votre monolithe devient trop lourd à maintenir : temps de déploiement long, dépendances fortes entre les modules, difficultés à scaler certaines parties du système.",{"type":29,"tag":2288,"props":16238,"children":16242},{"cta":16239,"href":16240,"title":16241,"type":5755},"Télécharger le guide gratuit →","\u002Fmes-ressources","Ressource gratuite : De 6 semaines à 8 jours de lead time en 90 jours",[16243],{"type":29,"tag":30,"props":16244,"children":16245},{},[16246],{"type":34,"value":16247},"Le framework 4 phases appliqué dans 12 équipes engineering, avec des exemples before\u002Fafter chiffrés (services financiers, médias, assurance). Réduire votre lead time de 50%, c'est possible avec la bonne méthode.",{"type":29,"tag":5763,"props":16249,"children":16250},{},[16251],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":16253},[16254,16255,16259,16263,16267,16272,16273,16275],{"id":10696,"depth":101,"text":10702},{"id":10763,"depth":101,"text":10769,"children":16256},[16257,16258],{"id":10806,"depth":128,"text":10812},{"id":10920,"depth":128,"text":10926},{"id":11321,"depth":101,"text":11327,"children":16260},[16261,16262],{"id":11347,"depth":128,"text":11353},{"id":11464,"depth":128,"text":11470},{"id":12082,"depth":101,"text":12088,"children":16264},[16265,16266],{"id":12120,"depth":128,"text":12126},{"id":12214,"depth":128,"text":12220},{"id":13300,"depth":101,"text":13306,"children":16268},[16269,16270,16271],{"id":13321,"depth":128,"text":13327},{"id":13790,"depth":128,"text":13796},{"id":14619,"depth":128,"text":14625},{"id":15990,"depth":101,"text":15996},{"id":16070,"depth":101,"text":16274},"Les pièges à éviter :",{"id":16128,"depth":101,"text":16134},"content:fr:architecture-craft:decomposer-monolithe-microservices-ddd-api-hexagonal-java.md","fr\u002Farchitecture-craft\u002Fdecomposer-monolithe-microservices-ddd-api-hexagonal-java.md","fr\u002Farchitecture-craft\u002Fdecomposer-monolithe-microservices-ddd-api-hexagonal-java",{"_path":16280,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":16281,"description":16282,"id":3458,"date":16283,"listed":13,"nocomments":7,"hidden":7,"categories":16284,"tags":16285,"cover":16286,"readingTime":16287,"body":16292,"_type":5777,"_id":18045,"_source":5779,"_file":18046,"_stem":18047,"_extension":5782},"\u002Ffr\u002Farchitecture-craft\u002Fbackend-for-frontend-bff-java","Backend for Frontend (BFF), Comprendre, Implémenter et Optimiser avec des Exemples en Java","Découvrez le concept du Backend for Frontend (BFF), ses avantages et comment l’implémenter avec des exemples en Java. Apprenez les bonnes pratiques et réponses aux...","2024-08-21",[6],[17,10685],"covers\u002Farticles\u002Fbackend-for-frontend.jpg",{"text":16288,"minutes":16289,"time":16290,"words":16291},"10 min read",9.585,575100,1917,{"type":26,"children":16293,"toc":18022},[16294,16299,16310,16322,16325,16331,16336,16347,16353,16396,16402,16407,16410,16416,16421,16427,16446,16452,16457,16706,16711,16717,16722,17249,17254,17260,17265,17579,17584,17590,17602,17688,17694,17699,17722,17727,17730,17744,17750,17755,17761,17773,17783,17789,17800,17810,17816,17828,17852,17858,17863,17872,17878,17883,17892,17898,17903,17912,17926,17929,17935,17948,17961,17974,17987,18000,18003,18008,18018],{"type":29,"tag":30,"props":16295,"children":16296},{},[16297],{"type":34,"value":16298},"Une API backend qui doit servir plusieurs frontends (web, mobile, parfois smartwatch) finit toujours par poser le même problème. Chaque interface a des besoins distincts. Les requêtes REST classiques ne suffisent plus. Les frontends manipulent trop de données inutiles. La maintenance devient un casse-tête.",{"type":29,"tag":30,"props":16300,"children":16301},{},[16302,16303,16308],{"type":34,"value":10774},{"type":29,"tag":447,"props":16304,"children":16305},{},[16306],{"type":34,"value":16307},"Backend for Frontend (BFF)",{"type":34,"value":16309}," répond à cette tension. Oui, c'est une couche supplémentaire dans l'architecture. Mais bien placée, cette complexité évite des migraines durables : un backend dédié par frontend, qui adapte les données aux besoins réels de chaque client.",{"type":29,"tag":30,"props":16311,"children":16312},{},[16313,16315,16320],{"type":34,"value":16314},"J’ai accompagné plusieurs équipes dans cette transition, en contexte bancaire et médias où la multiplicité des frontends est la règle. Le BFF a chaque fois fait une différence concrète sur la performance des livraisons et la satisfaction des équipes frontend. Cet article montre ",{"type":29,"tag":447,"props":16316,"children":16317},{},[16318],{"type":34,"value":16319},"comment améliorer la modularité et la performance de votre projet",{"type":34,"value":16321}," en adoptant cette approche, avec des exemples en Java.",{"type":29,"tag":47,"props":16323,"children":16324},{},[],{"type":29,"tag":51,"props":16326,"children":16328},{"id":16327},"pourquoi-utiliser-le-backend-for-frontend",[16329],{"type":34,"value":16330},"Pourquoi utiliser le Backend for Frontend ?",{"type":29,"tag":30,"props":16332,"children":16333},{},[16334],{"type":34,"value":16335},"Les API REST classiques fonctionnent bien, jusqu'à un certain point. Un backend qui doit servir une application web, une mobile et une tablette se heurte vite au mur des besoins divergents. Le mobile veut des données minimales pour ne pas saturer le réseau, le web a besoin de détails supplémentaires, la tablette demande un mélange des deux. Vouloir tout gérer dans un seul backend mène au chaos, un pattern que j’observe systématiquement dans les grandes DSI que j’accompagne.",{"type":29,"tag":30,"props":16337,"children":16338},{},[16339,16340,16345],{"type":34,"value":10774},{"type":29,"tag":447,"props":16341,"children":16342},{},[16343],{"type":34,"value":16344},"Backend for Frontend",{"type":34,"value":16346}," répond à cette tension. Plutôt qu’une API unique qui tente de satisfaire tout le monde (et échoue), on crée un backend dédié à chaque frontend. Chaque BFF adapte les données et la logique d'orchestration aux besoins de son client.",{"type":29,"tag":6010,"props":16348,"children":16350},{"id":16349},"les-avantages-du-bff",[16351],{"type":34,"value":16352},"Les avantages du BFF :",{"type":29,"tag":11367,"props":16354,"children":16355},{},[16356,16366,16376,16386],{"type":29,"tag":457,"props":16357,"children":16358},{},[16359,16364],{"type":29,"tag":447,"props":16360,"children":16361},{},[16362],{"type":34,"value":16363},"Optimisation des performances",{"type":34,"value":16365},"\nLes frontends reçoivent exactement les données dont ils ont besoin, ni plus, ni moins. Moins de surcharge réseau pour les mobiles, et des requêtes plus rapides pour les interfaces web. Ce que j’observe concrètement : des temps de réponse réduits de 30 à 50 % sur les interfaces mobiles après introduction d’un BFF dédié.",{"type":29,"tag":457,"props":16367,"children":16368},{},[16369,16374],{"type":29,"tag":447,"props":16370,"children":16371},{},[16372],{"type":34,"value":16373},"Séparation des responsabilités",{"type":34,"value":16375},"\nChaque BFF se concentre uniquement sur son frontend. Cela simplifie la gestion du code, évite les embrouilles et permet de mettre à jour une interface sans impacter les autres.",{"type":29,"tag":457,"props":16377,"children":16378},{},[16379,16384],{"type":29,"tag":447,"props":16380,"children":16381},{},[16382],{"type":34,"value":16383},"Meilleure maintenabilité",{"type":34,"value":16385},"\nLe code est plus modulaire, plus facile à tester et à maintenir. Au lieu de tout entasser dans un seul backend, chaque frontend a son serveur backend propre, ce qui réduit les risques d’introduire des bugs en essayant de répondre aux besoins divergents.",{"type":29,"tag":457,"props":16387,"children":16388},{},[16389,16394],{"type":29,"tag":447,"props":16390,"children":16391},{},[16392],{"type":34,"value":16393},"Flexibilité",{"type":34,"value":16395},"\nSi votre application web doit utiliser une logique métier différente de celle de l’application mobile, aucun problème. Chaque BFF peut implémenter sa propre version de la logique, sans impacter les autres.",{"type":29,"tag":6010,"props":16397,"children":16399},{"id":16398},"mais-attention-ce-nest-pas-magique",[16400],{"type":34,"value":16401},"Mais attention, ce n’est pas magique :",{"type":29,"tag":30,"props":16403,"children":16404},{},[16405],{"type":34,"value":16406},"Le BFF apporte de réels bénéfices, mais il ajoute une couche supplémentaire à votre architecture. Si vous n’êtes pas vigilant, cela peut compliquer la gestion et la maintenance de votre projet. Je vous recommande de trouver le bon équilibre entre modularité et complexité avant de vous lancer.",{"type":29,"tag":47,"props":16408,"children":16409},{},[],{"type":29,"tag":51,"props":16411,"children":16413},{"id":16412},"exemple-concret-en-java-implémenter-un-backend-for-frontend",[16414],{"type":34,"value":16415},"Exemple concret en Java : Implémenter un Backend for Frontend",{"type":29,"tag":30,"props":16417,"children":16418},{},[16419],{"type":34,"value":16420},"Prenons une application avec une interface web et une application mobile. Les deux clients récupèrent des informations sur les produits, mais le mobile a besoin de moins de données pour éviter la surcharge réseau, là où l'interface web exige des détails supplémentaires. Le BFF résout cette tension proprement.",{"type":29,"tag":6010,"props":16422,"children":16424},{"id":16423},"architecture-simple",[16425],{"type":34,"value":16426},"Architecture simple",{"type":29,"tag":30,"props":16428,"children":16429},{},[16430,16432,16437,16439,16444],{"type":34,"value":16431},"Pour cet exemple, deux BFF : un pour le ",{"type":29,"tag":447,"props":16433,"children":16434},{},[16435],{"type":34,"value":16436},"frontend mobile",{"type":34,"value":16438},", un pour le ",{"type":29,"tag":447,"props":16440,"children":16441},{},[16442],{"type":34,"value":16443},"frontend web",{"type":34,"value":16445},". Chaque BFF interroge le même backend principal (l'API de notre système e-commerce) et adapte la réponse selon le client.",{"type":29,"tag":6010,"props":16447,"children":16449},{"id":16448},"_1-définir-le-backend-principal-api-e-commerce",[16450],{"type":34,"value":16451},"1. Définir le backend principal (API e-commerce)",{"type":29,"tag":30,"props":16453,"children":16454},{},[16455],{"type":34,"value":16456},"Le backend principal expose une API classique qui fournit toutes les informations sur les produits.",{"type":29,"tag":77,"props":16458,"children":16460},{"className":81,"code":16459,"language":80,"meta":8,"style":8},"@RestController\n@RequestMapping(\"\u002Fapi\u002Fproducts\")\npublic class ProductController {\n\n    @GetMapping(\"\u002F{id}\")\n    public Product getProductDetails(@PathVariable Long id) {\n        \u002F\u002F Simule la récupération d'un produit à partir d'une base de données\n        Product product = new Product(id, \"Smartphone\", \"Un smartphone ultra performant\", 699.99, \"caractéristiques complètes...\");\n        return product;\n    }\n}\n",[16461],{"type":29,"tag":84,"props":16462,"children":16463},{"__ignoreMap":8},[16464,16475,16499,16519,16526,16550,16595,16603,16676,16692,16699],{"type":29,"tag":88,"props":16465,"children":16466},{"class":90,"line":91},[16467,16471],{"type":29,"tag":88,"props":16468,"children":16469},{"style":1974},[16470],{"type":34,"value":1977},{"type":29,"tag":88,"props":16472,"children":16473},{"style":1980},[16474],{"type":34,"value":9193},{"type":29,"tag":88,"props":16476,"children":16477},{"class":90,"line":101},[16478,16482,16486,16490,16495],{"type":29,"tag":88,"props":16479,"children":16480},{"style":1974},[16481],{"type":34,"value":1977},{"type":29,"tag":88,"props":16483,"children":16484},{"style":1980},[16485],{"type":34,"value":9205},{"type":29,"tag":88,"props":16487,"children":16488},{"style":122},[16489],{"type":34,"value":181},{"type":29,"tag":88,"props":16491,"children":16492},{"style":184},[16493],{"type":34,"value":16494},"\"\u002Fapi\u002Fproducts\"",{"type":29,"tag":88,"props":16496,"children":16497},{"style":122},[16498],{"type":34,"value":3078},{"type":29,"tag":88,"props":16500,"children":16501},{"class":90,"line":128},[16502,16506,16510,16515],{"type":29,"tag":88,"props":16503,"children":16504},{"style":105},[16505],{"type":34,"value":108},{"type":29,"tag":88,"props":16507,"children":16508},{"style":105},[16509],{"type":34,"value":113},{"type":29,"tag":88,"props":16511,"children":16512},{"style":116},[16513],{"type":34,"value":16514}," ProductController",{"type":29,"tag":88,"props":16516,"children":16517},{"style":122},[16518],{"type":34,"value":125},{"type":29,"tag":88,"props":16520,"children":16521},{"class":90,"line":137},[16522],{"type":29,"tag":88,"props":16523,"children":16524},{"emptyLinePlaceholder":13},[16525],{"type":34,"value":134},{"type":29,"tag":88,"props":16527,"children":16528},{"class":90,"line":211},[16529,16533,16537,16541,16546],{"type":29,"tag":88,"props":16530,"children":16531},{"style":1974},[16532],{"type":34,"value":3302},{"type":29,"tag":88,"props":16534,"children":16535},{"style":1980},[16536],{"type":34,"value":11841},{"type":29,"tag":88,"props":16538,"children":16539},{"style":122},[16540],{"type":34,"value":181},{"type":29,"tag":88,"props":16542,"children":16543},{"style":184},[16544],{"type":34,"value":16545},"\"\u002F{id}\"",{"type":29,"tag":88,"props":16547,"children":16548},{"style":122},[16549],{"type":34,"value":3078},{"type":29,"tag":88,"props":16551,"children":16552},{"class":90,"line":262},[16553,16557,16562,16567,16571,16575,16579,16583,16587,16591],{"type":29,"tag":88,"props":16554,"children":16555},{"style":105},[16556],{"type":34,"value":276},{"type":29,"tag":88,"props":16558,"children":16559},{"style":151},[16560],{"type":34,"value":16561}," Product",{"type":29,"tag":88,"props":16563,"children":16564},{"style":174},[16565],{"type":34,"value":16566}," getProductDetails",{"type":29,"tag":88,"props":16568,"children":16569},{"style":122},[16570],{"type":34,"value":181},{"type":29,"tag":88,"props":16572,"children":16573},{"style":1974},[16574],{"type":34,"value":1977},{"type":29,"tag":88,"props":16576,"children":16577},{"style":1980},[16578],{"type":34,"value":11895},{"type":29,"tag":88,"props":16580,"children":16581},{"style":151},[16582],{"type":34,"value":8051},{"type":29,"tag":88,"props":16584,"children":16585},{"style":298},[16586],{"type":34,"value":3435},{"type":29,"tag":88,"props":16588,"children":16589},{"style":122},[16590],{"type":34,"value":306},{"type":29,"tag":88,"props":16592,"children":16593},{"style":122},[16594],{"type":34,"value":125},{"type":29,"tag":88,"props":16596,"children":16597},{"class":90,"line":270},[16598],{"type":29,"tag":88,"props":16599,"children":16600},{"style":95},[16601],{"type":34,"value":16602},"        \u002F\u002F Simule la récupération d'un produit à partir d'une base de données\n",{"type":29,"tag":88,"props":16604,"children":16605},{"class":90,"line":313},[16606,16611,16616,16620,16624,16628,16632,16636,16640,16645,16649,16654,16658,16663,16667,16672],{"type":29,"tag":88,"props":16607,"children":16608},{"style":151},[16609],{"type":34,"value":16610},"        Product",{"type":29,"tag":88,"props":16612,"children":16613},{"style":157},[16614],{"type":34,"value":16615}," product ",{"type":29,"tag":88,"props":16617,"children":16618},{"style":163},[16619],{"type":34,"value":166},{"type":29,"tag":88,"props":16621,"children":16622},{"style":105},[16623],{"type":34,"value":171},{"type":29,"tag":88,"props":16625,"children":16626},{"style":174},[16627],{"type":34,"value":16561},{"type":29,"tag":88,"props":16629,"children":16630},{"style":122},[16631],{"type":34,"value":181},{"type":29,"tag":88,"props":16633,"children":16634},{"style":157},[16635],{"type":34,"value":3410},{"type":29,"tag":88,"props":16637,"children":16638},{"style":122},[16639],{"type":34,"value":192},{"type":29,"tag":88,"props":16641,"children":16642},{"style":184},[16643],{"type":34,"value":16644}," \"Smartphone\"",{"type":29,"tag":88,"props":16646,"children":16647},{"style":122},[16648],{"type":34,"value":192},{"type":29,"tag":88,"props":16650,"children":16651},{"style":184},[16652],{"type":34,"value":16653}," \"Un smartphone ultra performant\"",{"type":29,"tag":88,"props":16655,"children":16656},{"style":122},[16657],{"type":34,"value":192},{"type":29,"tag":88,"props":16659,"children":16660},{"style":195},[16661],{"type":34,"value":16662}," 699.99",{"type":29,"tag":88,"props":16664,"children":16665},{"style":122},[16666],{"type":34,"value":192},{"type":29,"tag":88,"props":16668,"children":16669},{"style":184},[16670],{"type":34,"value":16671}," \"caractéristiques complètes...\"",{"type":29,"tag":88,"props":16673,"children":16674},{"style":122},[16675],{"type":34,"value":357},{"type":29,"tag":88,"props":16677,"children":16678},{"class":90,"line":360},[16679,16683,16688],{"type":29,"tag":88,"props":16680,"children":16681},{"style":105},[16682],{"type":34,"value":415},{"type":29,"tag":88,"props":16684,"children":16685},{"style":157},[16686],{"type":34,"value":16687}," product",{"type":29,"tag":88,"props":16689,"children":16690},{"style":122},[16691],{"type":34,"value":424},{"type":29,"tag":88,"props":16693,"children":16694},{"class":90,"line":409},[16695],{"type":29,"tag":88,"props":16696,"children":16697},{"style":122},[16698],{"type":34,"value":433},{"type":29,"tag":88,"props":16700,"children":16701},{"class":90,"line":427},[16702],{"type":29,"tag":88,"props":16703,"children":16704},{"style":122},[16705],{"type":34,"value":442},{"type":29,"tag":30,"props":16707,"children":16708},{},[16709],{"type":34,"value":16710},"Ce backend renvoie toutes les informations d’un produit, qu’il s’agisse de son nom, sa description, son prix et d’autres détails. C’est génial pour une interface web, mais probablement trop lourd pour une application mobile.",{"type":29,"tag":6010,"props":16712,"children":16714},{"id":16713},"_2-implémenter-le-bff-pour-lapplication-mobile",[16715],{"type":34,"value":16716},"2. Implémenter le BFF pour l’application mobile",{"type":29,"tag":30,"props":16718,"children":16719},{},[16720],{"type":34,"value":16721},"Le BFF mobile n'a besoin que du nom et du prix du produit. Voici comment il peut simplifier les données renvoyées au frontend mobile.",{"type":29,"tag":77,"props":16723,"children":16725},{"className":81,"code":16724,"language":80,"meta":8,"style":8},"@RestController\n@RequestMapping(\"\u002Fbff\u002Fmobile\u002Fproducts\")\npublic class MobileProductController {\n\n    private final RestTemplate restTemplate;\n\n    public MobileProductController(RestTemplate restTemplate) {\n        this.restTemplate = restTemplate;\n    }\n\n    @GetMapping(\"\u002F{id}\")\n    public Map\u003CString, Object> getProductForMobile(@PathVariable Long id) {\n        \u002F\u002F Récupération des données complètes depuis le backend principal\n        Product product = restTemplate.getForObject(\"http:\u002F\u002Flocalhost:8080\u002Fapi\u002Fproducts\u002F\" + id, Product.class);\n\n        \u002F\u002F Adapter la réponse pour le mobile\n        Map\u003CString, Object> productForMobile = new HashMap\u003C>();\n        productForMobile.put(\"name\", product.getName());\n        productForMobile.put(\"price\", product.getPrice());\n\n        return productForMobile;\n    }\n}\n",[16726],{"type":29,"tag":84,"props":16727,"children":16728},{"__ignoreMap":8},[16729,16740,16764,16784,16791,16816,16823,16855,16883,16890,16897,16920,16985,16993,17058,17065,17073,17122,17168,17212,17219,17235,17242],{"type":29,"tag":88,"props":16730,"children":16731},{"class":90,"line":91},[16732,16736],{"type":29,"tag":88,"props":16733,"children":16734},{"style":1974},[16735],{"type":34,"value":1977},{"type":29,"tag":88,"props":16737,"children":16738},{"style":1980},[16739],{"type":34,"value":9193},{"type":29,"tag":88,"props":16741,"children":16742},{"class":90,"line":101},[16743,16747,16751,16755,16760],{"type":29,"tag":88,"props":16744,"children":16745},{"style":1974},[16746],{"type":34,"value":1977},{"type":29,"tag":88,"props":16748,"children":16749},{"style":1980},[16750],{"type":34,"value":9205},{"type":29,"tag":88,"props":16752,"children":16753},{"style":122},[16754],{"type":34,"value":181},{"type":29,"tag":88,"props":16756,"children":16757},{"style":184},[16758],{"type":34,"value":16759},"\"\u002Fbff\u002Fmobile\u002Fproducts\"",{"type":29,"tag":88,"props":16761,"children":16762},{"style":122},[16763],{"type":34,"value":3078},{"type":29,"tag":88,"props":16765,"children":16766},{"class":90,"line":128},[16767,16771,16775,16780],{"type":29,"tag":88,"props":16768,"children":16769},{"style":105},[16770],{"type":34,"value":108},{"type":29,"tag":88,"props":16772,"children":16773},{"style":105},[16774],{"type":34,"value":113},{"type":29,"tag":88,"props":16776,"children":16777},{"style":116},[16778],{"type":34,"value":16779}," MobileProductController",{"type":29,"tag":88,"props":16781,"children":16782},{"style":122},[16783],{"type":34,"value":125},{"type":29,"tag":88,"props":16785,"children":16786},{"class":90,"line":137},[16787],{"type":29,"tag":88,"props":16788,"children":16789},{"emptyLinePlaceholder":13},[16790],{"type":34,"value":134},{"type":29,"tag":88,"props":16792,"children":16793},{"class":90,"line":211},[16794,16798,16802,16807,16812],{"type":29,"tag":88,"props":16795,"children":16796},{"style":105},[16797],{"type":34,"value":143},{"type":29,"tag":88,"props":16799,"children":16800},{"style":105},[16801],{"type":34,"value":148},{"type":29,"tag":88,"props":16803,"children":16804},{"style":151},[16805],{"type":34,"value":16806}," RestTemplate",{"type":29,"tag":88,"props":16808,"children":16809},{"style":157},[16810],{"type":34,"value":16811}," restTemplate",{"type":29,"tag":88,"props":16813,"children":16814},{"style":122},[16815],{"type":34,"value":424},{"type":29,"tag":88,"props":16817,"children":16818},{"class":90,"line":262},[16819],{"type":29,"tag":88,"props":16820,"children":16821},{"emptyLinePlaceholder":13},[16822],{"type":34,"value":134},{"type":29,"tag":88,"props":16824,"children":16825},{"class":90,"line":270},[16826,16830,16834,16838,16843,16847,16851],{"type":29,"tag":88,"props":16827,"children":16828},{"style":105},[16829],{"type":34,"value":276},{"type":29,"tag":88,"props":16831,"children":16832},{"style":174},[16833],{"type":34,"value":16779},{"type":29,"tag":88,"props":16835,"children":16836},{"style":122},[16837],{"type":34,"value":181},{"type":29,"tag":88,"props":16839,"children":16840},{"style":151},[16841],{"type":34,"value":16842},"RestTemplate",{"type":29,"tag":88,"props":16844,"children":16845},{"style":298},[16846],{"type":34,"value":16811},{"type":29,"tag":88,"props":16848,"children":16849},{"style":122},[16850],{"type":34,"value":306},{"type":29,"tag":88,"props":16852,"children":16853},{"style":122},[16854],{"type":34,"value":125},{"type":29,"tag":88,"props":16856,"children":16857},{"class":90,"line":313},[16858,16862,16866,16871,16875,16879],{"type":29,"tag":88,"props":16859,"children":16860},{"style":873},[16861],{"type":34,"value":876},{"type":29,"tag":88,"props":16863,"children":16864},{"style":122},[16865],{"type":34,"value":338},{"type":29,"tag":88,"props":16867,"children":16868},{"style":157},[16869],{"type":34,"value":16870},"restTemplate ",{"type":29,"tag":88,"props":16872,"children":16873},{"style":163},[16874],{"type":34,"value":166},{"type":29,"tag":88,"props":16876,"children":16877},{"style":157},[16878],{"type":34,"value":16811},{"type":29,"tag":88,"props":16880,"children":16881},{"style":122},[16882],{"type":34,"value":424},{"type":29,"tag":88,"props":16884,"children":16885},{"class":90,"line":360},[16886],{"type":29,"tag":88,"props":16887,"children":16888},{"style":122},[16889],{"type":34,"value":433},{"type":29,"tag":88,"props":16891,"children":16892},{"class":90,"line":409},[16893],{"type":29,"tag":88,"props":16894,"children":16895},{"emptyLinePlaceholder":13},[16896],{"type":34,"value":134},{"type":29,"tag":88,"props":16898,"children":16899},{"class":90,"line":427},[16900,16904,16908,16912,16916],{"type":29,"tag":88,"props":16901,"children":16902},{"style":1974},[16903],{"type":34,"value":3302},{"type":29,"tag":88,"props":16905,"children":16906},{"style":1980},[16907],{"type":34,"value":11841},{"type":29,"tag":88,"props":16909,"children":16910},{"style":122},[16911],{"type":34,"value":181},{"type":29,"tag":88,"props":16913,"children":16914},{"style":184},[16915],{"type":34,"value":16545},{"type":29,"tag":88,"props":16917,"children":16918},{"style":122},[16919],{"type":34,"value":3078},{"type":29,"tag":88,"props":16921,"children":16922},{"class":90,"line":436},[16923,16927,16931,16935,16939,16943,16948,16952,16957,16961,16965,16969,16973,16977,16981],{"type":29,"tag":88,"props":16924,"children":16925},{"style":105},[16926],{"type":34,"value":276},{"type":29,"tag":88,"props":16928,"children":16929},{"style":151},[16930],{"type":34,"value":1384},{"type":29,"tag":88,"props":16932,"children":16933},{"style":122},[16934],{"type":34,"value":1683},{"type":29,"tag":88,"props":16936,"children":16937},{"style":105},[16938],{"type":34,"value":695},{"type":29,"tag":88,"props":16940,"children":16941},{"style":122},[16942],{"type":34,"value":192},{"type":29,"tag":88,"props":16944,"children":16945},{"style":105},[16946],{"type":34,"value":16947}," Object",{"type":29,"tag":88,"props":16949,"children":16950},{"style":122},[16951],{"type":34,"value":1701},{"type":29,"tag":88,"props":16953,"children":16954},{"style":174},[16955],{"type":34,"value":16956}," getProductForMobile",{"type":29,"tag":88,"props":16958,"children":16959},{"style":122},[16960],{"type":34,"value":181},{"type":29,"tag":88,"props":16962,"children":16963},{"style":1974},[16964],{"type":34,"value":1977},{"type":29,"tag":88,"props":16966,"children":16967},{"style":1980},[16968],{"type":34,"value":11895},{"type":29,"tag":88,"props":16970,"children":16971},{"style":151},[16972],{"type":34,"value":8051},{"type":29,"tag":88,"props":16974,"children":16975},{"style":298},[16976],{"type":34,"value":3435},{"type":29,"tag":88,"props":16978,"children":16979},{"style":122},[16980],{"type":34,"value":306},{"type":29,"tag":88,"props":16982,"children":16983},{"style":122},[16984],{"type":34,"value":125},{"type":29,"tag":88,"props":16986,"children":16987},{"class":90,"line":767},[16988],{"type":29,"tag":88,"props":16989,"children":16990},{"style":95},[16991],{"type":34,"value":16992},"        \u002F\u002F Récupération des données complètes depuis le backend principal\n",{"type":29,"tag":88,"props":16994,"children":16995},{"class":90,"line":792},[16996,17000,17004,17008,17012,17016,17021,17025,17030,17034,17038,17042,17046,17050,17054],{"type":29,"tag":88,"props":16997,"children":16998},{"style":151},[16999],{"type":34,"value":16610},{"type":29,"tag":88,"props":17001,"children":17002},{"style":157},[17003],{"type":34,"value":16615},{"type":29,"tag":88,"props":17005,"children":17006},{"style":163},[17007],{"type":34,"value":166},{"type":29,"tag":88,"props":17009,"children":17010},{"style":157},[17011],{"type":34,"value":16811},{"type":29,"tag":88,"props":17013,"children":17014},{"style":122},[17015],{"type":34,"value":338},{"type":29,"tag":88,"props":17017,"children":17018},{"style":174},[17019],{"type":34,"value":17020},"getForObject",{"type":29,"tag":88,"props":17022,"children":17023},{"style":122},[17024],{"type":34,"value":181},{"type":29,"tag":88,"props":17026,"children":17027},{"style":184},[17028],{"type":34,"value":17029},"\"http:\u002F\u002Flocalhost:8080\u002Fapi\u002Fproducts\u002F\"",{"type":29,"tag":88,"props":17031,"children":17032},{"style":163},[17033],{"type":34,"value":5485},{"type":29,"tag":88,"props":17035,"children":17036},{"style":157},[17037],{"type":34,"value":3435},{"type":29,"tag":88,"props":17039,"children":17040},{"style":122},[17041],{"type":34,"value":192},{"type":29,"tag":88,"props":17043,"children":17044},{"style":157},[17045],{"type":34,"value":16561},{"type":29,"tag":88,"props":17047,"children":17048},{"style":122},[17049],{"type":34,"value":338},{"type":29,"tag":88,"props":17051,"children":17052},{"style":157},[17053],{"type":34,"value":1225},{"type":29,"tag":88,"props":17055,"children":17056},{"style":122},[17057],{"type":34,"value":357},{"type":29,"tag":88,"props":17059,"children":17060},{"class":90,"line":817},[17061],{"type":29,"tag":88,"props":17062,"children":17063},{"emptyLinePlaceholder":13},[17064],{"type":34,"value":134},{"type":29,"tag":88,"props":17066,"children":17067},{"class":90,"line":825},[17068],{"type":29,"tag":88,"props":17069,"children":17070},{"style":95},[17071],{"type":34,"value":17072},"        \u002F\u002F Adapter la réponse pour le mobile\n",{"type":29,"tag":88,"props":17074,"children":17075},{"class":90,"line":869},[17076,17081,17085,17089,17093,17097,17101,17106,17110,17114,17118],{"type":29,"tag":88,"props":17077,"children":17078},{"style":151},[17079],{"type":34,"value":17080},"        Map",{"type":29,"tag":88,"props":17082,"children":17083},{"style":122},[17084],{"type":34,"value":1683},{"type":29,"tag":88,"props":17086,"children":17087},{"style":105},[17088],{"type":34,"value":695},{"type":29,"tag":88,"props":17090,"children":17091},{"style":122},[17092],{"type":34,"value":192},{"type":29,"tag":88,"props":17094,"children":17095},{"style":105},[17096],{"type":34,"value":16947},{"type":29,"tag":88,"props":17098,"children":17099},{"style":122},[17100],{"type":34,"value":1701},{"type":29,"tag":88,"props":17102,"children":17103},{"style":157},[17104],{"type":34,"value":17105}," productForMobile ",{"type":29,"tag":88,"props":17107,"children":17108},{"style":163},[17109],{"type":34,"value":166},{"type":29,"tag":88,"props":17111,"children":17112},{"style":105},[17113],{"type":34,"value":171},{"type":29,"tag":88,"props":17115,"children":17116},{"style":151},[17117],{"type":34,"value":1719},{"type":29,"tag":88,"props":17119,"children":17120},{"style":122},[17121],{"type":34,"value":1724},{"type":29,"tag":88,"props":17123,"children":17124},{"class":90,"line":900},[17125,17130,17134,17138,17142,17147,17151,17155,17159,17164],{"type":29,"tag":88,"props":17126,"children":17127},{"style":157},[17128],{"type":34,"value":17129},"        productForMobile",{"type":29,"tag":88,"props":17131,"children":17132},{"style":122},[17133],{"type":34,"value":338},{"type":29,"tag":88,"props":17135,"children":17136},{"style":174},[17137],{"type":34,"value":1827},{"type":29,"tag":88,"props":17139,"children":17140},{"style":122},[17141],{"type":34,"value":181},{"type":29,"tag":88,"props":17143,"children":17144},{"style":184},[17145],{"type":34,"value":17146},"\"name\"",{"type":29,"tag":88,"props":17148,"children":17149},{"style":122},[17150],{"type":34,"value":192},{"type":29,"tag":88,"props":17152,"children":17153},{"style":157},[17154],{"type":34,"value":16687},{"type":29,"tag":88,"props":17156,"children":17157},{"style":122},[17158],{"type":34,"value":338},{"type":29,"tag":88,"props":17160,"children":17161},{"style":174},[17162],{"type":34,"value":17163},"getName",{"type":29,"tag":88,"props":17165,"children":17166},{"style":122},[17167],{"type":34,"value":2958},{"type":29,"tag":88,"props":17169,"children":17170},{"class":90,"line":929},[17171,17175,17179,17183,17187,17192,17196,17200,17204,17208],{"type":29,"tag":88,"props":17172,"children":17173},{"style":157},[17174],{"type":34,"value":17129},{"type":29,"tag":88,"props":17176,"children":17177},{"style":122},[17178],{"type":34,"value":338},{"type":29,"tag":88,"props":17180,"children":17181},{"style":174},[17182],{"type":34,"value":1827},{"type":29,"tag":88,"props":17184,"children":17185},{"style":122},[17186],{"type":34,"value":181},{"type":29,"tag":88,"props":17188,"children":17189},{"style":184},[17190],{"type":34,"value":17191},"\"price\"",{"type":29,"tag":88,"props":17193,"children":17194},{"style":122},[17195],{"type":34,"value":192},{"type":29,"tag":88,"props":17197,"children":17198},{"style":157},[17199],{"type":34,"value":16687},{"type":29,"tag":88,"props":17201,"children":17202},{"style":122},[17203],{"type":34,"value":338},{"type":29,"tag":88,"props":17205,"children":17206},{"style":174},[17207],{"type":34,"value":11246},{"type":29,"tag":88,"props":17209,"children":17210},{"style":122},[17211],{"type":34,"value":2958},{"type":29,"tag":88,"props":17213,"children":17214},{"class":90,"line":937},[17215],{"type":29,"tag":88,"props":17216,"children":17217},{"emptyLinePlaceholder":13},[17218],{"type":34,"value":134},{"type":29,"tag":88,"props":17220,"children":17221},{"class":90,"line":945},[17222,17226,17231],{"type":29,"tag":88,"props":17223,"children":17224},{"style":105},[17225],{"type":34,"value":415},{"type":29,"tag":88,"props":17227,"children":17228},{"style":157},[17229],{"type":34,"value":17230}," productForMobile",{"type":29,"tag":88,"props":17232,"children":17233},{"style":122},[17234],{"type":34,"value":424},{"type":29,"tag":88,"props":17236,"children":17237},{"class":90,"line":981},[17238],{"type":29,"tag":88,"props":17239,"children":17240},{"style":122},[17241],{"type":34,"value":433},{"type":29,"tag":88,"props":17243,"children":17244},{"class":90,"line":1021},[17245],{"type":29,"tag":88,"props":17246,"children":17247},{"style":122},[17248],{"type":34,"value":442},{"type":29,"tag":30,"props":17250,"children":17251},{},[17252],{"type":34,"value":17253},"Ici, le BFF mobile fait une requête au backend principal, mais ne renvoie que les informations pertinentes pour l’application mobile : le nom et le prix du produit. On simplifie ainsi la réponse pour qu’elle soit plus légère et adaptée au réseau mobile.",{"type":29,"tag":6010,"props":17255,"children":17257},{"id":17256},"_3-implémenter-le-bff-pour-lapplication-web",[17258],{"type":34,"value":17259},"3. Implémenter le BFF pour l’application web",{"type":29,"tag":30,"props":17261,"children":17262},{},[17263],{"type":34,"value":17264},"L'application web, quant à elle, a besoin de plus de détails : la description complète, les caractéristiques, etc. Voici le BFF pour cette interface.",{"type":29,"tag":77,"props":17266,"children":17268},{"className":81,"code":17267,"language":80,"meta":8,"style":8},"@RestController\n@RequestMapping(\"\u002Fbff\u002Fweb\u002Fproducts\")\npublic class WebProductController {\n\n    private final RestTemplate restTemplate;\n\n    public WebProductController(RestTemplate restTemplate) {\n        this.restTemplate = restTemplate;\n    }\n\n    @GetMapping(\"\u002F{id}\")\n    public Product getProductForWeb(@PathVariable Long id) {\n        \u002F\u002F Récupération des données complètes depuis le backend principal\n        return restTemplate.getForObject(\"http:\u002F\u002Flocalhost:8080\u002Fapi\u002Fproducts\u002F\" + id, Product.class);\n    }\n}\n",[17269],{"type":29,"tag":84,"props":17270,"children":17271},{"__ignoreMap":8},[17272,17283,17307,17327,17334,17357,17364,17395,17422,17429,17436,17459,17503,17510,17565,17572],{"type":29,"tag":88,"props":17273,"children":17274},{"class":90,"line":91},[17275,17279],{"type":29,"tag":88,"props":17276,"children":17277},{"style":1974},[17278],{"type":34,"value":1977},{"type":29,"tag":88,"props":17280,"children":17281},{"style":1980},[17282],{"type":34,"value":9193},{"type":29,"tag":88,"props":17284,"children":17285},{"class":90,"line":101},[17286,17290,17294,17298,17303],{"type":29,"tag":88,"props":17287,"children":17288},{"style":1974},[17289],{"type":34,"value":1977},{"type":29,"tag":88,"props":17291,"children":17292},{"style":1980},[17293],{"type":34,"value":9205},{"type":29,"tag":88,"props":17295,"children":17296},{"style":122},[17297],{"type":34,"value":181},{"type":29,"tag":88,"props":17299,"children":17300},{"style":184},[17301],{"type":34,"value":17302},"\"\u002Fbff\u002Fweb\u002Fproducts\"",{"type":29,"tag":88,"props":17304,"children":17305},{"style":122},[17306],{"type":34,"value":3078},{"type":29,"tag":88,"props":17308,"children":17309},{"class":90,"line":128},[17310,17314,17318,17323],{"type":29,"tag":88,"props":17311,"children":17312},{"style":105},[17313],{"type":34,"value":108},{"type":29,"tag":88,"props":17315,"children":17316},{"style":105},[17317],{"type":34,"value":113},{"type":29,"tag":88,"props":17319,"children":17320},{"style":116},[17321],{"type":34,"value":17322}," WebProductController",{"type":29,"tag":88,"props":17324,"children":17325},{"style":122},[17326],{"type":34,"value":125},{"type":29,"tag":88,"props":17328,"children":17329},{"class":90,"line":137},[17330],{"type":29,"tag":88,"props":17331,"children":17332},{"emptyLinePlaceholder":13},[17333],{"type":34,"value":134},{"type":29,"tag":88,"props":17335,"children":17336},{"class":90,"line":211},[17337,17341,17345,17349,17353],{"type":29,"tag":88,"props":17338,"children":17339},{"style":105},[17340],{"type":34,"value":143},{"type":29,"tag":88,"props":17342,"children":17343},{"style":105},[17344],{"type":34,"value":148},{"type":29,"tag":88,"props":17346,"children":17347},{"style":151},[17348],{"type":34,"value":16806},{"type":29,"tag":88,"props":17350,"children":17351},{"style":157},[17352],{"type":34,"value":16811},{"type":29,"tag":88,"props":17354,"children":17355},{"style":122},[17356],{"type":34,"value":424},{"type":29,"tag":88,"props":17358,"children":17359},{"class":90,"line":262},[17360],{"type":29,"tag":88,"props":17361,"children":17362},{"emptyLinePlaceholder":13},[17363],{"type":34,"value":134},{"type":29,"tag":88,"props":17365,"children":17366},{"class":90,"line":270},[17367,17371,17375,17379,17383,17387,17391],{"type":29,"tag":88,"props":17368,"children":17369},{"style":105},[17370],{"type":34,"value":276},{"type":29,"tag":88,"props":17372,"children":17373},{"style":174},[17374],{"type":34,"value":17322},{"type":29,"tag":88,"props":17376,"children":17377},{"style":122},[17378],{"type":34,"value":181},{"type":29,"tag":88,"props":17380,"children":17381},{"style":151},[17382],{"type":34,"value":16842},{"type":29,"tag":88,"props":17384,"children":17385},{"style":298},[17386],{"type":34,"value":16811},{"type":29,"tag":88,"props":17388,"children":17389},{"style":122},[17390],{"type":34,"value":306},{"type":29,"tag":88,"props":17392,"children":17393},{"style":122},[17394],{"type":34,"value":125},{"type":29,"tag":88,"props":17396,"children":17397},{"class":90,"line":313},[17398,17402,17406,17410,17414,17418],{"type":29,"tag":88,"props":17399,"children":17400},{"style":873},[17401],{"type":34,"value":876},{"type":29,"tag":88,"props":17403,"children":17404},{"style":122},[17405],{"type":34,"value":338},{"type":29,"tag":88,"props":17407,"children":17408},{"style":157},[17409],{"type":34,"value":16870},{"type":29,"tag":88,"props":17411,"children":17412},{"style":163},[17413],{"type":34,"value":166},{"type":29,"tag":88,"props":17415,"children":17416},{"style":157},[17417],{"type":34,"value":16811},{"type":29,"tag":88,"props":17419,"children":17420},{"style":122},[17421],{"type":34,"value":424},{"type":29,"tag":88,"props":17423,"children":17424},{"class":90,"line":360},[17425],{"type":29,"tag":88,"props":17426,"children":17427},{"style":122},[17428],{"type":34,"value":433},{"type":29,"tag":88,"props":17430,"children":17431},{"class":90,"line":409},[17432],{"type":29,"tag":88,"props":17433,"children":17434},{"emptyLinePlaceholder":13},[17435],{"type":34,"value":134},{"type":29,"tag":88,"props":17437,"children":17438},{"class":90,"line":427},[17439,17443,17447,17451,17455],{"type":29,"tag":88,"props":17440,"children":17441},{"style":1974},[17442],{"type":34,"value":3302},{"type":29,"tag":88,"props":17444,"children":17445},{"style":1980},[17446],{"type":34,"value":11841},{"type":29,"tag":88,"props":17448,"children":17449},{"style":122},[17450],{"type":34,"value":181},{"type":29,"tag":88,"props":17452,"children":17453},{"style":184},[17454],{"type":34,"value":16545},{"type":29,"tag":88,"props":17456,"children":17457},{"style":122},[17458],{"type":34,"value":3078},{"type":29,"tag":88,"props":17460,"children":17461},{"class":90,"line":436},[17462,17466,17470,17475,17479,17483,17487,17491,17495,17499],{"type":29,"tag":88,"props":17463,"children":17464},{"style":105},[17465],{"type":34,"value":276},{"type":29,"tag":88,"props":17467,"children":17468},{"style":151},[17469],{"type":34,"value":16561},{"type":29,"tag":88,"props":17471,"children":17472},{"style":174},[17473],{"type":34,"value":17474}," getProductForWeb",{"type":29,"tag":88,"props":17476,"children":17477},{"style":122},[17478],{"type":34,"value":181},{"type":29,"tag":88,"props":17480,"children":17481},{"style":1974},[17482],{"type":34,"value":1977},{"type":29,"tag":88,"props":17484,"children":17485},{"style":1980},[17486],{"type":34,"value":11895},{"type":29,"tag":88,"props":17488,"children":17489},{"style":151},[17490],{"type":34,"value":8051},{"type":29,"tag":88,"props":17492,"children":17493},{"style":298},[17494],{"type":34,"value":3435},{"type":29,"tag":88,"props":17496,"children":17497},{"style":122},[17498],{"type":34,"value":306},{"type":29,"tag":88,"props":17500,"children":17501},{"style":122},[17502],{"type":34,"value":125},{"type":29,"tag":88,"props":17504,"children":17505},{"class":90,"line":767},[17506],{"type":29,"tag":88,"props":17507,"children":17508},{"style":95},[17509],{"type":34,"value":16992},{"type":29,"tag":88,"props":17511,"children":17512},{"class":90,"line":792},[17513,17517,17521,17525,17529,17533,17537,17541,17545,17549,17553,17557,17561],{"type":29,"tag":88,"props":17514,"children":17515},{"style":105},[17516],{"type":34,"value":415},{"type":29,"tag":88,"props":17518,"children":17519},{"style":157},[17520],{"type":34,"value":16811},{"type":29,"tag":88,"props":17522,"children":17523},{"style":122},[17524],{"type":34,"value":338},{"type":29,"tag":88,"props":17526,"children":17527},{"style":174},[17528],{"type":34,"value":17020},{"type":29,"tag":88,"props":17530,"children":17531},{"style":122},[17532],{"type":34,"value":181},{"type":29,"tag":88,"props":17534,"children":17535},{"style":184},[17536],{"type":34,"value":17029},{"type":29,"tag":88,"props":17538,"children":17539},{"style":163},[17540],{"type":34,"value":5485},{"type":29,"tag":88,"props":17542,"children":17543},{"style":157},[17544],{"type":34,"value":3435},{"type":29,"tag":88,"props":17546,"children":17547},{"style":122},[17548],{"type":34,"value":192},{"type":29,"tag":88,"props":17550,"children":17551},{"style":157},[17552],{"type":34,"value":16561},{"type":29,"tag":88,"props":17554,"children":17555},{"style":122},[17556],{"type":34,"value":338},{"type":29,"tag":88,"props":17558,"children":17559},{"style":157},[17560],{"type":34,"value":1225},{"type":29,"tag":88,"props":17562,"children":17563},{"style":122},[17564],{"type":34,"value":357},{"type":29,"tag":88,"props":17566,"children":17567},{"class":90,"line":817},[17568],{"type":29,"tag":88,"props":17569,"children":17570},{"style":122},[17571],{"type":34,"value":433},{"type":29,"tag":88,"props":17573,"children":17574},{"class":90,"line":825},[17575],{"type":29,"tag":88,"props":17576,"children":17577},{"style":122},[17578],{"type":34,"value":442},{"type":29,"tag":30,"props":17580,"children":17581},{},[17582],{"type":34,"value":17583},"Dans ce cas, le BFF web renvoie toutes les informations fournies par le backend principal, car l’interface web a besoin de ces détails.",{"type":29,"tag":6010,"props":17585,"children":17587},{"id":17586},"_4-configuration-spring-boot-pour-gérer-plusieurs-bff",[17588],{"type":34,"value":17589},"4. Configuration Spring Boot pour gérer plusieurs BFF",{"type":29,"tag":30,"props":17591,"children":17592},{},[17593,17595,17600],{"type":34,"value":17594},"Dans notre configuration Spring Boot, nous devons ajouter une gestion des requêtes HTTP avec ",{"type":29,"tag":84,"props":17596,"children":17598},{"className":17597},[],[17599],{"type":34,"value":16842},{"type":34,"value":17601},", qui permet à chaque BFF de communiquer avec le backend principal.",{"type":29,"tag":77,"props":17603,"children":17605},{"className":81,"code":17604,"language":80,"meta":8,"style":8},"@Bean\npublic RestTemplate restTemplate(RestTemplateBuilder builder) {\n    return builder.build();\n}\n",[17606],{"type":29,"tag":84,"props":17607,"children":17608},{"__ignoreMap":8},[17609,17621,17658,17681],{"type":29,"tag":88,"props":17610,"children":17611},{"class":90,"line":91},[17612,17616],{"type":29,"tag":88,"props":17613,"children":17614},{"style":1974},[17615],{"type":34,"value":1977},{"type":29,"tag":88,"props":17617,"children":17618},{"style":1980},[17619],{"type":34,"value":17620},"Bean\n",{"type":29,"tag":88,"props":17622,"children":17623},{"class":90,"line":101},[17624,17628,17632,17636,17640,17645,17650,17654],{"type":29,"tag":88,"props":17625,"children":17626},{"style":105},[17627],{"type":34,"value":108},{"type":29,"tag":88,"props":17629,"children":17630},{"style":151},[17631],{"type":34,"value":16806},{"type":29,"tag":88,"props":17633,"children":17634},{"style":174},[17635],{"type":34,"value":16811},{"type":29,"tag":88,"props":17637,"children":17638},{"style":122},[17639],{"type":34,"value":181},{"type":29,"tag":88,"props":17641,"children":17642},{"style":151},[17643],{"type":34,"value":17644},"RestTemplateBuilder",{"type":29,"tag":88,"props":17646,"children":17647},{"style":157},[17648],{"type":34,"value":17649}," builder",{"type":29,"tag":88,"props":17651,"children":17652},{"style":122},[17653],{"type":34,"value":306},{"type":29,"tag":88,"props":17655,"children":17656},{"style":122},[17657],{"type":34,"value":125},{"type":29,"tag":88,"props":17659,"children":17660},{"class":90,"line":128},[17661,17665,17669,17673,17677],{"type":29,"tag":88,"props":17662,"children":17663},{"style":105},[17664],{"type":34,"value":1579},{"type":29,"tag":88,"props":17666,"children":17667},{"style":157},[17668],{"type":34,"value":17649},{"type":29,"tag":88,"props":17670,"children":17671},{"style":122},[17672],{"type":34,"value":338},{"type":29,"tag":88,"props":17674,"children":17675},{"style":174},[17676],{"type":34,"value":9673},{"type":29,"tag":88,"props":17678,"children":17679},{"style":122},[17680],{"type":34,"value":1810},{"type":29,"tag":88,"props":17682,"children":17683},{"class":90,"line":137},[17684],{"type":29,"tag":88,"props":17685,"children":17686},{"style":122},[17687],{"type":34,"value":442},{"type":29,"tag":6010,"props":17689,"children":17691},{"id":17690},"_5-résultat-final",[17692],{"type":34,"value":17693},"5. Résultat final",{"type":29,"tag":30,"props":17695,"children":17696},{},[17697],{"type":34,"value":17698},"Nous avons maintenant deux BFF distincts :",{"type":29,"tag":453,"props":17700,"children":17701},{},[17702,17712],{"type":29,"tag":457,"props":17703,"children":17704},{},[17705,17710],{"type":29,"tag":447,"props":17706,"children":17707},{},[17708],{"type":34,"value":17709},"\u002Fbff\u002Fmobile\u002Fproducts\u002F{id}",{"type":34,"value":17711}," : Renvoie des données optimisées pour le mobile (nom et prix du produit).",{"type":29,"tag":457,"props":17713,"children":17714},{},[17715,17720],{"type":29,"tag":447,"props":17716,"children":17717},{},[17718],{"type":34,"value":17719},"\u002Fbff\u002Fweb\u002Fproducts\u002F{id}",{"type":34,"value":17721}," : Renvoie les données complètes pour l’application web.",{"type":29,"tag":30,"props":17723,"children":17724},{},[17725],{"type":34,"value":17726},"Chaque frontend reçoit les données spécifiques dont il a besoin, sans surcharge.",{"type":29,"tag":47,"props":17728,"children":17729},{},[],{"type":29,"tag":2288,"props":17731,"children":17733},{"cta":2290,"href":2291,"title":17732,"type":2293},"Vous voulez savoir quand un BFF se justifie vraiment, et quand il vous coûtera plus qu'il ne rapporte ?",[17734,17739],{"type":29,"tag":30,"props":17735,"children":17736},{},[17737],{"type":34,"value":17738},"Découper proprement une couche d'adaptation par frontend, ça ne s'apprend pas en recopiant un exemple : ça se travaille sur votre code, avec vos contraintes. En mentoring 1:1, je relis vos choix d'architecture avec vous, on trace ensemble la frontière entre adaptation et logique métier.",{"type":29,"tag":30,"props":17740,"children":17741},{},[17742],{"type":34,"value":17743},"Vous repartez avec le réflexe de placer la complexité au bon endroit, et de défendre vos décisions face à votre équipe.",{"type":29,"tag":51,"props":17745,"children":17747},{"id":17746},"bonnes-pratiques-pour-réussir-votre-backend-for-frontend-bff",[17748],{"type":34,"value":17749},"Bonnes pratiques pour réussir votre Backend for Frontend (BFF)",{"type":29,"tag":30,"props":17751,"children":17752},{},[17753],{"type":34,"value":17754},"L'exemple Java étant posé, quelques principes pour rendre votre architecture Backend for Frontend robuste, maintenable et évolutive.",{"type":29,"tag":6010,"props":17756,"children":17758},{"id":17757},"_1-séparer-les-responsabilités-de-chaque-bff",[17759],{"type":34,"value":17760},"1. Séparer les responsabilités de chaque BFF",{"type":29,"tag":30,"props":17762,"children":17763},{},[17764,17766,17771],{"type":34,"value":17765},"Chaque BFF doit rester centré sur les besoins de ",{"type":29,"tag":447,"props":17767,"children":17768},{},[17769],{"type":34,"value":17770},"son",{"type":34,"value":17772}," frontend spécifique. Je vous recommande d’éviter de mélanger les fonctionnalités pour différentes interfaces dans un même BFF, car cela entraînera à nouveau une surcharge et une complexité inutiles.",{"type":29,"tag":30,"props":17774,"children":17775},{},[17776,17781],{"type":29,"tag":447,"props":17777,"children":17778},{},[17779],{"type":34,"value":17780},"Astuce :",{"type":34,"value":17782}," Pensez à chaque BFF comme un service dédié à son frontend. Gardez son périmètre aussi restreint que possible pour faciliter les mises à jour et l’ajout de nouvelles fonctionnalités sans impacter les autres.",{"type":29,"tag":6010,"props":17784,"children":17786},{"id":17785},"_2-minimiser-la-logique-métier-dans-le-bff",[17787],{"type":34,"value":17788},"2. Minimiser la logique métier dans le BFF",{"type":29,"tag":30,"props":17790,"children":17791},{},[17792,17794,17798],{"type":34,"value":17793},"Le rôle du BFF est d’adapter les données, pas d’implémenter de la logique métier complexe. La logique métier doit rester dans le backend principal (ou dans d’autres services backend), afin de conserver une architecture claire et maintenable. Cette séparation entre la couche d’adaptation et le domaine métier est au cœur de la ",{"type":29,"tag":63,"props":17795,"children":17796},{"href":65},[17797],{"type":34,"value":68},{"type":34,"value":17799}," telle que la décrit Robert C. Martin : les dépendances doivent toujours pointer vers le domaine, jamais vers la périphérie.",{"type":29,"tag":30,"props":17801,"children":17802},{},[17803,17808],{"type":29,"tag":447,"props":17804,"children":17805},{},[17806],{"type":34,"value":17807},"Piège à éviter :",{"type":34,"value":17809}," Ne transformez pas votre BFF en un \"mini-backend\" avec des tonnes de logique métier. Cela risque de rendre votre couche BFF lourde et difficile à maintenir.",{"type":29,"tag":6010,"props":17811,"children":17813},{"id":17812},"_3-utiliser-des-outils-dagrégation-de-données",[17814],{"type":34,"value":17815},"3. Utiliser des outils d’agrégation de données",{"type":29,"tag":30,"props":17817,"children":17818},{},[17819,17821,17826],{"type":34,"value":17820},"Un BFF est particulièrement utile pour agréger des données provenant de plusieurs services backend. Si vous devez composer des données venant de différentes sources (par exemple, un service d’authentification, un service produit, et un service de recommandations), le BFF est l’endroit idéal pour faire cela. Dans une architecture ",{"type":29,"tag":63,"props":17822,"children":17823},{"href":10586},[17824],{"type":34,"value":17825},"microservices avec une base de données par service",{"type":34,"value":17827},", le BFF devient un point d’agrégation naturel pour les lectures cross-services.",{"type":29,"tag":30,"props":17829,"children":17830},{},[17831,17835,17837,17842,17844,17850],{"type":29,"tag":447,"props":17832,"children":17833},{},[17834],{"type":34,"value":17780},{"type":34,"value":17836}," Utilisez des outils comme ",{"type":29,"tag":84,"props":17838,"children":17840},{"className":17839},[],[17841],{"type":34,"value":16842},{"type":34,"value":17843}," ou des librairies de gestion des requêtes asynchrones (comme ",{"type":29,"tag":84,"props":17845,"children":17847},{"className":17846},[],[17848],{"type":34,"value":17849},"WebClient",{"type":34,"value":17851}," dans Spring) pour faciliter la gestion de ces multiples appels backend.",{"type":29,"tag":6010,"props":17853,"children":17855},{"id":17854},"_4-documenter-clairement-chaque-bff",[17856],{"type":34,"value":17857},"4. Documenter clairement chaque BFF",{"type":29,"tag":30,"props":17859,"children":17860},{},[17861],{"type":34,"value":17862},"Comme chaque BFF sert un frontend spécifique, la documentation est cruciale pour éviter les confusions entre les équipes frontend et backend. Je vous encourage à documenter clairement les endpoints et les types de réponses pour que les développeurs frontend sachent exactement ce qu’ils vont recevoir.",{"type":29,"tag":30,"props":17864,"children":17865},{},[17866,17870],{"type":29,"tag":447,"props":17867,"children":17868},{},[17869],{"type":34,"value":17780},{"type":34,"value":17871}," Utilisez des outils comme Swagger pour générer automatiquement de la documentation API et garder les différentes équipes synchronisées.",{"type":29,"tag":6010,"props":17873,"children":17875},{"id":17874},"_5-éviter-la-duplication-de-code",[17876],{"type":34,"value":17877},"5. Éviter la duplication de code",{"type":29,"tag":30,"props":17879,"children":17880},{},[17881],{"type":34,"value":17882},"Si plusieurs BFF doivent accéder à des données similaires, essayez de centraliser certaines fonctions ou modèles de données. Le risque avec plusieurs BFF est de créer des duplications inutiles dans le code. Utilisez des services partagés ou des bibliothèques communes pour éviter ces duplications.",{"type":29,"tag":30,"props":17884,"children":17885},{},[17886,17890],{"type":29,"tag":447,"props":17887,"children":17888},{},[17889],{"type":34,"value":17780},{"type":34,"value":17891}," Créez des services utilitaires ou des bibliothèques que chaque BFF peut réutiliser pour les parties communes, comme l’authentification, la gestion des erreurs, ou l’accès aux données partagées.",{"type":29,"tag":6010,"props":17893,"children":17895},{"id":17894},"_6-mettre-en-place-des-tests-automatisés",[17896],{"type":34,"value":17897},"6. Mettre en place des tests automatisés",{"type":29,"tag":30,"props":17899,"children":17900},{},[17901],{"type":34,"value":17902},"Comme tout service backend, chaque BFF doit être couvert par des tests unitaires et d’intégration. Assurez-vous de tester non seulement les réponses pour chaque frontend, mais aussi les interactions avec le backend principal.",{"type":29,"tag":30,"props":17904,"children":17905},{},[17906,17910],{"type":29,"tag":447,"props":17907,"children":17908},{},[17909],{"type":34,"value":17780},{"type":34,"value":17911}," Utilisez JUnit et MockMVC (ou d’autres frameworks de tests comme Mockito) pour simuler les appels aux backends et vérifier que chaque BFF renvoie bien les données attendues pour son frontend.",{"type":29,"tag":2288,"props":17913,"children":17915},{"cta":5629,"href":5630,"title":17914,"type":5632},"Le BFF n'est qu'une pratique parmi 100 pour garder une architecture saine",[17916,17921],{"type":29,"tag":30,"props":17917,"children":17918},{},[17919],{"type":34,"value":17920},"Savoir où placer une couche d'adaptation comme le BFF, c'est un réflexe craft. Le Craft Bundle réunit les 100 pratiques que j'applique pour coder propre : séparer les responsabilités, garder les dépendances orientées vers le domaine, tester ce qui compte.",{"type":29,"tag":30,"props":17922,"children":17923},{},[17924],{"type":34,"value":17925},"Ce sont les décisions d'architecture que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vues tenir en production sur plusieurs années.",{"type":29,"tag":47,"props":17927,"children":17928},{},[],{"type":29,"tag":51,"props":17930,"children":17932},{"id":17931},"faq-sur-le-backend-for-frontend-bff",[17933],{"type":34,"value":17934},"FAQ sur le Backend for Frontend (BFF)",{"type":29,"tag":5649,"props":17936,"children":17937},{},[17938,17943],{"type":29,"tag":5653,"props":17939,"children":17940},{},[17941],{"type":34,"value":17942},"1. Quelle est la différence entre un BFF et une API REST classique ?",{"type":29,"tag":30,"props":17944,"children":17945},{},[17946],{"type":34,"value":17947},"Contrairement à une API REST classique, qui tente de servir tous les types de frontends avec la même interface, un BFF est conçu spécifiquement pour un type de frontend. Il adapte les réponses pour répondre précisément aux besoins de chaque client (mobile, web, etc.), améliorant ainsi les performances et la simplicité d’utilisation pour chaque frontend.",{"type":29,"tag":5649,"props":17949,"children":17950},{},[17951,17956],{"type":29,"tag":5653,"props":17952,"children":17953},{},[17954],{"type":34,"value":17955},"2. Est-ce que cela ne rend pas l’architecture plus complexe ?",{"type":29,"tag":30,"props":17957,"children":17958},{},[17959],{"type":34,"value":17960},"Cela peut ajouter une couche de complexité, mais en contrepartie, cela simplifie la gestion des données et des interactions pour chaque frontend. La complexité est bien placée : au lieu de créer une API gigantesque qui essaie de tout faire, on la découpe en petits services dédiés, plus faciles à maintenir.",{"type":29,"tag":5649,"props":17962,"children":17963},{},[17964,17969],{"type":29,"tag":5653,"props":17965,"children":17966},{},[17967],{"type":34,"value":17968},"3. Dois-je créer un BFF pour chaque type d’application (iOS, Android, Web) ?",{"type":29,"tag":30,"props":17970,"children":17971},{},[17972],{"type":34,"value":17973},"Pas nécessairement. Cela dépend des besoins spécifiques de chaque frontend. Si plusieurs frontends ont des exigences similaires, vous pouvez utiliser un seul BFF pour ces clients. Mais s’ils ont des besoins très différents, un BFF par interface peut être plus pertinent.",{"type":29,"tag":5649,"props":17975,"children":17976},{},[17977,17982],{"type":29,"tag":5653,"props":17978,"children":17979},{},[17980],{"type":34,"value":17981},"4. Est-ce que le BFF impacte les performances globales ?",{"type":29,"tag":30,"props":17983,"children":17984},{},[17985],{"type":34,"value":17986},"En fait, il peut les améliorer. En personnalisant les réponses aux besoins spécifiques de chaque frontend, vous évitez d’envoyer des données inutiles et vous optimisez les requêtes. Cela réduit la consommation de bande passante, notamment pour les clients mobiles.",{"type":29,"tag":5649,"props":17988,"children":17989},{},[17990,17995],{"type":29,"tag":5653,"props":17991,"children":17992},{},[17993],{"type":34,"value":17994},"5. Est-ce que le BFF est une bonne solution pour les projets à petite échelle ?",{"type":29,"tag":30,"props":17996,"children":17997},{},[17998],{"type":34,"value":17999},"Si vous gérez une seule application frontend, vous n’aurez peut-être pas besoin d’un BFF. Mais dès que vous commencez à avoir plusieurs interfaces avec des besoins spécifiques, le BFF devient une solution intéressante, même pour des projets relativement modestes.",{"type":29,"tag":47,"props":18001,"children":18002},{},[],{"type":29,"tag":30,"props":18004,"children":18005},{},[18006],{"type":34,"value":18007},"Le BFF est un pattern qui débloque les équipes multi-frontend et leur redonne de la vélocité. Une seule condition : ne pas s’en servir comme prétexte pour glisser de la logique métier dans la mauvaise couche.",{"type":29,"tag":2288,"props":18009,"children":18012},{"cta":18010,"href":16240,"title":18011,"type":5755},"Télécharger la checklist gratuite →","Ressource gratuite : Votre équipe est-elle vraiment prête pour l'IA ?",[18013],{"type":29,"tag":30,"props":18014,"children":18015},{},[18016],{"type":34,"value":18017},"Les architectures multi-frontend comme le BFF sont la fondation des systèmes IA modernes. 25 questions, 5 dimensions, score de maturité IA sur 25 : identifiez vos 3 gaps critiques avant de scaler vos outils IA.",{"type":29,"tag":5763,"props":18019,"children":18020},{},[18021],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":18023},[18024,18028,18036,18044],{"id":16327,"depth":101,"text":16330,"children":18025},[18026,18027],{"id":16349,"depth":128,"text":16352},{"id":16398,"depth":128,"text":16401},{"id":16412,"depth":101,"text":16415,"children":18029},[18030,18031,18032,18033,18034,18035],{"id":16423,"depth":128,"text":16426},{"id":16448,"depth":128,"text":16451},{"id":16713,"depth":128,"text":16716},{"id":17256,"depth":128,"text":17259},{"id":17586,"depth":128,"text":17589},{"id":17690,"depth":128,"text":17693},{"id":17746,"depth":101,"text":17749,"children":18037},[18038,18039,18040,18041,18042,18043],{"id":17757,"depth":128,"text":17760},{"id":17785,"depth":128,"text":17788},{"id":17812,"depth":128,"text":17815},{"id":17854,"depth":128,"text":17857},{"id":17874,"depth":128,"text":17877},{"id":17894,"depth":128,"text":17897},{"id":17931,"depth":101,"text":17934},"content:fr:architecture-craft:backend-for-frontend-bff-java.md","fr\u002Farchitecture-craft\u002Fbackend-for-frontend-bff-java.md","fr\u002Farchitecture-craft\u002Fbackend-for-frontend-bff-java",{"_path":18049,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":18050,"description":18051,"id":3442,"date":18052,"listed":13,"nocomments":7,"hidden":7,"categories":18053,"tags":18054,"cover":18055,"readingTime":18056,"body":18060,"_type":5777,"_id":20918,"_source":5779,"_file":20919,"_stem":20920,"_extension":5782},"\u002Ffr\u002Farchitecture-craft\u002Fapi-first-openapi-spring-boot","API First, Avantages, Bonnes Pratiques et Intégration avec OpenAPI et Spring Boot","Découvrez les avantages de l'approche API First, comment utiliser OpenAPI pour documenter vos API et générer du code avec Spring Boot et Java. Guide complet avec...","2024-08-20",[6],[17,10685],"covers\u002Farticles\u002Fprincipe-api-first.jpg",{"text":16288,"minutes":18057,"time":18058,"words":18059},9.705,582300,1941,{"type":26,"children":18061,"toc":20896},[18062,18067,18077,18094,18111,18114,18120,18131,18137,18142,18148,18159,18165,18177,18183,18188,18194,18199,18202,18216,18222,18239,18245,18250,18570,18614,18620,18625,18658,18664,18682,18687,18867,20459,20465,20527,20532,20535,20541,20562,20568,20573,20579,20603,20608,20661,20667,20684,20690,20708,20714,20725,20728,20742,20745,20751,20770,20811,20828,20847,20860,20879,20889,20892],{"type":29,"tag":30,"props":18063,"children":18064},{},[18065],{"type":34,"value":18066},"Dès qu'un projet implique plusieurs équipes (front-end, back-end, gestion de produit), la cohérence devient un défi quotidien. Les API qui permettent la communication entre ces composants sont souvent développées en cours de route, après le démarrage du code. Conséquence : malentendus, bugs d'intégration et sprints engloutis dans les corrections.",{"type":29,"tag":30,"props":18068,"children":18069},{},[18070,18071,18075],{"type":34,"value":16051},{"type":29,"tag":447,"props":18072,"children":18073},{},[18074],{"type":34,"value":10736},{"type":34,"value":18076}," inverse la séquence. L'API n'est plus une réflexion après coup, elle devient l'élément central du projet. On la définit, la documente et la valide avant la première ligne de code. Toutes les équipes s'alignent dès le départ.",{"type":29,"tag":30,"props":18078,"children":18079},{},[18080,18082,18086,18088,18093],{"type":34,"value":18081},"Un argument courant contre l'API First est qu'elle complique le démarrage. Au contraire : elle simplifie la vie des développeurs sur la durée. Avec ",{"type":29,"tag":447,"props":18083,"children":18084},{},[18085],{"type":34,"value":11426},{"type":34,"value":18087},", vous définissez vos contrats de manière standardisée et générez automatiquement le code de votre projet ",{"type":29,"tag":447,"props":18089,"children":18090},{},[18091],{"type":34,"value":18092},"Spring Boot",{"type":34,"value":338},{"type":29,"tag":30,"props":18095,"children":18096},{},[18097,18099,18103,18105,18109],{"type":34,"value":18098},"Cet article montre comment l'approche API First avec ",{"type":29,"tag":447,"props":18100,"children":18101},{},[18102],{"type":34,"value":18092},{"type":34,"value":18104}," et ",{"type":29,"tag":447,"props":18106,"children":18107},{},[18108],{"type":34,"value":10755},{"type":34,"value":18110}," transforme la façon de développer. Exemples concrets de spécifications OpenAPI, génération de code, bonnes pratiques pour l'adopter en mission.",{"type":29,"tag":47,"props":18112,"children":18113},{},[],{"type":29,"tag":51,"props":18115,"children":18117},{"id":18116},"les-avantages-dune-approche-api-first",[18118],{"type":34,"value":18119},"Les avantages d'une approche API First",{"type":29,"tag":30,"props":18121,"children":18122},{},[18123,18125,18129],{"type":34,"value":18124},"L’adoption d'une approche ",{"type":29,"tag":447,"props":18126,"children":18127},{},[18128],{"type":34,"value":10736},{"type":34,"value":18130}," apporte des bénéfices concrets, surtout sur des projets complexes mêlant front-end et back-end. Les principaux gains observés en mission :",{"type":29,"tag":6010,"props":18132,"children":18134},{"id":18133},"_1-amélioration-de-la-collaboration-inter-équipes",[18135],{"type":34,"value":18136},"1. Amélioration de la collaboration inter-équipes",{"type":29,"tag":30,"props":18138,"children":18139},{},[18140],{"type":34,"value":18141},"Quand vous développez une API après avoir commencé à coder, il arrive souvent que les équipes front-end et back-end ne soient pas synchronisées. Les développeurs front-end peuvent créer des interfaces qui ne correspondent pas aux services disponibles, et les développeurs back-end peuvent ajouter des fonctionnalités qui ne sont pas encore exploitées par le front-end. Avec l’approche API First, tout le monde part d'une spécification commune. Cela veut dire que dès le début du projet, toutes les équipes ont une vue claire de ce à quoi ressemblera l'API finale. Cela améliore la communication et permet aux équipes de travailler en parallèle sans surprises.",{"type":29,"tag":6010,"props":18143,"children":18145},{"id":18144},"_2-documentation-centralisée-dès-le-début",[18146],{"type":34,"value":18147},"2. Documentation centralisée dès le début",{"type":29,"tag":30,"props":18149,"children":18150},{},[18151,18153,18157],{"type":34,"value":18152},"L’un des gros points faibles des projets traditionnels est la documentation. Souvent, elle est écrite en fin de projet, quand tout est déjà en place, voire pas du tout. Avec API First, la spécification de l’API (généralement en utilisant un format comme ",{"type":29,"tag":447,"props":18154,"children":18155},{},[18156],{"type":34,"value":11426},{"type":34,"value":18158},") devient la source de vérité. Elle est à la fois la documentation et le contrat entre les équipes. De plus, cette spécification est mise à jour tout au long du projet, ce qui signifie que tout changement dans l'API est immédiatement visible et répercuté. Cela élimine les mauvaises surprises et garantit que la documentation reste à jour en permanence.",{"type":29,"tag":6010,"props":18160,"children":18162},{"id":18161},"_3-réduction-des-erreurs-grâce-à-une-spécification-claire",[18163],{"type":34,"value":18164},"3. Réduction des erreurs grâce à une spécification claire",{"type":29,"tag":30,"props":18166,"children":18167},{},[18168,18170,18175],{"type":34,"value":18169},"Les erreurs dans la communication entre le front-end et le back-end sont courantes lorsque les API ne sont pas bien spécifiées ou changent en cours de route. Avec API First, ces erreurs sont réduites parce que tout est planifié et validé en amont. Chaque décision de conception d'API mérite d'être consignée dans un ",{"type":29,"tag":63,"props":18171,"children":18172},{"href":7292},[18173],{"type":34,"value":18174},"Architecture Decision Record",{"type":34,"value":18176}," pour que le contexte reste accessible à toute l'équipe. Par exemple, vous pouvez valider la spécification de votre API avant de commencer à écrire du code, et des outils comme OpenAPI permettent même de générer automatiquement des tests pour vérifier que le comportement de l’API correspond bien à ce qui a été défini.",{"type":29,"tag":6010,"props":18178,"children":18180},{"id":18179},"_4-gains-de-temps-à-long-terme",[18181],{"type":34,"value":18182},"4. Gains de temps à long terme",{"type":29,"tag":30,"props":18184,"children":18185},{},[18186],{"type":34,"value":18187},"Définir l'API d'abord paraît coûter du temps. Sur la durée, c'est l'inverse : une API validée avant le code réduit les bugs et les retours en arrière. La génération automatique de code à partir d'une spécification OpenAPI (illustrée plus loin avec Spring Boot) supprime une part du code manuel et libère l'équipe pour les fonctionnalités à valeur. J'ai observé ce gain dans des missions chez de grandes DSI bancaires : adopter l'OpenAPI Specification comme contrat d'équipe a réduit de moitié les allers-retours d'intégration entre front et back.",{"type":29,"tag":6010,"props":18189,"children":18191},{"id":18190},"_5-facilité-de-maintenance-et-dévolution",[18192],{"type":34,"value":18193},"5. Facilité de maintenance et d’évolution",{"type":29,"tag":30,"props":18195,"children":18196},{},[18197],{"type":34,"value":18198},"Une API bien documentée et centralisée anticipe les évolutions futures. Quand le moment vient de faire évoluer le projet, le contrat existant rend visibles les parties à ajuster, sans devoir tout redévelopper ni risquer de casser des fonctionnalités voisines.",{"type":29,"tag":47,"props":18200,"children":18201},{},[],{"type":29,"tag":2288,"props":18203,"children":18205},{"cta":2290,"href":2291,"title":18204,"type":2293},"Vous voulez concevoir vos contrats d'API avant d'écrire la première ligne ?",[18206,18211],{"type":29,"tag":30,"props":18207,"children":18208},{},[18209],{"type":34,"value":18210},"Penser une API comme un contrat, découper proprement ses endpoints, anticiper les versions : ça ne s'apprend pas en lisant un guide, ça se travaille sur votre vrai code. En mentoring 1:1, je relis vos specs OpenAPI et vos services Spring Boot avec vous, et je vous montre comment raisonner contrat-d'abord.",{"type":29,"tag":30,"props":18212,"children":18213},{},[18214],{"type":34,"value":18215},"Vous repartez avec les réflexes qui font qu'une API tient dans le temps, au lieu de coder puis documenter après coup.",{"type":29,"tag":51,"props":18217,"children":18219},{"id":18218},"openapi-le-standard-pour-api-first",[18220],{"type":34,"value":18221},"OpenAPI : Le standard pour API First",{"type":29,"tag":30,"props":18223,"children":18224},{},[18225,18227,18231,18233,18237],{"type":34,"value":18226},"Un pilier de l’approche ",{"type":29,"tag":447,"props":18228,"children":18229},{},[18230],{"type":34,"value":10736},{"type":34,"value":18232}," : s'appuyer sur des outils standardisés pour définir et documenter les API. ",{"type":29,"tag":447,"props":18234,"children":18235},{},[18236],{"type":34,"value":11426},{"type":34,"value":18238}," (anciennement Swagger) reste le standard de fait dans l'industrie. Il décrit chaque endpoint, les méthodes HTTP, les paramètres, les types de réponse. Cette spécification devient le contrat sur lequel toutes les équipes s’alignent.",{"type":29,"tag":6010,"props":18240,"children":18242},{"id":18241},"_1-présentation-dopenapi",[18243],{"type":34,"value":18244},"1. Présentation d’OpenAPI",{"type":29,"tag":30,"props":18246,"children":18247},{},[18248],{"type":34,"value":18249},"OpenAPI est un format de fichier (souvent en JSON ou en YAML) qui décrit votre API. Voici un exemple simple d’une spécification OpenAPI pour un service de gestion d’utilisateurs :",{"type":29,"tag":77,"props":18251,"children":18255},{"className":18252,"code":18253,"language":18254,"meta":8,"style":8},"language-yaml shiki shiki-themes catppuccin-frappe github-dark","openapi: 3.0.0\ninfo:\n  title: User Management API\n  version: 1.0.0\npaths:\n  \u002Fusers:\n    get:\n      summary: Get a list of users\n      responses:\n        '200':\n          description: A JSON array of user objects\n          content:\n            application\u002Fjson:\n              schema:\n                type: array\n                items:\n                  type: object\n                  properties:\n                    id:\n                      type: integer\n                    name:\n                      type: string\n","yaml",[18256],{"type":29,"tag":84,"props":18257,"children":18258},{"__ignoreMap":8},[18259,18278,18291,18308,18325,18337,18349,18361,18378,18390,18402,18419,18431,18443,18455,18472,18484,18501,18513,18525,18542,18554],{"type":29,"tag":88,"props":18260,"children":18261},{"class":90,"line":91},[18262,18268,18273],{"type":29,"tag":88,"props":18263,"children":18265},{"style":18264},"--shiki-default:#8CAAEE;--shiki-dark:#85E89D",[18266],{"type":34,"value":18267},"openapi",{"type":29,"tag":88,"props":18269,"children":18270},{"style":6165},[18271],{"type":34,"value":18272},":",{"type":29,"tag":88,"props":18274,"children":18275},{"style":195},[18276],{"type":34,"value":18277}," 3.0.0\n",{"type":29,"tag":88,"props":18279,"children":18280},{"class":90,"line":101},[18281,18286],{"type":29,"tag":88,"props":18282,"children":18283},{"style":18264},[18284],{"type":34,"value":18285},"info",{"type":29,"tag":88,"props":18287,"children":18288},{"style":6165},[18289],{"type":34,"value":18290},":\n",{"type":29,"tag":88,"props":18292,"children":18293},{"class":90,"line":128},[18294,18299,18303],{"type":29,"tag":88,"props":18295,"children":18296},{"style":18264},[18297],{"type":34,"value":18298},"  title",{"type":29,"tag":88,"props":18300,"children":18301},{"style":6165},[18302],{"type":34,"value":18272},{"type":29,"tag":88,"props":18304,"children":18305},{"style":184},[18306],{"type":34,"value":18307}," User Management API\n",{"type":29,"tag":88,"props":18309,"children":18310},{"class":90,"line":137},[18311,18316,18320],{"type":29,"tag":88,"props":18312,"children":18313},{"style":18264},[18314],{"type":34,"value":18315},"  version",{"type":29,"tag":88,"props":18317,"children":18318},{"style":6165},[18319],{"type":34,"value":18272},{"type":29,"tag":88,"props":18321,"children":18322},{"style":195},[18323],{"type":34,"value":18324}," 1.0.0\n",{"type":29,"tag":88,"props":18326,"children":18327},{"class":90,"line":211},[18328,18333],{"type":29,"tag":88,"props":18329,"children":18330},{"style":18264},[18331],{"type":34,"value":18332},"paths",{"type":29,"tag":88,"props":18334,"children":18335},{"style":6165},[18336],{"type":34,"value":18290},{"type":29,"tag":88,"props":18338,"children":18339},{"class":90,"line":262},[18340,18345],{"type":29,"tag":88,"props":18341,"children":18342},{"style":18264},[18343],{"type":34,"value":18344},"  \u002Fusers",{"type":29,"tag":88,"props":18346,"children":18347},{"style":6165},[18348],{"type":34,"value":18290},{"type":29,"tag":88,"props":18350,"children":18351},{"class":90,"line":270},[18352,18357],{"type":29,"tag":88,"props":18353,"children":18354},{"style":18264},[18355],{"type":34,"value":18356},"    get",{"type":29,"tag":88,"props":18358,"children":18359},{"style":6165},[18360],{"type":34,"value":18290},{"type":29,"tag":88,"props":18362,"children":18363},{"class":90,"line":313},[18364,18369,18373],{"type":29,"tag":88,"props":18365,"children":18366},{"style":18264},[18367],{"type":34,"value":18368},"      summary",{"type":29,"tag":88,"props":18370,"children":18371},{"style":6165},[18372],{"type":34,"value":18272},{"type":29,"tag":88,"props":18374,"children":18375},{"style":184},[18376],{"type":34,"value":18377}," Get a list of users\n",{"type":29,"tag":88,"props":18379,"children":18380},{"class":90,"line":360},[18381,18386],{"type":29,"tag":88,"props":18382,"children":18383},{"style":18264},[18384],{"type":34,"value":18385},"      responses",{"type":29,"tag":88,"props":18387,"children":18388},{"style":6165},[18389],{"type":34,"value":18290},{"type":29,"tag":88,"props":18391,"children":18392},{"class":90,"line":409},[18393,18398],{"type":29,"tag":88,"props":18394,"children":18395},{"style":184},[18396],{"type":34,"value":18397},"        '200'",{"type":29,"tag":88,"props":18399,"children":18400},{"style":6165},[18401],{"type":34,"value":18290},{"type":29,"tag":88,"props":18403,"children":18404},{"class":90,"line":427},[18405,18410,18414],{"type":29,"tag":88,"props":18406,"children":18407},{"style":18264},[18408],{"type":34,"value":18409},"          description",{"type":29,"tag":88,"props":18411,"children":18412},{"style":6165},[18413],{"type":34,"value":18272},{"type":29,"tag":88,"props":18415,"children":18416},{"style":184},[18417],{"type":34,"value":18418}," A JSON array of user objects\n",{"type":29,"tag":88,"props":18420,"children":18421},{"class":90,"line":436},[18422,18427],{"type":29,"tag":88,"props":18423,"children":18424},{"style":18264},[18425],{"type":34,"value":18426},"          content",{"type":29,"tag":88,"props":18428,"children":18429},{"style":6165},[18430],{"type":34,"value":18290},{"type":29,"tag":88,"props":18432,"children":18433},{"class":90,"line":767},[18434,18439],{"type":29,"tag":88,"props":18435,"children":18436},{"style":18264},[18437],{"type":34,"value":18438},"            application\u002Fjson",{"type":29,"tag":88,"props":18440,"children":18441},{"style":6165},[18442],{"type":34,"value":18290},{"type":29,"tag":88,"props":18444,"children":18445},{"class":90,"line":792},[18446,18451],{"type":29,"tag":88,"props":18447,"children":18448},{"style":18264},[18449],{"type":34,"value":18450},"              schema",{"type":29,"tag":88,"props":18452,"children":18453},{"style":6165},[18454],{"type":34,"value":18290},{"type":29,"tag":88,"props":18456,"children":18457},{"class":90,"line":817},[18458,18463,18467],{"type":29,"tag":88,"props":18459,"children":18460},{"style":18264},[18461],{"type":34,"value":18462},"                type",{"type":29,"tag":88,"props":18464,"children":18465},{"style":6165},[18466],{"type":34,"value":18272},{"type":29,"tag":88,"props":18468,"children":18469},{"style":184},[18470],{"type":34,"value":18471}," array\n",{"type":29,"tag":88,"props":18473,"children":18474},{"class":90,"line":825},[18475,18480],{"type":29,"tag":88,"props":18476,"children":18477},{"style":18264},[18478],{"type":34,"value":18479},"                items",{"type":29,"tag":88,"props":18481,"children":18482},{"style":6165},[18483],{"type":34,"value":18290},{"type":29,"tag":88,"props":18485,"children":18486},{"class":90,"line":869},[18487,18492,18496],{"type":29,"tag":88,"props":18488,"children":18489},{"style":18264},[18490],{"type":34,"value":18491},"                  type",{"type":29,"tag":88,"props":18493,"children":18494},{"style":6165},[18495],{"type":34,"value":18272},{"type":29,"tag":88,"props":18497,"children":18498},{"style":184},[18499],{"type":34,"value":18500}," object\n",{"type":29,"tag":88,"props":18502,"children":18503},{"class":90,"line":900},[18504,18509],{"type":29,"tag":88,"props":18505,"children":18506},{"style":18264},[18507],{"type":34,"value":18508},"                  properties",{"type":29,"tag":88,"props":18510,"children":18511},{"style":6165},[18512],{"type":34,"value":18290},{"type":29,"tag":88,"props":18514,"children":18515},{"class":90,"line":929},[18516,18521],{"type":29,"tag":88,"props":18517,"children":18518},{"style":18264},[18519],{"type":34,"value":18520},"                    id",{"type":29,"tag":88,"props":18522,"children":18523},{"style":6165},[18524],{"type":34,"value":18290},{"type":29,"tag":88,"props":18526,"children":18527},{"class":90,"line":937},[18528,18533,18537],{"type":29,"tag":88,"props":18529,"children":18530},{"style":18264},[18531],{"type":34,"value":18532},"                      type",{"type":29,"tag":88,"props":18534,"children":18535},{"style":6165},[18536],{"type":34,"value":18272},{"type":29,"tag":88,"props":18538,"children":18539},{"style":184},[18540],{"type":34,"value":18541}," integer\n",{"type":29,"tag":88,"props":18543,"children":18544},{"class":90,"line":945},[18545,18550],{"type":29,"tag":88,"props":18546,"children":18547},{"style":18264},[18548],{"type":34,"value":18549},"                    name",{"type":29,"tag":88,"props":18551,"children":18552},{"style":6165},[18553],{"type":34,"value":18290},{"type":29,"tag":88,"props":18555,"children":18556},{"class":90,"line":981},[18557,18561,18565],{"type":29,"tag":88,"props":18558,"children":18559},{"style":18264},[18560],{"type":34,"value":18532},{"type":29,"tag":88,"props":18562,"children":18563},{"style":6165},[18564],{"type":34,"value":18272},{"type":29,"tag":88,"props":18566,"children":18567},{"style":184},[18568],{"type":34,"value":18569}," string\n",{"type":29,"tag":30,"props":18571,"children":18572},{},[18573,18575,18581,18583,18589,18590,18596,18598,18604,18606,18612],{"type":34,"value":18574},"Dans cet exemple, nous avons une API qui gère une collection d’utilisateurs avec un endpoint ",{"type":29,"tag":84,"props":18576,"children":18578},{"className":18577},[],[18579],{"type":34,"value":18580},"\u002Fusers",{"type":34,"value":18582}," qui retourne une liste d’utilisateurs en JSON. La spécification définit les types de données (comme ",{"type":29,"tag":84,"props":18584,"children":18586},{"className":18585},[],[18587],{"type":34,"value":18588},"integer",{"type":34,"value":5730},{"type":29,"tag":84,"props":18591,"children":18593},{"className":18592},[],[18594],{"type":34,"value":18595},"string",{"type":34,"value":18597},"), les méthodes HTTP (ici ",{"type":29,"tag":84,"props":18599,"children":18601},{"className":18600},[],[18602],{"type":34,"value":18603},"GET",{"type":34,"value":18605},"), ainsi que les réponses possibles (un code HTTP ",{"type":29,"tag":84,"props":18607,"children":18609},{"className":18608},[],[18610],{"type":34,"value":18611},"200",{"type":34,"value":18613}," pour indiquer une réponse réussie).",{"type":29,"tag":6010,"props":18615,"children":18617},{"id":18616},"_2-avantages-dopenapi-dans-lapproche-api-first",[18618],{"type":34,"value":18619},"2. Avantages d'OpenAPI dans l'approche API First",{"type":29,"tag":30,"props":18621,"children":18622},{},[18623],{"type":34,"value":18624},"L’utilisation d’OpenAPI dans une approche API First présente plusieurs avantages :",{"type":29,"tag":453,"props":18626,"children":18627},{},[18628,18638,18648],{"type":29,"tag":457,"props":18629,"children":18630},{},[18631,18636],{"type":29,"tag":447,"props":18632,"children":18633},{},[18634],{"type":34,"value":18635},"Clarté et transparence",{"type":34,"value":18637}," : La spécification sert de documentation unique et centralisée que toutes les équipes peuvent consulter.",{"type":29,"tag":457,"props":18639,"children":18640},{},[18641,18646],{"type":29,"tag":447,"props":18642,"children":18643},{},[18644],{"type":34,"value":18645},"Validations automatiques",{"type":34,"value":18647}," : Des outils existent pour valider que les appels à l’API respectent la spécification.",{"type":29,"tag":457,"props":18649,"children":18650},{},[18651,18656],{"type":29,"tag":447,"props":18652,"children":18653},{},[18654],{"type":34,"value":18655},"Génération de code",{"type":34,"value":18657}," : OpenAPI génère automatiquement du code pour plusieurs langages, ce qui accélère le développement.",{"type":29,"tag":6010,"props":18659,"children":18661},{"id":18660},"_3-utilisation-dopenapi-dans-un-projet-spring-boot",[18662],{"type":34,"value":18663},"3. Utilisation d’OpenAPI dans un projet Spring Boot",{"type":29,"tag":30,"props":18665,"children":18666},{},[18667,18669,18673,18675,18680],{"type":34,"value":18668},"Intégrer ",{"type":29,"tag":447,"props":18670,"children":18671},{},[18672],{"type":34,"value":11426},{"type":34,"value":18674}," dans un projet Spring Boot est simple grâce à des bibliothèques comme ",{"type":29,"tag":447,"props":18676,"children":18677},{},[18678],{"type":34,"value":18679},"springdoc-openapi",{"type":34,"value":18681},", qui génèrent automatiquement une spécification OpenAPI à partir de votre code Java.",{"type":29,"tag":30,"props":18683,"children":18684},{},[18685],{"type":34,"value":18686},"Pour configurer Spring Boot afin de générer une documentation OpenAPI :",{"type":29,"tag":11367,"props":18688,"children":18689},{},[18690,18844,18856],{"type":29,"tag":457,"props":18691,"children":18692},{},[18693,18695,18701,18702],{"type":34,"value":18694},"Ajoutez la dépendance suivante à votre fichier ",{"type":29,"tag":84,"props":18696,"children":18698},{"className":18697},[],[18699],{"type":34,"value":18700},"pom.xml",{"type":34,"value":5854},{"type":29,"tag":77,"props":18703,"children":18707},{"className":18704,"code":18705,"language":18706,"meta":8,"style":8},"language-xml shiki shiki-themes catppuccin-frappe github-dark","\u003Cdependency>\n    \u003CgroupId>org.springdoc\u003C\u002FgroupId>\n    \u003CartifactId>springdoc-openapi-ui\u003C\u002FartifactId>\n    \u003Cversion>1.5.12\u003C\u002Fversion>\n\u003C\u002Fdependency>\n","xml",[18708],{"type":29,"tag":84,"props":18709,"children":18710},{"__ignoreMap":8},[18711,18728,18763,18796,18829],{"type":29,"tag":88,"props":18712,"children":18713},{"class":90,"line":91},[18714,18718,18723],{"type":29,"tag":88,"props":18715,"children":18716},{"style":6165},[18717],{"type":34,"value":1683},{"type":29,"tag":88,"props":18719,"children":18720},{"style":18264},[18721],{"type":34,"value":18722},"dependency",{"type":29,"tag":88,"props":18724,"children":18725},{"style":6165},[18726],{"type":34,"value":18727},">\n",{"type":29,"tag":88,"props":18729,"children":18730},{"class":90,"line":101},[18731,18736,18741,18745,18750,18755,18759],{"type":29,"tag":88,"props":18732,"children":18733},{"style":6165},[18734],{"type":34,"value":18735},"    \u003C",{"type":29,"tag":88,"props":18737,"children":18738},{"style":18264},[18739],{"type":34,"value":18740},"groupId",{"type":29,"tag":88,"props":18742,"children":18743},{"style":6165},[18744],{"type":34,"value":1701},{"type":29,"tag":88,"props":18746,"children":18747},{"style":157},[18748],{"type":34,"value":18749},"org.springdoc",{"type":29,"tag":88,"props":18751,"children":18752},{"style":6165},[18753],{"type":34,"value":18754},"\u003C\u002F",{"type":29,"tag":88,"props":18756,"children":18757},{"style":18264},[18758],{"type":34,"value":18740},{"type":29,"tag":88,"props":18760,"children":18761},{"style":6165},[18762],{"type":34,"value":18727},{"type":29,"tag":88,"props":18764,"children":18765},{"class":90,"line":128},[18766,18770,18775,18779,18784,18788,18792],{"type":29,"tag":88,"props":18767,"children":18768},{"style":6165},[18769],{"type":34,"value":18735},{"type":29,"tag":88,"props":18771,"children":18772},{"style":18264},[18773],{"type":34,"value":18774},"artifactId",{"type":29,"tag":88,"props":18776,"children":18777},{"style":6165},[18778],{"type":34,"value":1701},{"type":29,"tag":88,"props":18780,"children":18781},{"style":157},[18782],{"type":34,"value":18783},"springdoc-openapi-ui",{"type":29,"tag":88,"props":18785,"children":18786},{"style":6165},[18787],{"type":34,"value":18754},{"type":29,"tag":88,"props":18789,"children":18790},{"style":18264},[18791],{"type":34,"value":18774},{"type":29,"tag":88,"props":18793,"children":18794},{"style":6165},[18795],{"type":34,"value":18727},{"type":29,"tag":88,"props":18797,"children":18798},{"class":90,"line":137},[18799,18803,18808,18812,18817,18821,18825],{"type":29,"tag":88,"props":18800,"children":18801},{"style":6165},[18802],{"type":34,"value":18735},{"type":29,"tag":88,"props":18804,"children":18805},{"style":18264},[18806],{"type":34,"value":18807},"version",{"type":29,"tag":88,"props":18809,"children":18810},{"style":6165},[18811],{"type":34,"value":1701},{"type":29,"tag":88,"props":18813,"children":18814},{"style":157},[18815],{"type":34,"value":18816},"1.5.12",{"type":29,"tag":88,"props":18818,"children":18819},{"style":6165},[18820],{"type":34,"value":18754},{"type":29,"tag":88,"props":18822,"children":18823},{"style":18264},[18824],{"type":34,"value":18807},{"type":29,"tag":88,"props":18826,"children":18827},{"style":6165},[18828],{"type":34,"value":18727},{"type":29,"tag":88,"props":18830,"children":18831},{"class":90,"line":211},[18832,18836,18840],{"type":29,"tag":88,"props":18833,"children":18834},{"style":6165},[18835],{"type":34,"value":18754},{"type":29,"tag":88,"props":18837,"children":18838},{"style":18264},[18839],{"type":34,"value":18722},{"type":29,"tag":88,"props":18841,"children":18842},{"style":6165},[18843],{"type":34,"value":18727},{"type":29,"tag":457,"props":18845,"children":18846},{},[18847,18849,18855],{"type":34,"value":18848},"Lancez votre projet Spring Boot. Une interface Swagger est automatiquement disponible à l’URL ",{"type":29,"tag":84,"props":18850,"children":18852},{"className":18851},[],[18853],{"type":34,"value":18854},"http:\u002F\u002Flocalhost:8080\u002Fswagger-ui.html",{"type":34,"value":338},{"type":29,"tag":457,"props":18857,"children":18858},{},[18859,18861,18865],{"type":34,"value":18860},"Exemple de contrôleur Spring Boot documenté par OpenAPI, avec des annotations ",{"type":29,"tag":447,"props":18862,"children":18863},{},[18864],{"type":34,"value":11420},{"type":34,"value":18866}," pour enrichir la documentation :",{"type":29,"tag":77,"props":18868,"children":18870},{"className":81,"code":18869,"language":80,"meta":8,"style":8},"import io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\nimport java.util.List;\n\n@RestController\n@RequestMapping(\"\u002Fapi\u002Fusers\")\npublic class UserController {\n\n    @Operation(summary = \"Obtenir la liste des utilisateurs\")\n    @ApiResponses(value = {\n        @ApiResponse(responseCode = \"200\", description = \"Liste des utilisateurs trouvée\",\n            content = { @Content(mediaType = \"application\u002Fjson\",\n            schema = @Schema(implementation = User.class)) }),\n        @ApiResponse(responseCode = \"400\", description = \"Requête invalide\",\n            content = @Content),\n        @ApiResponse(responseCode = \"404\", description = \"Utilisateurs non trouvés\",\n            content = @Content) })\n    @GetMapping\n    public List\u003CUser> getUsers() {\n        \u002F\u002F Simuler une liste d'utilisateurs\n        return List.of(new User(1, \"Alice\"), new User(2, \"Bob\"));\n    }\n\n}\n\nclass User {\n    private int id;\n    private String name;\n\n    public User(int id, String name) {\n        this.id = id\n\n;\n        this.name = name;\n    }\n\n    \u002F\u002F Getters et setters\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n}\n",[18871],{"type":29,"tag":84,"props":18872,"children":18873},{"__ignoreMap":8},[18874,18936,19001,19065,19130,19194,19254,19309,19365,19372,19406,19413,19424,19448,19467,19474,19506,19534,19586,19633,19688,19737,19761,19810,19838,19850,19887,19895,19977,19984,19991,19998,20005,20020,20040,20060,20067,20111,20135,20142,20149,20177,20184,20191,20199,20223,20238,20245,20252,20288,20315,20322,20329,20353,20368,20375,20382,20418,20445,20452],{"type":29,"tag":88,"props":18875,"children":18876},{"class":90,"line":91},[18877,18882,18887,18891,18896,18900,18905,18909,18914,18918,18923,18927,18932],{"type":29,"tag":88,"props":18878,"children":18879},{"style":105},[18880],{"type":34,"value":18881},"import",{"type":29,"tag":88,"props":18883,"children":18884},{"style":157},[18885],{"type":34,"value":18886}," io",{"type":29,"tag":88,"props":18888,"children":18889},{"style":122},[18890],{"type":34,"value":338},{"type":29,"tag":88,"props":18892,"children":18893},{"style":157},[18894],{"type":34,"value":18895},"swagger",{"type":29,"tag":88,"props":18897,"children":18898},{"style":122},[18899],{"type":34,"value":338},{"type":29,"tag":88,"props":18901,"children":18902},{"style":157},[18903],{"type":34,"value":18904},"v3",{"type":29,"tag":88,"props":18906,"children":18907},{"style":122},[18908],{"type":34,"value":338},{"type":29,"tag":88,"props":18910,"children":18911},{"style":157},[18912],{"type":34,"value":18913},"oas",{"type":29,"tag":88,"props":18915,"children":18916},{"style":122},[18917],{"type":34,"value":338},{"type":29,"tag":88,"props":18919,"children":18920},{"style":157},[18921],{"type":34,"value":18922},"annotations",{"type":29,"tag":88,"props":18924,"children":18925},{"style":122},[18926],{"type":34,"value":338},{"type":29,"tag":88,"props":18928,"children":18929},{"style":157},[18930],{"type":34,"value":18931},"Operation",{"type":29,"tag":88,"props":18933,"children":18934},{"style":122},[18935],{"type":34,"value":424},{"type":29,"tag":88,"props":18937,"children":18938},{"class":90,"line":101},[18939,18943,18947,18951,18955,18959,18963,18967,18971,18975,18979,18983,18988,18992,18997],{"type":29,"tag":88,"props":18940,"children":18941},{"style":105},[18942],{"type":34,"value":18881},{"type":29,"tag":88,"props":18944,"children":18945},{"style":157},[18946],{"type":34,"value":18886},{"type":29,"tag":88,"props":18948,"children":18949},{"style":122},[18950],{"type":34,"value":338},{"type":29,"tag":88,"props":18952,"children":18953},{"style":157},[18954],{"type":34,"value":18895},{"type":29,"tag":88,"props":18956,"children":18957},{"style":122},[18958],{"type":34,"value":338},{"type":29,"tag":88,"props":18960,"children":18961},{"style":157},[18962],{"type":34,"value":18904},{"type":29,"tag":88,"props":18964,"children":18965},{"style":122},[18966],{"type":34,"value":338},{"type":29,"tag":88,"props":18968,"children":18969},{"style":157},[18970],{"type":34,"value":18913},{"type":29,"tag":88,"props":18972,"children":18973},{"style":122},[18974],{"type":34,"value":338},{"type":29,"tag":88,"props":18976,"children":18977},{"style":157},[18978],{"type":34,"value":18922},{"type":29,"tag":88,"props":18980,"children":18981},{"style":122},[18982],{"type":34,"value":338},{"type":29,"tag":88,"props":18984,"children":18985},{"style":157},[18986],{"type":34,"value":18987},"media",{"type":29,"tag":88,"props":18989,"children":18990},{"style":122},[18991],{"type":34,"value":338},{"type":29,"tag":88,"props":18993,"children":18994},{"style":157},[18995],{"type":34,"value":18996},"Content",{"type":29,"tag":88,"props":18998,"children":18999},{"style":122},[19000],{"type":34,"value":424},{"type":29,"tag":88,"props":19002,"children":19003},{"class":90,"line":128},[19004,19008,19012,19016,19020,19024,19028,19032,19036,19040,19044,19048,19052,19056,19061],{"type":29,"tag":88,"props":19005,"children":19006},{"style":105},[19007],{"type":34,"value":18881},{"type":29,"tag":88,"props":19009,"children":19010},{"style":157},[19011],{"type":34,"value":18886},{"type":29,"tag":88,"props":19013,"children":19014},{"style":122},[19015],{"type":34,"value":338},{"type":29,"tag":88,"props":19017,"children":19018},{"style":157},[19019],{"type":34,"value":18895},{"type":29,"tag":88,"props":19021,"children":19022},{"style":122},[19023],{"type":34,"value":338},{"type":29,"tag":88,"props":19025,"children":19026},{"style":157},[19027],{"type":34,"value":18904},{"type":29,"tag":88,"props":19029,"children":19030},{"style":122},[19031],{"type":34,"value":338},{"type":29,"tag":88,"props":19033,"children":19034},{"style":157},[19035],{"type":34,"value":18913},{"type":29,"tag":88,"props":19037,"children":19038},{"style":122},[19039],{"type":34,"value":338},{"type":29,"tag":88,"props":19041,"children":19042},{"style":157},[19043],{"type":34,"value":18922},{"type":29,"tag":88,"props":19045,"children":19046},{"style":122},[19047],{"type":34,"value":338},{"type":29,"tag":88,"props":19049,"children":19050},{"style":157},[19051],{"type":34,"value":18987},{"type":29,"tag":88,"props":19053,"children":19054},{"style":122},[19055],{"type":34,"value":338},{"type":29,"tag":88,"props":19057,"children":19058},{"style":157},[19059],{"type":34,"value":19060},"Schema",{"type":29,"tag":88,"props":19062,"children":19063},{"style":122},[19064],{"type":34,"value":424},{"type":29,"tag":88,"props":19066,"children":19067},{"class":90,"line":137},[19068,19072,19076,19080,19084,19088,19092,19096,19100,19104,19108,19112,19117,19121,19126],{"type":29,"tag":88,"props":19069,"children":19070},{"style":105},[19071],{"type":34,"value":18881},{"type":29,"tag":88,"props":19073,"children":19074},{"style":157},[19075],{"type":34,"value":18886},{"type":29,"tag":88,"props":19077,"children":19078},{"style":122},[19079],{"type":34,"value":338},{"type":29,"tag":88,"props":19081,"children":19082},{"style":157},[19083],{"type":34,"value":18895},{"type":29,"tag":88,"props":19085,"children":19086},{"style":122},[19087],{"type":34,"value":338},{"type":29,"tag":88,"props":19089,"children":19090},{"style":157},[19091],{"type":34,"value":18904},{"type":29,"tag":88,"props":19093,"children":19094},{"style":122},[19095],{"type":34,"value":338},{"type":29,"tag":88,"props":19097,"children":19098},{"style":157},[19099],{"type":34,"value":18913},{"type":29,"tag":88,"props":19101,"children":19102},{"style":122},[19103],{"type":34,"value":338},{"type":29,"tag":88,"props":19105,"children":19106},{"style":157},[19107],{"type":34,"value":18922},{"type":29,"tag":88,"props":19109,"children":19110},{"style":122},[19111],{"type":34,"value":338},{"type":29,"tag":88,"props":19113,"children":19114},{"style":157},[19115],{"type":34,"value":19116},"responses",{"type":29,"tag":88,"props":19118,"children":19119},{"style":122},[19120],{"type":34,"value":338},{"type":29,"tag":88,"props":19122,"children":19123},{"style":157},[19124],{"type":34,"value":19125},"ApiResponse",{"type":29,"tag":88,"props":19127,"children":19128},{"style":122},[19129],{"type":34,"value":424},{"type":29,"tag":88,"props":19131,"children":19132},{"class":90,"line":211},[19133,19137,19141,19145,19149,19153,19157,19161,19165,19169,19173,19177,19181,19185,19190],{"type":29,"tag":88,"props":19134,"children":19135},{"style":105},[19136],{"type":34,"value":18881},{"type":29,"tag":88,"props":19138,"children":19139},{"style":157},[19140],{"type":34,"value":18886},{"type":29,"tag":88,"props":19142,"children":19143},{"style":122},[19144],{"type":34,"value":338},{"type":29,"tag":88,"props":19146,"children":19147},{"style":157},[19148],{"type":34,"value":18895},{"type":29,"tag":88,"props":19150,"children":19151},{"style":122},[19152],{"type":34,"value":338},{"type":29,"tag":88,"props":19154,"children":19155},{"style":157},[19156],{"type":34,"value":18904},{"type":29,"tag":88,"props":19158,"children":19159},{"style":122},[19160],{"type":34,"value":338},{"type":29,"tag":88,"props":19162,"children":19163},{"style":157},[19164],{"type":34,"value":18913},{"type":29,"tag":88,"props":19166,"children":19167},{"style":122},[19168],{"type":34,"value":338},{"type":29,"tag":88,"props":19170,"children":19171},{"style":157},[19172],{"type":34,"value":18922},{"type":29,"tag":88,"props":19174,"children":19175},{"style":122},[19176],{"type":34,"value":338},{"type":29,"tag":88,"props":19178,"children":19179},{"style":157},[19180],{"type":34,"value":19116},{"type":29,"tag":88,"props":19182,"children":19183},{"style":122},[19184],{"type":34,"value":338},{"type":29,"tag":88,"props":19186,"children":19187},{"style":157},[19188],{"type":34,"value":19189},"ApiResponses",{"type":29,"tag":88,"props":19191,"children":19192},{"style":122},[19193],{"type":34,"value":424},{"type":29,"tag":88,"props":19195,"children":19196},{"class":90,"line":262},[19197,19201,19206,19210,19215,19219,19224,19228,19233,19237,19242,19246,19250],{"type":29,"tag":88,"props":19198,"children":19199},{"style":105},[19200],{"type":34,"value":18881},{"type":29,"tag":88,"props":19202,"children":19203},{"style":157},[19204],{"type":34,"value":19205}," org",{"type":29,"tag":88,"props":19207,"children":19208},{"style":122},[19209],{"type":34,"value":338},{"type":29,"tag":88,"props":19211,"children":19212},{"style":157},[19213],{"type":34,"value":19214},"springframework",{"type":29,"tag":88,"props":19216,"children":19217},{"style":122},[19218],{"type":34,"value":338},{"type":29,"tag":88,"props":19220,"children":19221},{"style":157},[19222],{"type":34,"value":19223},"web",{"type":29,"tag":88,"props":19225,"children":19226},{"style":122},[19227],{"type":34,"value":338},{"type":29,"tag":88,"props":19229,"children":19230},{"style":157},[19231],{"type":34,"value":19232},"bind",{"type":29,"tag":88,"props":19234,"children":19235},{"style":122},[19236],{"type":34,"value":338},{"type":29,"tag":88,"props":19238,"children":19239},{"style":157},[19240],{"type":34,"value":19241},"annotation",{"type":29,"tag":88,"props":19243,"children":19244},{"style":122},[19245],{"type":34,"value":338},{"type":29,"tag":88,"props":19247,"children":19248},{"style":157},[19249],{"type":34,"value":11841},{"type":29,"tag":88,"props":19251,"children":19252},{"style":122},[19253],{"type":34,"value":424},{"type":29,"tag":88,"props":19255,"children":19256},{"class":90,"line":270},[19257,19261,19265,19269,19273,19277,19281,19285,19289,19293,19297,19301,19305],{"type":29,"tag":88,"props":19258,"children":19259},{"style":105},[19260],{"type":34,"value":18881},{"type":29,"tag":88,"props":19262,"children":19263},{"style":157},[19264],{"type":34,"value":19205},{"type":29,"tag":88,"props":19266,"children":19267},{"style":122},[19268],{"type":34,"value":338},{"type":29,"tag":88,"props":19270,"children":19271},{"style":157},[19272],{"type":34,"value":19214},{"type":29,"tag":88,"props":19274,"children":19275},{"style":122},[19276],{"type":34,"value":338},{"type":29,"tag":88,"props":19278,"children":19279},{"style":157},[19280],{"type":34,"value":19223},{"type":29,"tag":88,"props":19282,"children":19283},{"style":122},[19284],{"type":34,"value":338},{"type":29,"tag":88,"props":19286,"children":19287},{"style":157},[19288],{"type":34,"value":19232},{"type":29,"tag":88,"props":19290,"children":19291},{"style":122},[19292],{"type":34,"value":338},{"type":29,"tag":88,"props":19294,"children":19295},{"style":157},[19296],{"type":34,"value":19241},{"type":29,"tag":88,"props":19298,"children":19299},{"style":122},[19300],{"type":34,"value":338},{"type":29,"tag":88,"props":19302,"children":19303},{"style":157},[19304],{"type":34,"value":9205},{"type":29,"tag":88,"props":19306,"children":19307},{"style":122},[19308],{"type":34,"value":424},{"type":29,"tag":88,"props":19310,"children":19311},{"class":90,"line":313},[19312,19316,19320,19324,19328,19332,19336,19340,19344,19348,19352,19356,19361],{"type":29,"tag":88,"props":19313,"children":19314},{"style":105},[19315],{"type":34,"value":18881},{"type":29,"tag":88,"props":19317,"children":19318},{"style":157},[19319],{"type":34,"value":19205},{"type":29,"tag":88,"props":19321,"children":19322},{"style":122},[19323],{"type":34,"value":338},{"type":29,"tag":88,"props":19325,"children":19326},{"style":157},[19327],{"type":34,"value":19214},{"type":29,"tag":88,"props":19329,"children":19330},{"style":122},[19331],{"type":34,"value":338},{"type":29,"tag":88,"props":19333,"children":19334},{"style":157},[19335],{"type":34,"value":19223},{"type":29,"tag":88,"props":19337,"children":19338},{"style":122},[19339],{"type":34,"value":338},{"type":29,"tag":88,"props":19341,"children":19342},{"style":157},[19343],{"type":34,"value":19232},{"type":29,"tag":88,"props":19345,"children":19346},{"style":122},[19347],{"type":34,"value":338},{"type":29,"tag":88,"props":19349,"children":19350},{"style":157},[19351],{"type":34,"value":19241},{"type":29,"tag":88,"props":19353,"children":19354},{"style":122},[19355],{"type":34,"value":338},{"type":29,"tag":88,"props":19357,"children":19358},{"style":157},[19359],{"type":34,"value":19360},"RestController",{"type":29,"tag":88,"props":19362,"children":19363},{"style":122},[19364],{"type":34,"value":424},{"type":29,"tag":88,"props":19366,"children":19367},{"class":90,"line":360},[19368],{"type":29,"tag":88,"props":19369,"children":19370},{"emptyLinePlaceholder":13},[19371],{"type":34,"value":134},{"type":29,"tag":88,"props":19373,"children":19374},{"class":90,"line":409},[19375,19379,19384,19388,19393,19397,19402],{"type":29,"tag":88,"props":19376,"children":19377},{"style":105},[19378],{"type":34,"value":18881},{"type":29,"tag":88,"props":19380,"children":19381},{"style":157},[19382],{"type":34,"value":19383}," java",{"type":29,"tag":88,"props":19385,"children":19386},{"style":122},[19387],{"type":34,"value":338},{"type":29,"tag":88,"props":19389,"children":19390},{"style":157},[19391],{"type":34,"value":19392},"util",{"type":29,"tag":88,"props":19394,"children":19395},{"style":122},[19396],{"type":34,"value":338},{"type":29,"tag":88,"props":19398,"children":19399},{"style":157},[19400],{"type":34,"value":19401},"List",{"type":29,"tag":88,"props":19403,"children":19404},{"style":122},[19405],{"type":34,"value":424},{"type":29,"tag":88,"props":19407,"children":19408},{"class":90,"line":427},[19409],{"type":29,"tag":88,"props":19410,"children":19411},{"emptyLinePlaceholder":13},[19412],{"type":34,"value":134},{"type":29,"tag":88,"props":19414,"children":19415},{"class":90,"line":436},[19416,19420],{"type":29,"tag":88,"props":19417,"children":19418},{"style":1974},[19419],{"type":34,"value":1977},{"type":29,"tag":88,"props":19421,"children":19422},{"style":1980},[19423],{"type":34,"value":9193},{"type":29,"tag":88,"props":19425,"children":19426},{"class":90,"line":767},[19427,19431,19435,19439,19444],{"type":29,"tag":88,"props":19428,"children":19429},{"style":1974},[19430],{"type":34,"value":1977},{"type":29,"tag":88,"props":19432,"children":19433},{"style":1980},[19434],{"type":34,"value":9205},{"type":29,"tag":88,"props":19436,"children":19437},{"style":122},[19438],{"type":34,"value":181},{"type":29,"tag":88,"props":19440,"children":19441},{"style":184},[19442],{"type":34,"value":19443},"\"\u002Fapi\u002Fusers\"",{"type":29,"tag":88,"props":19445,"children":19446},{"style":122},[19447],{"type":34,"value":3078},{"type":29,"tag":88,"props":19449,"children":19450},{"class":90,"line":792},[19451,19455,19459,19463],{"type":29,"tag":88,"props":19452,"children":19453},{"style":105},[19454],{"type":34,"value":108},{"type":29,"tag":88,"props":19456,"children":19457},{"style":105},[19458],{"type":34,"value":113},{"type":29,"tag":88,"props":19460,"children":19461},{"style":116},[19462],{"type":34,"value":9234},{"type":29,"tag":88,"props":19464,"children":19465},{"style":122},[19466],{"type":34,"value":125},{"type":29,"tag":88,"props":19468,"children":19469},{"class":90,"line":817},[19470],{"type":29,"tag":88,"props":19471,"children":19472},{"emptyLinePlaceholder":13},[19473],{"type":34,"value":134},{"type":29,"tag":88,"props":19475,"children":19476},{"class":90,"line":825},[19477,19481,19485,19489,19493,19497,19502],{"type":29,"tag":88,"props":19478,"children":19479},{"style":1974},[19480],{"type":34,"value":3302},{"type":29,"tag":88,"props":19482,"children":19483},{"style":1980},[19484],{"type":34,"value":18931},{"type":29,"tag":88,"props":19486,"children":19487},{"style":122},[19488],{"type":34,"value":181},{"type":29,"tag":88,"props":19490,"children":19491},{"style":6106},[19492],{"type":34,"value":5653},{"type":29,"tag":88,"props":19494,"children":19495},{"style":163},[19496],{"type":34,"value":6113},{"type":29,"tag":88,"props":19498,"children":19499},{"style":184},[19500],{"type":34,"value":19501}," \"Obtenir la liste des utilisateurs\"",{"type":29,"tag":88,"props":19503,"children":19504},{"style":122},[19505],{"type":34,"value":3078},{"type":29,"tag":88,"props":19507,"children":19508},{"class":90,"line":869},[19509,19513,19517,19521,19526,19530],{"type":29,"tag":88,"props":19510,"children":19511},{"style":1974},[19512],{"type":34,"value":3302},{"type":29,"tag":88,"props":19514,"children":19515},{"style":1980},[19516],{"type":34,"value":19189},{"type":29,"tag":88,"props":19518,"children":19519},{"style":122},[19520],{"type":34,"value":181},{"type":29,"tag":88,"props":19522,"children":19523},{"style":6106},[19524],{"type":34,"value":19525},"value",{"type":29,"tag":88,"props":19527,"children":19528},{"style":163},[19529],{"type":34,"value":6113},{"type":29,"tag":88,"props":19531,"children":19532},{"style":122},[19533],{"type":34,"value":125},{"type":29,"tag":88,"props":19535,"children":19536},{"class":90,"line":900},[19537,19542,19546,19550,19555,19559,19564,19568,19573,19577,19582],{"type":29,"tag":88,"props":19538,"children":19539},{"style":1974},[19540],{"type":34,"value":19541},"        @",{"type":29,"tag":88,"props":19543,"children":19544},{"style":1980},[19545],{"type":34,"value":19125},{"type":29,"tag":88,"props":19547,"children":19548},{"style":122},[19549],{"type":34,"value":181},{"type":29,"tag":88,"props":19551,"children":19552},{"style":6106},[19553],{"type":34,"value":19554},"responseCode",{"type":29,"tag":88,"props":19556,"children":19557},{"style":163},[19558],{"type":34,"value":6113},{"type":29,"tag":88,"props":19560,"children":19561},{"style":184},[19562],{"type":34,"value":19563}," \"200\"",{"type":29,"tag":88,"props":19565,"children":19566},{"style":122},[19567],{"type":34,"value":192},{"type":29,"tag":88,"props":19569,"children":19570},{"style":6106},[19571],{"type":34,"value":19572}," description",{"type":29,"tag":88,"props":19574,"children":19575},{"style":163},[19576],{"type":34,"value":6113},{"type":29,"tag":88,"props":19578,"children":19579},{"style":184},[19580],{"type":34,"value":19581}," \"Liste des utilisateurs trouvée\"",{"type":29,"tag":88,"props":19583,"children":19584},{"style":122},[19585],{"type":34,"value":4907},{"type":29,"tag":88,"props":19587,"children":19588},{"class":90,"line":929},[19589,19594,19598,19603,19607,19611,19615,19620,19624,19629],{"type":29,"tag":88,"props":19590,"children":19591},{"style":6106},[19592],{"type":34,"value":19593},"            content",{"type":29,"tag":88,"props":19595,"children":19596},{"style":163},[19597],{"type":34,"value":6113},{"type":29,"tag":88,"props":19599,"children":19600},{"style":122},[19601],{"type":34,"value":19602}," {",{"type":29,"tag":88,"props":19604,"children":19605},{"style":1974},[19606],{"type":34,"value":15325},{"type":29,"tag":88,"props":19608,"children":19609},{"style":1980},[19610],{"type":34,"value":18996},{"type":29,"tag":88,"props":19612,"children":19613},{"style":122},[19614],{"type":34,"value":181},{"type":29,"tag":88,"props":19616,"children":19617},{"style":6106},[19618],{"type":34,"value":19619},"mediaType",{"type":29,"tag":88,"props":19621,"children":19622},{"style":163},[19623],{"type":34,"value":6113},{"type":29,"tag":88,"props":19625,"children":19626},{"style":184},[19627],{"type":34,"value":19628}," \"application\u002Fjson\"",{"type":29,"tag":88,"props":19630,"children":19631},{"style":122},[19632],{"type":34,"value":4907},{"type":29,"tag":88,"props":19634,"children":19635},{"class":90,"line":937},[19636,19641,19645,19649,19653,19657,19662,19666,19670,19674,19678,19683],{"type":29,"tag":88,"props":19637,"children":19638},{"style":6106},[19639],{"type":34,"value":19640},"            schema",{"type":29,"tag":88,"props":19642,"children":19643},{"style":163},[19644],{"type":34,"value":6113},{"type":29,"tag":88,"props":19646,"children":19647},{"style":1974},[19648],{"type":34,"value":15325},{"type":29,"tag":88,"props":19650,"children":19651},{"style":1980},[19652],{"type":34,"value":19060},{"type":29,"tag":88,"props":19654,"children":19655},{"style":122},[19656],{"type":34,"value":181},{"type":29,"tag":88,"props":19658,"children":19659},{"style":6106},[19660],{"type":34,"value":19661},"implementation",{"type":29,"tag":88,"props":19663,"children":19664},{"style":163},[19665],{"type":34,"value":6113},{"type":29,"tag":88,"props":19667,"children":19668},{"style":157},[19669],{"type":34,"value":8883},{"type":29,"tag":88,"props":19671,"children":19672},{"style":122},[19673],{"type":34,"value":338},{"type":29,"tag":88,"props":19675,"children":19676},{"style":157},[19677],{"type":34,"value":1225},{"type":29,"tag":88,"props":19679,"children":19680},{"style":122},[19681],{"type":34,"value":19682},"))",{"type":29,"tag":88,"props":19684,"children":19685},{"style":122},[19686],{"type":34,"value":19687}," }),\n",{"type":29,"tag":88,"props":19689,"children":19690},{"class":90,"line":945},[19691,19695,19699,19703,19707,19711,19716,19720,19724,19728,19733],{"type":29,"tag":88,"props":19692,"children":19693},{"style":1974},[19694],{"type":34,"value":19541},{"type":29,"tag":88,"props":19696,"children":19697},{"style":1980},[19698],{"type":34,"value":19125},{"type":29,"tag":88,"props":19700,"children":19701},{"style":122},[19702],{"type":34,"value":181},{"type":29,"tag":88,"props":19704,"children":19705},{"style":6106},[19706],{"type":34,"value":19554},{"type":29,"tag":88,"props":19708,"children":19709},{"style":163},[19710],{"type":34,"value":6113},{"type":29,"tag":88,"props":19712,"children":19713},{"style":184},[19714],{"type":34,"value":19715}," \"400\"",{"type":29,"tag":88,"props":19717,"children":19718},{"style":122},[19719],{"type":34,"value":192},{"type":29,"tag":88,"props":19721,"children":19722},{"style":6106},[19723],{"type":34,"value":19572},{"type":29,"tag":88,"props":19725,"children":19726},{"style":163},[19727],{"type":34,"value":6113},{"type":29,"tag":88,"props":19729,"children":19730},{"style":184},[19731],{"type":34,"value":19732}," \"Requête invalide\"",{"type":29,"tag":88,"props":19734,"children":19735},{"style":122},[19736],{"type":34,"value":4907},{"type":29,"tag":88,"props":19738,"children":19739},{"class":90,"line":981},[19740,19744,19748,19752,19756],{"type":29,"tag":88,"props":19741,"children":19742},{"style":6106},[19743],{"type":34,"value":19593},{"type":29,"tag":88,"props":19745,"children":19746},{"style":163},[19747],{"type":34,"value":6113},{"type":29,"tag":88,"props":19749,"children":19750},{"style":1974},[19751],{"type":34,"value":15325},{"type":29,"tag":88,"props":19753,"children":19754},{"style":1980},[19755],{"type":34,"value":18996},{"type":29,"tag":88,"props":19757,"children":19758},{"style":122},[19759],{"type":34,"value":19760},"),\n",{"type":29,"tag":88,"props":19762,"children":19763},{"class":90,"line":1021},[19764,19768,19772,19776,19780,19784,19789,19793,19797,19801,19806],{"type":29,"tag":88,"props":19765,"children":19766},{"style":1974},[19767],{"type":34,"value":19541},{"type":29,"tag":88,"props":19769,"children":19770},{"style":1980},[19771],{"type":34,"value":19125},{"type":29,"tag":88,"props":19773,"children":19774},{"style":122},[19775],{"type":34,"value":181},{"type":29,"tag":88,"props":19777,"children":19778},{"style":6106},[19779],{"type":34,"value":19554},{"type":29,"tag":88,"props":19781,"children":19782},{"style":163},[19783],{"type":34,"value":6113},{"type":29,"tag":88,"props":19785,"children":19786},{"style":184},[19787],{"type":34,"value":19788}," \"404\"",{"type":29,"tag":88,"props":19790,"children":19791},{"style":122},[19792],{"type":34,"value":192},{"type":29,"tag":88,"props":19794,"children":19795},{"style":6106},[19796],{"type":34,"value":19572},{"type":29,"tag":88,"props":19798,"children":19799},{"style":163},[19800],{"type":34,"value":6113},{"type":29,"tag":88,"props":19802,"children":19803},{"style":184},[19804],{"type":34,"value":19805}," \"Utilisateurs non trouvés\"",{"type":29,"tag":88,"props":19807,"children":19808},{"style":122},[19809],{"type":34,"value":4907},{"type":29,"tag":88,"props":19811,"children":19812},{"class":90,"line":1066},[19813,19817,19821,19825,19829,19833],{"type":29,"tag":88,"props":19814,"children":19815},{"style":6106},[19816],{"type":34,"value":19593},{"type":29,"tag":88,"props":19818,"children":19819},{"style":163},[19820],{"type":34,"value":6113},{"type":29,"tag":88,"props":19822,"children":19823},{"style":1974},[19824],{"type":34,"value":15325},{"type":29,"tag":88,"props":19826,"children":19827},{"style":1980},[19828],{"type":34,"value":18996},{"type":29,"tag":88,"props":19830,"children":19831},{"style":122},[19832],{"type":34,"value":306},{"type":29,"tag":88,"props":19834,"children":19835},{"style":122},[19836],{"type":34,"value":19837}," })\n",{"type":29,"tag":88,"props":19839,"children":19840},{"class":90,"line":1082},[19841,19845],{"type":29,"tag":88,"props":19842,"children":19843},{"style":1974},[19844],{"type":34,"value":3302},{"type":29,"tag":88,"props":19846,"children":19847},{"style":1980},[19848],{"type":34,"value":19849},"GetMapping\n",{"type":29,"tag":88,"props":19851,"children":19852},{"class":90,"line":1090},[19853,19857,19861,19865,19870,19874,19879,19883],{"type":29,"tag":88,"props":19854,"children":19855},{"style":105},[19856],{"type":34,"value":276},{"type":29,"tag":88,"props":19858,"children":19859},{"style":151},[19860],{"type":34,"value":5355},{"type":29,"tag":88,"props":19862,"children":19863},{"style":122},[19864],{"type":34,"value":1683},{"type":29,"tag":88,"props":19866,"children":19867},{"style":105},[19868],{"type":34,"value":19869},"User",{"type":29,"tag":88,"props":19871,"children":19872},{"style":122},[19873],{"type":34,"value":1701},{"type":29,"tag":88,"props":19875,"children":19876},{"style":174},[19877],{"type":34,"value":19878}," getUsers",{"type":29,"tag":88,"props":19880,"children":19881},{"style":122},[19882],{"type":34,"value":1470},{"type":29,"tag":88,"props":19884,"children":19885},{"style":122},[19886],{"type":34,"value":125},{"type":29,"tag":88,"props":19888,"children":19889},{"class":90,"line":1098},[19890],{"type":29,"tag":88,"props":19891,"children":19892},{"style":95},[19893],{"type":34,"value":19894},"        \u002F\u002F Simuler une liste d'utilisateurs\n",{"type":29,"tag":88,"props":19896,"children":19897},{"class":90,"line":1106},[19898,19902,19906,19910,19914,19918,19922,19926,19930,19934,19938,19943,19947,19951,19955,19959,19964,19968,19973],{"type":29,"tag":88,"props":19899,"children":19900},{"style":105},[19901],{"type":34,"value":415},{"type":29,"tag":88,"props":19903,"children":19904},{"style":157},[19905],{"type":34,"value":5355},{"type":29,"tag":88,"props":19907,"children":19908},{"style":122},[19909],{"type":34,"value":338},{"type":29,"tag":88,"props":19911,"children":19912},{"style":174},[19913],{"type":34,"value":1393},{"type":29,"tag":88,"props":19915,"children":19916},{"style":122},[19917],{"type":34,"value":181},{"type":29,"tag":88,"props":19919,"children":19920},{"style":105},[19921],{"type":34,"value":2151},{"type":29,"tag":88,"props":19923,"children":19924},{"style":174},[19925],{"type":34,"value":8883},{"type":29,"tag":88,"props":19927,"children":19928},{"style":122},[19929],{"type":34,"value":181},{"type":29,"tag":88,"props":19931,"children":19932},{"style":195},[19933],{"type":34,"value":2275},{"type":29,"tag":88,"props":19935,"children":19936},{"style":122},[19937],{"type":34,"value":192},{"type":29,"tag":88,"props":19939,"children":19940},{"style":184},[19941],{"type":34,"value":19942}," \"Alice\"",{"type":29,"tag":88,"props":19944,"children":19945},{"style":122},[19946],{"type":34,"value":4242},{"type":29,"tag":88,"props":19948,"children":19949},{"style":105},[19950],{"type":34,"value":171},{"type":29,"tag":88,"props":19952,"children":19953},{"style":174},[19954],{"type":34,"value":8883},{"type":29,"tag":88,"props":19956,"children":19957},{"style":122},[19958],{"type":34,"value":181},{"type":29,"tag":88,"props":19960,"children":19961},{"style":195},[19962],{"type":34,"value":19963},"2",{"type":29,"tag":88,"props":19965,"children":19966},{"style":122},[19967],{"type":34,"value":192},{"type":29,"tag":88,"props":19969,"children":19970},{"style":184},[19971],{"type":34,"value":19972}," \"Bob\"",{"type":29,"tag":88,"props":19974,"children":19975},{"style":122},[19976],{"type":34,"value":1415},{"type":29,"tag":88,"props":19978,"children":19979},{"class":90,"line":1115},[19980],{"type":29,"tag":88,"props":19981,"children":19982},{"style":122},[19983],{"type":34,"value":433},{"type":29,"tag":88,"props":19985,"children":19986},{"class":90,"line":11},[19987],{"type":29,"tag":88,"props":19988,"children":19989},{"emptyLinePlaceholder":13},[19990],{"type":34,"value":134},{"type":29,"tag":88,"props":19992,"children":19993},{"class":90,"line":1180},[19994],{"type":29,"tag":88,"props":19995,"children":19996},{"style":122},[19997],{"type":34,"value":442},{"type":29,"tag":88,"props":19999,"children":20000},{"class":90,"line":1240},[20001],{"type":29,"tag":88,"props":20002,"children":20003},{"emptyLinePlaceholder":13},[20004],{"type":34,"value":134},{"type":29,"tag":88,"props":20006,"children":20007},{"class":90,"line":1248},[20008,20012,20016],{"type":29,"tag":88,"props":20009,"children":20010},{"style":105},[20011],{"type":34,"value":1225},{"type":29,"tag":88,"props":20013,"children":20014},{"style":116},[20015],{"type":34,"value":8883},{"type":29,"tag":88,"props":20017,"children":20018},{"style":122},[20019],{"type":34,"value":125},{"type":29,"tag":88,"props":20021,"children":20022},{"class":90,"line":1256},[20023,20027,20032,20036],{"type":29,"tag":88,"props":20024,"children":20025},{"style":105},[20026],{"type":34,"value":143},{"type":29,"tag":88,"props":20028,"children":20029},{"style":105},[20030],{"type":34,"value":20031}," int",{"type":29,"tag":88,"props":20033,"children":20034},{"style":157},[20035],{"type":34,"value":3435},{"type":29,"tag":88,"props":20037,"children":20038},{"style":122},[20039],{"type":34,"value":424},{"type":29,"tag":88,"props":20041,"children":20042},{"class":90,"line":1264},[20043,20047,20051,20056],{"type":29,"tag":88,"props":20044,"children":20045},{"style":105},[20046],{"type":34,"value":143},{"type":29,"tag":88,"props":20048,"children":20049},{"style":151},[20050],{"type":34,"value":281},{"type":29,"tag":88,"props":20052,"children":20053},{"style":157},[20054],{"type":34,"value":20055}," name",{"type":29,"tag":88,"props":20057,"children":20058},{"style":122},[20059],{"type":34,"value":424},{"type":29,"tag":88,"props":20061,"children":20062},{"class":90,"line":1293},[20063],{"type":29,"tag":88,"props":20064,"children":20065},{"emptyLinePlaceholder":13},[20066],{"type":34,"value":134},{"type":29,"tag":88,"props":20068,"children":20069},{"class":90,"line":1342},[20070,20074,20078,20082,20087,20091,20095,20099,20103,20107],{"type":29,"tag":88,"props":20071,"children":20072},{"style":105},[20073],{"type":34,"value":276},{"type":29,"tag":88,"props":20075,"children":20076},{"style":174},[20077],{"type":34,"value":8883},{"type":29,"tag":88,"props":20079,"children":20080},{"style":122},[20081],{"type":34,"value":181},{"type":29,"tag":88,"props":20083,"children":20084},{"style":105},[20085],{"type":34,"value":20086},"int",{"type":29,"tag":88,"props":20088,"children":20089},{"style":298},[20090],{"type":34,"value":3435},{"type":29,"tag":88,"props":20092,"children":20093},{"style":122},[20094],{"type":34,"value":192},{"type":29,"tag":88,"props":20096,"children":20097},{"style":151},[20098],{"type":34,"value":281},{"type":29,"tag":88,"props":20100,"children":20101},{"style":298},[20102],{"type":34,"value":20055},{"type":29,"tag":88,"props":20104,"children":20105},{"style":122},[20106],{"type":34,"value":306},{"type":29,"tag":88,"props":20108,"children":20109},{"style":122},[20110],{"type":34,"value":125},{"type":29,"tag":88,"props":20112,"children":20113},{"class":90,"line":1418},[20114,20118,20122,20126,20130],{"type":29,"tag":88,"props":20115,"children":20116},{"style":873},[20117],{"type":34,"value":876},{"type":29,"tag":88,"props":20119,"children":20120},{"style":122},[20121],{"type":34,"value":338},{"type":29,"tag":88,"props":20123,"children":20124},{"style":157},[20125],{"type":34,"value":8325},{"type":29,"tag":88,"props":20127,"children":20128},{"style":163},[20129],{"type":34,"value":166},{"type":29,"tag":88,"props":20131,"children":20132},{"style":157},[20133],{"type":34,"value":20134}," id\n",{"type":29,"tag":88,"props":20136,"children":20137},{"class":90,"line":1426},[20138],{"type":29,"tag":88,"props":20139,"children":20140},{"emptyLinePlaceholder":13},[20141],{"type":34,"value":134},{"type":29,"tag":88,"props":20143,"children":20144},{"class":90,"line":1434},[20145],{"type":29,"tag":88,"props":20146,"children":20147},{"style":122},[20148],{"type":34,"value":424},{"type":29,"tag":88,"props":20150,"children":20151},{"class":90,"line":1442},[20152,20156,20160,20165,20169,20173],{"type":29,"tag":88,"props":20153,"children":20154},{"style":873},[20155],{"type":34,"value":876},{"type":29,"tag":88,"props":20157,"children":20158},{"style":122},[20159],{"type":34,"value":338},{"type":29,"tag":88,"props":20161,"children":20162},{"style":157},[20163],{"type":34,"value":20164},"name ",{"type":29,"tag":88,"props":20166,"children":20167},{"style":163},[20168],{"type":34,"value":166},{"type":29,"tag":88,"props":20170,"children":20171},{"style":157},[20172],{"type":34,"value":20055},{"type":29,"tag":88,"props":20174,"children":20175},{"style":122},[20176],{"type":34,"value":424},{"type":29,"tag":88,"props":20178,"children":20179},{"class":90,"line":1451},[20180],{"type":29,"tag":88,"props":20181,"children":20182},{"style":122},[20183],{"type":34,"value":433},{"type":29,"tag":88,"props":20185,"children":20186},{"class":90,"line":1477},[20187],{"type":29,"tag":88,"props":20188,"children":20189},{"emptyLinePlaceholder":13},[20190],{"type":34,"value":134},{"type":29,"tag":88,"props":20192,"children":20193},{"class":90,"line":1516},[20194],{"type":29,"tag":88,"props":20195,"children":20196},{"style":95},[20197],{"type":34,"value":20198},"    \u002F\u002F Getters et setters\n",{"type":29,"tag":88,"props":20200,"children":20201},{"class":90,"line":1573},[20202,20206,20210,20215,20219],{"type":29,"tag":88,"props":20203,"children":20204},{"style":105},[20205],{"type":34,"value":276},{"type":29,"tag":88,"props":20207,"children":20208},{"style":105},[20209],{"type":34,"value":20031},{"type":29,"tag":88,"props":20211,"children":20212},{"style":174},[20213],{"type":34,"value":20214}," getId",{"type":29,"tag":88,"props":20216,"children":20217},{"style":122},[20218],{"type":34,"value":1470},{"type":29,"tag":88,"props":20220,"children":20221},{"style":122},[20222],{"type":34,"value":125},{"type":29,"tag":88,"props":20224,"children":20225},{"class":90,"line":1611},[20226,20230,20234],{"type":29,"tag":88,"props":20227,"children":20228},{"style":105},[20229],{"type":34,"value":415},{"type":29,"tag":88,"props":20231,"children":20232},{"style":157},[20233],{"type":34,"value":3435},{"type":29,"tag":88,"props":20235,"children":20236},{"style":122},[20237],{"type":34,"value":424},{"type":29,"tag":88,"props":20239,"children":20240},{"class":90,"line":3231},[20241],{"type":29,"tag":88,"props":20242,"children":20243},{"style":122},[20244],{"type":34,"value":433},{"type":29,"tag":88,"props":20246,"children":20247},{"class":90,"line":3288},[20248],{"type":29,"tag":88,"props":20249,"children":20250},{"emptyLinePlaceholder":13},[20251],{"type":34,"value":134},{"type":29,"tag":88,"props":20253,"children":20254},{"class":90,"line":3296},[20255,20259,20263,20268,20272,20276,20280,20284],{"type":29,"tag":88,"props":20256,"children":20257},{"style":105},[20258],{"type":34,"value":276},{"type":29,"tag":88,"props":20260,"children":20261},{"style":105},[20262],{"type":34,"value":1303},{"type":29,"tag":88,"props":20264,"children":20265},{"style":174},[20266],{"type":34,"value":20267}," setId",{"type":29,"tag":88,"props":20269,"children":20270},{"style":122},[20271],{"type":34,"value":181},{"type":29,"tag":88,"props":20273,"children":20274},{"style":105},[20275],{"type":34,"value":20086},{"type":29,"tag":88,"props":20277,"children":20278},{"style":298},[20279],{"type":34,"value":3435},{"type":29,"tag":88,"props":20281,"children":20282},{"style":122},[20283],{"type":34,"value":306},{"type":29,"tag":88,"props":20285,"children":20286},{"style":122},[20287],{"type":34,"value":125},{"type":29,"tag":88,"props":20289,"children":20290},{"class":90,"line":3310},[20291,20295,20299,20303,20307,20311],{"type":29,"tag":88,"props":20292,"children":20293},{"style":873},[20294],{"type":34,"value":876},{"type":29,"tag":88,"props":20296,"children":20297},{"style":122},[20298],{"type":34,"value":338},{"type":29,"tag":88,"props":20300,"children":20301},{"style":157},[20302],{"type":34,"value":8325},{"type":29,"tag":88,"props":20304,"children":20305},{"style":163},[20306],{"type":34,"value":166},{"type":29,"tag":88,"props":20308,"children":20309},{"style":157},[20310],{"type":34,"value":3435},{"type":29,"tag":88,"props":20312,"children":20313},{"style":122},[20314],{"type":34,"value":424},{"type":29,"tag":88,"props":20316,"children":20317},{"class":90,"line":3346},[20318],{"type":29,"tag":88,"props":20319,"children":20320},{"style":122},[20321],{"type":34,"value":433},{"type":29,"tag":88,"props":20323,"children":20324},{"class":90,"line":3387},[20325],{"type":29,"tag":88,"props":20326,"children":20327},{"emptyLinePlaceholder":13},[20328],{"type":34,"value":134},{"type":29,"tag":88,"props":20330,"children":20331},{"class":90,"line":3425},[20332,20336,20340,20345,20349],{"type":29,"tag":88,"props":20333,"children":20334},{"style":105},[20335],{"type":34,"value":276},{"type":29,"tag":88,"props":20337,"children":20338},{"style":151},[20339],{"type":34,"value":281},{"type":29,"tag":88,"props":20341,"children":20342},{"style":174},[20343],{"type":34,"value":20344}," getName",{"type":29,"tag":88,"props":20346,"children":20347},{"style":122},[20348],{"type":34,"value":1470},{"type":29,"tag":88,"props":20350,"children":20351},{"style":122},[20352],{"type":34,"value":125},{"type":29,"tag":88,"props":20354,"children":20355},{"class":90,"line":3442},[20356,20360,20364],{"type":29,"tag":88,"props":20357,"children":20358},{"style":105},[20359],{"type":34,"value":415},{"type":29,"tag":88,"props":20361,"children":20362},{"style":157},[20363],{"type":34,"value":20055},{"type":29,"tag":88,"props":20365,"children":20366},{"style":122},[20367],{"type":34,"value":424},{"type":29,"tag":88,"props":20369,"children":20370},{"class":90,"line":3450},[20371],{"type":29,"tag":88,"props":20372,"children":20373},{"style":122},[20374],{"type":34,"value":433},{"type":29,"tag":88,"props":20376,"children":20377},{"class":90,"line":3458},[20378],{"type":29,"tag":88,"props":20379,"children":20380},{"emptyLinePlaceholder":13},[20381],{"type":34,"value":134},{"type":29,"tag":88,"props":20383,"children":20384},{"class":90,"line":3470},[20385,20389,20393,20398,20402,20406,20410,20414],{"type":29,"tag":88,"props":20386,"children":20387},{"style":105},[20388],{"type":34,"value":276},{"type":29,"tag":88,"props":20390,"children":20391},{"style":105},[20392],{"type":34,"value":1303},{"type":29,"tag":88,"props":20394,"children":20395},{"style":174},[20396],{"type":34,"value":20397}," setName",{"type":29,"tag":88,"props":20399,"children":20400},{"style":122},[20401],{"type":34,"value":181},{"type":29,"tag":88,"props":20403,"children":20404},{"style":151},[20405],{"type":34,"value":695},{"type":29,"tag":88,"props":20407,"children":20408},{"style":298},[20409],{"type":34,"value":20055},{"type":29,"tag":88,"props":20411,"children":20412},{"style":122},[20413],{"type":34,"value":306},{"type":29,"tag":88,"props":20415,"children":20416},{"style":122},[20417],{"type":34,"value":125},{"type":29,"tag":88,"props":20419,"children":20420},{"class":90,"line":3519},[20421,20425,20429,20433,20437,20441],{"type":29,"tag":88,"props":20422,"children":20423},{"style":873},[20424],{"type":34,"value":876},{"type":29,"tag":88,"props":20426,"children":20427},{"style":122},[20428],{"type":34,"value":338},{"type":29,"tag":88,"props":20430,"children":20431},{"style":157},[20432],{"type":34,"value":20164},{"type":29,"tag":88,"props":20434,"children":20435},{"style":163},[20436],{"type":34,"value":166},{"type":29,"tag":88,"props":20438,"children":20439},{"style":157},[20440],{"type":34,"value":20055},{"type":29,"tag":88,"props":20442,"children":20443},{"style":122},[20444],{"type":34,"value":424},{"type":29,"tag":88,"props":20446,"children":20447},{"class":90,"line":3571},[20448],{"type":29,"tag":88,"props":20449,"children":20450},{"style":122},[20451],{"type":34,"value":433},{"type":29,"tag":88,"props":20453,"children":20454},{"class":90,"line":3637},[20455],{"type":29,"tag":88,"props":20456,"children":20457},{"style":122},[20458],{"type":34,"value":442},{"type":29,"tag":12165,"props":20460,"children":20462},{"id":20461},"explication-des-annotations-swagger",[20463],{"type":34,"value":20464},"Explication des annotations Swagger :",{"type":29,"tag":453,"props":20466,"children":20467},{},[20468,20486,20511],{"type":29,"tag":457,"props":20469,"children":20470},{},[20471,20476,20478,20484],{"type":29,"tag":447,"props":20472,"children":20473},{},[20474],{"type":34,"value":20475},"@Operation",{"type":34,"value":20477}," : Décrit l'opération ou l'endpoint de manière concise. Ici, la méthode ",{"type":29,"tag":84,"props":20479,"children":20481},{"className":20480},[],[20482],{"type":34,"value":20483},"getUsers()",{"type":34,"value":20485}," est annotée pour indiquer qu'elle retourne une liste d’utilisateurs.",{"type":29,"tag":457,"props":20487,"children":20488},{},[20489,20494,20496,20501,20503,20509],{"type":29,"tag":447,"props":20490,"children":20491},{},[20492],{"type":34,"value":20493},"@ApiResponses",{"type":34,"value":20495}," : Définit les réponses possibles de l'API, comme le code ",{"type":29,"tag":84,"props":20497,"children":20499},{"className":20498},[],[20500],{"type":34,"value":18611},{"type":34,"value":20502}," pour une réponse réussie ou ",{"type":29,"tag":84,"props":20504,"children":20506},{"className":20505},[],[20507],{"type":34,"value":20508},"404",{"type":34,"value":20510}," pour des utilisateurs non trouvés.",{"type":29,"tag":457,"props":20512,"children":20513},{},[20514,20519,20521,20526],{"type":29,"tag":447,"props":20515,"children":20516},{},[20517],{"type":34,"value":20518},"@Schema",{"type":34,"value":20520}," : Définit le modèle des données pour structurer les réponses, ici l'objet ",{"type":29,"tag":84,"props":20522,"children":20524},{"className":20523},[],[20525],{"type":34,"value":19869},{"type":34,"value":338},{"type":29,"tag":30,"props":20528,"children":20529},{},[20530],{"type":34,"value":20531},"Avec cette configuration, vous pouvez visualiser et tester vos endpoints directement dans Swagger UI via votre navigateur.",{"type":29,"tag":47,"props":20533,"children":20534},{},[],{"type":29,"tag":51,"props":20536,"children":20538},{"id":20537},"bonnes-pratiques-pour-réussir-ladoption-dapi-first-avec-spring-boot-et-java",[20539],{"type":34,"value":20540},"Bonnes pratiques pour réussir l’adoption d’API First avec Spring Boot et Java",{"type":29,"tag":30,"props":20542,"children":20543},{},[20544,20546,20550,20552,20556,20557,20561],{"type":34,"value":20545},"Adopter l’approche ",{"type":29,"tag":447,"props":20547,"children":20548},{},[20549],{"type":34,"value":10736},{"type":34,"value":20551}," transforme la manière dont vous collaborez et écrivez du code. Quelques principes essentiels pour réussir cette adoption avec ",{"type":29,"tag":447,"props":20553,"children":20554},{},[20555],{"type":34,"value":18092},{"type":34,"value":18104},{"type":29,"tag":447,"props":20558,"children":20559},{},[20560],{"type":34,"value":10755},{"type":34,"value":338},{"type":29,"tag":6010,"props":20563,"children":20565},{"id":20564},"_1-impliquer-toutes-les-équipes-dès-le-début",[20566],{"type":34,"value":20567},"1. Impliquer toutes les équipes dès le début",{"type":29,"tag":30,"props":20569,"children":20570},{},[20571],{"type":34,"value":20572},"L’un des principes clés de l’approche API First est de considérer l’API comme un contrat entre toutes les parties prenantes : les développeurs front-end, back-end, les équipes QA, et parfois même les équipes produits. Il est donc crucial que ces équipes soient impliquées dès la phase de spécification de l’API. Cela garantit une collaboration harmonieuse et réduit les risques d’incohérences.",{"type":29,"tag":6010,"props":20574,"children":20576},{"id":20575},"_2-automatiser-la-génération-du-code-et-des-tests",[20577],{"type":34,"value":20578},"2. Automatiser la génération du code et des tests",{"type":29,"tag":30,"props":20580,"children":20581},{},[20582,20584,20588,20590,20595,20596,20601],{"type":34,"value":20583},"Un des grands gains de l’API First : générer automatiquement du code à partir de la spécification ",{"type":29,"tag":447,"props":20585,"children":20586},{},[20587],{"type":34,"value":11426},{"type":34,"value":20589},". Avec ",{"type":29,"tag":447,"props":20591,"children":20592},{},[20593],{"type":34,"value":20594},"Swagger Codegen",{"type":34,"value":5730},{"type":29,"tag":447,"props":20597,"children":20598},{},[20599],{"type":34,"value":20600},"OpenAPI Generator",{"type":34,"value":20602},", vous automatisez la création de contrôleurs, de modèles et même de clients API.",{"type":29,"tag":30,"props":20604,"children":20605},{},[20606],{"type":34,"value":20607},"Exemple de commande pour générer du code Spring Boot à partir d'une spécification OpenAPI :",{"type":29,"tag":77,"props":20609,"children":20613},{"className":20610,"code":20611,"language":20612,"meta":8,"style":8},"language-bash shiki shiki-themes catppuccin-frappe github-dark","openapi-generator-cli generate -i openapi.yaml -g spring -o .\u002Fgenerated-code\u002F\n","bash",[20614],{"type":29,"tag":84,"props":20615,"children":20616},{"__ignoreMap":8},[20617],{"type":29,"tag":88,"props":20618,"children":20619},{"class":90,"line":91},[20620,20625,20630,20636,20641,20646,20651,20656],{"type":29,"tag":88,"props":20621,"children":20622},{"style":174},[20623],{"type":34,"value":20624},"openapi-generator-cli",{"type":29,"tag":88,"props":20626,"children":20627},{"style":184},[20628],{"type":34,"value":20629}," generate",{"type":29,"tag":88,"props":20631,"children":20633},{"style":20632},"--shiki-default:#A6D189;--shiki-dark:#79B8FF",[20634],{"type":34,"value":20635}," -i",{"type":29,"tag":88,"props":20637,"children":20638},{"style":184},[20639],{"type":34,"value":20640}," openapi.yaml",{"type":29,"tag":88,"props":20642,"children":20643},{"style":20632},[20644],{"type":34,"value":20645}," -g",{"type":29,"tag":88,"props":20647,"children":20648},{"style":184},[20649],{"type":34,"value":20650}," spring",{"type":29,"tag":88,"props":20652,"children":20653},{"style":20632},[20654],{"type":34,"value":20655}," -o",{"type":29,"tag":88,"props":20657,"children":20658},{"style":184},[20659],{"type":34,"value":20660}," .\u002Fgenerated-code\u002F\n",{"type":29,"tag":6010,"props":20662,"children":20664},{"id":20663},"_3-mettre-à-jour-régulièrement-la-spécification",[20665],{"type":34,"value":20666},"3. Mettre à jour régulièrement la spécification",{"type":29,"tag":30,"props":20668,"children":20669},{},[20670,20672,20676,20678,20682],{"type":34,"value":20671},"Votre spécification ",{"type":29,"tag":447,"props":20673,"children":20674},{},[20675],{"type":34,"value":11426},{"type":34,"value":20677}," doit toujours être à jour avec votre code. Utilisez des outils comme ",{"type":29,"tag":447,"props":20679,"children":20680},{},[20681],{"type":34,"value":18679},{"type":34,"value":20683}," pour générer automatiquement une documentation OpenAPI à partir de vos contrôleurs Java. En maintenant cette documentation à jour, vous garantissez que l’API reste synchronisée avec le développement.",{"type":29,"tag":6010,"props":20685,"children":20687},{"id":20686},"_4-valider-lapi-dès-les-premières-étapes-du-projet",[20688],{"type":34,"value":20689},"4. Valider l’API dès les premières étapes du projet",{"type":29,"tag":30,"props":20691,"children":20692},{},[20693,20695,20700,20701,20706],{"type":34,"value":20694},"Avant même de commencer à coder, validez la spécification de votre API avec des outils comme ",{"type":29,"tag":447,"props":20696,"children":20697},{},[20698],{"type":34,"value":20699},"Swagger Editor",{"type":34,"value":5730},{"type":29,"tag":447,"props":20702,"children":20703},{},[20704],{"type":34,"value":20705},"Postman",{"type":34,"value":20707},". Testez les endpoints en amont pour aligner front et back sur le contrat avant l'implémentation.",{"type":29,"tag":6010,"props":20709,"children":20711},{"id":20710},"_5-favoriser-une-communication-continue-entre-les-équipes",[20712],{"type":34,"value":20713},"5. Favoriser une communication continue entre les équipes",{"type":29,"tag":30,"props":20715,"children":20716},{},[20717,20719,20723],{"type":34,"value":20718},"L’approche API First encourage la communication régulière entre les équipes de développement front-end, back-end et produit. Pour que cette API reste découplée de l’infrastructure et testable indépendamment, les principes de la ",{"type":29,"tag":63,"props":20720,"children":20721},{"href":65},[20722],{"type":34,"value":68},{"type":34,"value":20724}," sont un complément naturel. Organisez des revues régulières de la spécification de l’API pour vous assurer que toutes les parties prenantes sont alignées et que les changements sont bien compris par tous.",{"type":29,"tag":47,"props":20726,"children":20727},{},[],{"type":29,"tag":2288,"props":20729,"children":20731},{"cta":5629,"href":5630,"title":20730,"type":5632},"Concevoir l'API avant le code n'est qu'une des 100 pratiques craft",[20732,20737],{"type":29,"tag":30,"props":20733,"children":20734},{},[20735],{"type":34,"value":20736},"L'approche API First décrite ici est une pratique parmi d'autres : raisonner contrat-d'abord, c'est un réflexe de craftsman. Le Craft Bundle réunit les 100 pratiques que j'applique pour concevoir, coder et faire évoluer du logiciel propre.",{"type":29,"tag":30,"props":20738,"children":20739},{},[20740],{"type":34,"value":20741},"Ce sont les pratiques que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vues tenir face à une vraie montée en charge ni à une équipe qui évolue.",{"type":29,"tag":47,"props":20743,"children":20744},{},[],{"type":29,"tag":51,"props":20746,"children":20748},{"id":20747},"faq-sur-api-first-et-spring-boot",[20749],{"type":34,"value":20750},"FAQ sur API First et Spring Boot",{"type":29,"tag":5649,"props":20752,"children":20753},{},[20754,20759],{"type":29,"tag":5653,"props":20755,"children":20756},{},[20757],{"type":34,"value":20758},"1. Qu’est-ce que l’approche API First ?",{"type":29,"tag":30,"props":20760,"children":20761},{},[20762,20764,20768],{"type":34,"value":20763},"L’approche ",{"type":29,"tag":447,"props":20765,"children":20766},{},[20767],{"type":34,"value":10736},{"type":34,"value":20769}," consiste à définir et documenter une API avant de commencer à coder. L’API devient ainsi le contrat central entre toutes les équipes (front-end, back-end, QA, produit). Cela permet d’aligner les équipes dès le début et d’éviter les erreurs de communication et d’intégration tout au long du développement.",{"type":29,"tag":5649,"props":20771,"children":20772},{},[20773,20778],{"type":29,"tag":5653,"props":20774,"children":20775},{},[20776],{"type":34,"value":20777},"2. Quels sont les principaux avantages de l’approche API First ?",{"type":29,"tag":453,"props":20779,"children":20780},{},[20781,20791,20801],{"type":29,"tag":457,"props":20782,"children":20783},{},[20784,20789],{"type":29,"tag":447,"props":20785,"children":20786},{},[20787],{"type":34,"value":20788},"Collaboration inter-équipes",{"type":34,"value":20790}," : Les équipes front-end et back-end sont synchronisées dès le début grâce à une spécification centralisée.",{"type":29,"tag":457,"props":20792,"children":20793},{},[20794,20799],{"type":29,"tag":447,"props":20795,"children":20796},{},[20797],{"type":34,"value":20798},"Documentation à jour",{"type":34,"value":20800}," : OpenAPI sert à la fois de documentation et de contrat technique.",{"type":29,"tag":457,"props":20802,"children":20803},{},[20804,20809],{"type":29,"tag":447,"props":20805,"children":20806},{},[20807],{"type":34,"value":20808},"Réduction des erreurs",{"type":34,"value":20810}," : Les erreurs liées à des APIs mal définies sont minimisées car tout est validé et testé dès le début.",{"type":29,"tag":5649,"props":20812,"children":20813},{},[20814,20819],{"type":29,"tag":5653,"props":20815,"children":20816},{},[20817],{"type":34,"value":20818},"3. Comment OpenAPI s’intègre-t-il dans l’approche API First ?",{"type":29,"tag":30,"props":20820,"children":20821},{},[20822,20826],{"type":29,"tag":447,"props":20823,"children":20824},{},[20825],{"type":34,"value":11426},{"type":34,"value":20827}," est un standard de définition formelle des API, généralement en YAML ou JSON. Il génère du code automatiquement, documente les API et valide les endpoints à chaque étape du développement.",{"type":29,"tag":5649,"props":20829,"children":20830},{},[20831,20836],{"type":29,"tag":5653,"props":20832,"children":20833},{},[20834],{"type":34,"value":20835},"4. Comment utiliser OpenAPI avec Spring Boot ?",{"type":29,"tag":30,"props":20837,"children":20838},{},[20839,20841,20845],{"type":34,"value":20840},"Ajoutez la dépendance ",{"type":29,"tag":447,"props":20842,"children":20843},{},[20844],{"type":34,"value":18679},{"type":34,"value":20846}," à votre projet, et utilisez les annotations Swagger pour enrichir la documentation. Swagger UI vous permet de visualiser et tester vos endpoints en temps réel, et OpenAPI Generator peut automatiser la génération de code à partir d’une spécification.",{"type":29,"tag":5649,"props":20848,"children":20849},{},[20850,20855],{"type":29,"tag":5653,"props":20851,"children":20852},{},[20853],{"type":34,"value":20854},"5. Est-ce que l’approche API First est adaptée aux petites équipes ?",{"type":29,"tag":30,"props":20856,"children":20857},{},[20858],{"type":34,"value":20859},"Oui, API First est tout aussi bénéfique pour les petites équipes. Cela permet d’éviter des allers-retours coûteux entre front-end et back-end, et la documentation est toujours liée au code, réduisant les erreurs et augmentant l’efficacité.",{"type":29,"tag":5649,"props":20861,"children":20862},{},[20863,20868],{"type":29,"tag":5653,"props":20864,"children":20865},{},[20866],{"type":34,"value":20867},"6. Comment maintenir la documentation OpenAPI à jour pendant le développement ?",{"type":29,"tag":30,"props":20869,"children":20870},{},[20871,20873,20877],{"type":34,"value":20872},"Intégrez la mise à jour de la spécification OpenAPI dans votre flux de travail. Utiliser ",{"type":29,"tag":447,"props":20874,"children":20875},{},[20876],{"type":34,"value":18679},{"type":34,"value":20878}," vous permet de générer automatiquement une documentation OpenAPI à partir du code Java, en la tenant à jour à chaque modification du code.",{"type":29,"tag":2288,"props":20880,"children":20883},{"cta":20881,"href":16240,"title":20882,"type":5755},"Accéder au template gratuit →","Ressource gratuite : Auditez votre équipe engineering en 2 heures",[20884],{"type":29,"tag":30,"props":20885,"children":20886},{},[20887],{"type":34,"value":20888},"Le template Notion utilisé dans 15+ audits professionnels. 6 sections, 40 questions guidées, scoring visuel automatique. Format décisionnel prêt à présenter à votre direction.",{"type":29,"tag":47,"props":20890,"children":20891},{},[],{"type":29,"tag":5763,"props":20893,"children":20894},{},[20895],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":20897},[20898,20905,20910,20917],{"id":18116,"depth":101,"text":18119,"children":20899},[20900,20901,20902,20903,20904],{"id":18133,"depth":128,"text":18136},{"id":18144,"depth":128,"text":18147},{"id":18161,"depth":128,"text":18164},{"id":18179,"depth":128,"text":18182},{"id":18190,"depth":128,"text":18193},{"id":18218,"depth":101,"text":18221,"children":20906},[20907,20908,20909],{"id":18241,"depth":128,"text":18244},{"id":18616,"depth":128,"text":18619},{"id":18660,"depth":128,"text":18663},{"id":20537,"depth":101,"text":20540,"children":20911},[20912,20913,20914,20915,20916],{"id":20564,"depth":128,"text":20567},{"id":20575,"depth":128,"text":20578},{"id":20663,"depth":128,"text":20666},{"id":20686,"depth":128,"text":20689},{"id":20710,"depth":128,"text":20713},{"id":20747,"depth":101,"text":20750},"content:fr:architecture-craft:api-first-openapi-spring-boot.md","fr\u002Farchitecture-craft\u002Fapi-first-openapi-spring-boot.md","fr\u002Farchitecture-craft\u002Fapi-first-openapi-spring-boot",{"_path":20922,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":20923,"description":20924,"id":3450,"date":20925,"listed":13,"nocomments":7,"hidden":7,"categories":20926,"tags":20927,"cover":20928,"readingTime":20929,"body":20934,"_type":5777,"_id":22773,"_source":5779,"_file":22774,"_stem":22775,"_extension":5782},"\u002Ffr\u002Farchitecture-craft\u002Farchitecture-hexagonale-java-exemples-bonnes-pratiques","Architecture Hexagonale en Java, Avantages, Bonnes Pratiques et Exemple","Découvrez l'architecture hexagonale, ses avantages pour vos projets Java, et comment l'implémenter avec des exemples concrets. Apprenez à structurer vos applications pour...","2024-08-15",[6],[17,10685],"covers\u002Farticles\u002Farchitecture-hexagonale.jpg",{"text":20930,"minutes":20931,"time":20932,"words":20933},"7 min read",6.44,386400,1288,{"type":26,"children":20935,"toc":22748},[20936,20945,20950,20955,20960,20963,20972,20991,21000,21005,21014,21032,21049,21062,21071,21076,21085,21713,21722,22067,22076,22385,22404,22407,22421,22430,22435,22446,22465,22477,22488,22493,22504,22509,22512,22521,22526,22536,22553,22565,22575,22608,22618,22630,22642,22651,22654,22663,22676,22689,22702,22734,22744],{"type":29,"tag":51,"props":20937,"children":20939},{"id":20938},"pourquoi-larchitecture-hexagonale",[20940],{"type":29,"tag":447,"props":20941,"children":20942},{},[20943],{"type":34,"value":20944},"Pourquoi l'architecture hexagonale ?",{"type":29,"tag":30,"props":20946,"children":20947},{},[20948],{"type":34,"value":20949},"Une application Java démarre bien. Six mois plus tard, l'architecture en couches s'est transformée en plat de pâtes. Tout est connecté. Les tests deviennent un casse-tête. Le moindre changement menace de tout faire exploser.",{"type":29,"tag":30,"props":20951,"children":20952},{},[20953],{"type":34,"value":20954},"J’ai accompagné des équipes dans cette situation chez plusieurs clients bancaires et assurance. Le pattern se répète : la couche métier dépend directement de la base de données, et les tests unitaires ont besoin de toute l’application pour s’exécuter. Un désordre qui coûte plusieurs semaines de lead time par an.",{"type":29,"tag":30,"props":20956,"children":20957},{},[20958],{"type":34,"value":20959},"L’architecture hexagonale (ou \"Ports et Adapters\", formalisée par Alistair Cockburn) répond exactement à ce problème. Le domaine métier au centre, protégé. L'infrastructure (base de données, services externes) réduite à une collection d’adaptateurs interchangeables.",{"type":29,"tag":47,"props":20961,"children":20962},{},[],{"type":29,"tag":51,"props":20964,"children":20966},{"id":20965},"le-concept-darchitecture-hexagonale",[20967],{"type":29,"tag":447,"props":20968,"children":20969},{},[20970],{"type":34,"value":20971},"Le concept d'architecture hexagonale",{"type":29,"tag":30,"props":20973,"children":20974},{},[20975,20977,20982,20984,20989],{"type":34,"value":20976},"L’architecture hexagonale, également appelée ",{"type":29,"tag":447,"props":20978,"children":20979},{},[20980],{"type":34,"value":20981},"architecture Ports et Adapters",{"type":34,"value":20983},", place le ",{"type":29,"tag":447,"props":20985,"children":20986},{},[20987],{"type":34,"value":20988},"domaine métier",{"type":34,"value":20990}," au centre de l’application. L’objectif est de séparer complètement votre logique métier des aspects techniques comme la base de données, l’interface utilisateur ou encore les services externes.",{"type":29,"tag":6010,"props":20992,"children":20994},{"id":20993},"un-problème-de-dépendances",[20995],{"type":29,"tag":447,"props":20996,"children":20997},{},[20998],{"type":34,"value":20999},"Un problème de dépendances",{"type":29,"tag":30,"props":21001,"children":21002},{},[21003],{"type":34,"value":21004},"La grande faiblesse des architectures traditionnelles (architecture en couches notamment) tient à l'interconnexion excessive des couches. Prenons un service bancaire qui consulte le solde d'un compte. Si la couche métier dépend directement de la base de données, le moindre changement de schéma oblige à modifier la logique métier. La maintenabilité s'effondre.",{"type":29,"tag":6010,"props":21006,"children":21008},{"id":21007},"une-séparation-claire-le-domaine-au-centre",[21009],{"type":29,"tag":447,"props":21010,"children":21011},{},[21012],{"type":34,"value":21013},"Une séparation claire : le domaine au centre",{"type":29,"tag":30,"props":21015,"children":21016},{},[21017,21019,21023,21025,21030],{"type":34,"value":21018},"L’architecture hexagonale résout ce problème en séparant clairement le domaine métier du reste de l’application. Votre domaine contient toute la logique métier, tandis que les aspects techniques sont gérés par des ",{"type":29,"tag":447,"props":21020,"children":21021},{},[21022],{"type":34,"value":13292},{"type":34,"value":21024},", qui ne sont que des implémentations concrètes de ",{"type":29,"tag":447,"props":21026,"children":21027},{},[21028],{"type":34,"value":21029},"ports",{"type":34,"value":21031}," définis dans le domaine.",{"type":29,"tag":30,"props":21033,"children":21034},{},[21035,21037,21041,21043,21047],{"type":34,"value":21036},"En termes simples, les ",{"type":29,"tag":447,"props":21038,"children":21039},{},[21040],{"type":34,"value":21029},{"type":34,"value":21042}," sont des interfaces qui définissent comment le domaine interagit avec le reste du système, et les ",{"type":29,"tag":447,"props":21044,"children":21045},{},[21046],{"type":34,"value":13292},{"type":34,"value":21048}," sont des implémentations de ces interfaces. Ainsi, vous pouvez changer une implémentation (comme la base de données) sans toucher à votre domaine métier.",{"type":29,"tag":7066,"props":21050,"children":21051},{},[21052],{"type":29,"tag":30,"props":21053,"children":21054},{},[21055,21060],{"type":29,"tag":447,"props":21056,"children":21057},{},[21058],{"type":34,"value":21059},"TIP :",{"type":34,"value":21061}," Gardez en tête que le but de cette architecture est de protéger votre domaine métier des changements technologiques. Cela permet de réduire les risques de \"cascades de modifications\" qui peuvent survenir dans les projets trop couplés à leurs infrastructures.",{"type":29,"tag":6010,"props":21063,"children":21065},{"id":21064},"exemple-un-service-bancaire-en-java",[21066],{"type":29,"tag":447,"props":21067,"children":21068},{},[21069],{"type":34,"value":21070},"Exemple : un service bancaire en Java",{"type":29,"tag":30,"props":21072,"children":21073},{},[21074],{"type":34,"value":21075},"Voici un exemple simple en Java illustrant cette approche.",{"type":29,"tag":30,"props":21077,"children":21078},{},[21079,21084],{"type":29,"tag":447,"props":21080,"children":21081},{},[21082],{"type":34,"value":21083},"Le domaine (Compte et ServiceBancaire)",{"type":34,"value":5854},{"type":29,"tag":77,"props":21086,"children":21088},{"className":81,"code":21087,"language":80,"meta":8,"style":8},"public class Compte {\n    private String id;\n    private double solde;\n\n    public Compte(String id, double solde) {\n        this.id = id;\n        this.solde = solde;\n    }\n\n    public double obtenirSolde() {\n        return this.solde;\n    }\n}\n\npublic interface ComptePort {\n    Compte obtenirCompteParId(String id);\n}\n\npublic class ServiceBancaire {\n    private ComptePort comptePort;\n\n    public ServiceBancaire(ComptePort comptePort) {\n        this.comptePort = comptePort;\n    }\n\n    public double consulterSolde(String idCompte) {\n        Compte compte = comptePort.obtenirCompteParId(idCompte);\n        if (compte == null) {\n            throw new RuntimeException(\"Compte non trouvé !\");\n        }\n        return compte.obtenirSolde();\n    }\n}\n",[21089],{"type":29,"tag":84,"props":21090,"children":21091},{"__ignoreMap":8},[21092,21112,21131,21151,21158,21201,21228,21256,21263,21270,21294,21319,21326,21333,21340,21360,21389,21396,21403,21423,21443,21450,21482,21510,21517,21524,21561,21604,21638,21667,21674,21699,21706],{"type":29,"tag":88,"props":21093,"children":21094},{"class":90,"line":91},[21095,21099,21103,21108],{"type":29,"tag":88,"props":21096,"children":21097},{"style":105},[21098],{"type":34,"value":108},{"type":29,"tag":88,"props":21100,"children":21101},{"style":105},[21102],{"type":34,"value":113},{"type":29,"tag":88,"props":21104,"children":21105},{"style":116},[21106],{"type":34,"value":21107}," Compte",{"type":29,"tag":88,"props":21109,"children":21110},{"style":122},[21111],{"type":34,"value":125},{"type":29,"tag":88,"props":21113,"children":21114},{"class":90,"line":101},[21115,21119,21123,21127],{"type":29,"tag":88,"props":21116,"children":21117},{"style":105},[21118],{"type":34,"value":143},{"type":29,"tag":88,"props":21120,"children":21121},{"style":151},[21122],{"type":34,"value":281},{"type":29,"tag":88,"props":21124,"children":21125},{"style":157},[21126],{"type":34,"value":3435},{"type":29,"tag":88,"props":21128,"children":21129},{"style":122},[21130],{"type":34,"value":424},{"type":29,"tag":88,"props":21132,"children":21133},{"class":90,"line":128},[21134,21138,21142,21147],{"type":29,"tag":88,"props":21135,"children":21136},{"style":105},[21137],{"type":34,"value":143},{"type":29,"tag":88,"props":21139,"children":21140},{"style":105},[21141],{"type":34,"value":11179},{"type":29,"tag":88,"props":21143,"children":21144},{"style":157},[21145],{"type":34,"value":21146}," solde",{"type":29,"tag":88,"props":21148,"children":21149},{"style":122},[21150],{"type":34,"value":424},{"type":29,"tag":88,"props":21152,"children":21153},{"class":90,"line":137},[21154],{"type":29,"tag":88,"props":21155,"children":21156},{"emptyLinePlaceholder":13},[21157],{"type":34,"value":134},{"type":29,"tag":88,"props":21159,"children":21160},{"class":90,"line":211},[21161,21165,21169,21173,21177,21181,21185,21189,21193,21197],{"type":29,"tag":88,"props":21162,"children":21163},{"style":105},[21164],{"type":34,"value":276},{"type":29,"tag":88,"props":21166,"children":21167},{"style":174},[21168],{"type":34,"value":21107},{"type":29,"tag":88,"props":21170,"children":21171},{"style":122},[21172],{"type":34,"value":181},{"type":29,"tag":88,"props":21174,"children":21175},{"style":151},[21176],{"type":34,"value":695},{"type":29,"tag":88,"props":21178,"children":21179},{"style":298},[21180],{"type":34,"value":3435},{"type":29,"tag":88,"props":21182,"children":21183},{"style":122},[21184],{"type":34,"value":192},{"type":29,"tag":88,"props":21186,"children":21187},{"style":105},[21188],{"type":34,"value":11179},{"type":29,"tag":88,"props":21190,"children":21191},{"style":298},[21192],{"type":34,"value":21146},{"type":29,"tag":88,"props":21194,"children":21195},{"style":122},[21196],{"type":34,"value":306},{"type":29,"tag":88,"props":21198,"children":21199},{"style":122},[21200],{"type":34,"value":125},{"type":29,"tag":88,"props":21202,"children":21203},{"class":90,"line":262},[21204,21208,21212,21216,21220,21224],{"type":29,"tag":88,"props":21205,"children":21206},{"style":873},[21207],{"type":34,"value":876},{"type":29,"tag":88,"props":21209,"children":21210},{"style":122},[21211],{"type":34,"value":338},{"type":29,"tag":88,"props":21213,"children":21214},{"style":157},[21215],{"type":34,"value":8325},{"type":29,"tag":88,"props":21217,"children":21218},{"style":163},[21219],{"type":34,"value":166},{"type":29,"tag":88,"props":21221,"children":21222},{"style":157},[21223],{"type":34,"value":3435},{"type":29,"tag":88,"props":21225,"children":21226},{"style":122},[21227],{"type":34,"value":424},{"type":29,"tag":88,"props":21229,"children":21230},{"class":90,"line":270},[21231,21235,21239,21244,21248,21252],{"type":29,"tag":88,"props":21232,"children":21233},{"style":873},[21234],{"type":34,"value":876},{"type":29,"tag":88,"props":21236,"children":21237},{"style":122},[21238],{"type":34,"value":338},{"type":29,"tag":88,"props":21240,"children":21241},{"style":157},[21242],{"type":34,"value":21243},"solde ",{"type":29,"tag":88,"props":21245,"children":21246},{"style":163},[21247],{"type":34,"value":166},{"type":29,"tag":88,"props":21249,"children":21250},{"style":157},[21251],{"type":34,"value":21146},{"type":29,"tag":88,"props":21253,"children":21254},{"style":122},[21255],{"type":34,"value":424},{"type":29,"tag":88,"props":21257,"children":21258},{"class":90,"line":313},[21259],{"type":29,"tag":88,"props":21260,"children":21261},{"style":122},[21262],{"type":34,"value":433},{"type":29,"tag":88,"props":21264,"children":21265},{"class":90,"line":360},[21266],{"type":29,"tag":88,"props":21267,"children":21268},{"emptyLinePlaceholder":13},[21269],{"type":34,"value":134},{"type":29,"tag":88,"props":21271,"children":21272},{"class":90,"line":409},[21273,21277,21281,21286,21290],{"type":29,"tag":88,"props":21274,"children":21275},{"style":105},[21276],{"type":34,"value":276},{"type":29,"tag":88,"props":21278,"children":21279},{"style":105},[21280],{"type":34,"value":11179},{"type":29,"tag":88,"props":21282,"children":21283},{"style":174},[21284],{"type":34,"value":21285}," obtenirSolde",{"type":29,"tag":88,"props":21287,"children":21288},{"style":122},[21289],{"type":34,"value":1470},{"type":29,"tag":88,"props":21291,"children":21292},{"style":122},[21293],{"type":34,"value":125},{"type":29,"tag":88,"props":21295,"children":21296},{"class":90,"line":427},[21297,21301,21306,21310,21315],{"type":29,"tag":88,"props":21298,"children":21299},{"style":105},[21300],{"type":34,"value":415},{"type":29,"tag":88,"props":21302,"children":21303},{"style":873},[21304],{"type":34,"value":21305}," this",{"type":29,"tag":88,"props":21307,"children":21308},{"style":122},[21309],{"type":34,"value":338},{"type":29,"tag":88,"props":21311,"children":21312},{"style":157},[21313],{"type":34,"value":21314},"solde",{"type":29,"tag":88,"props":21316,"children":21317},{"style":122},[21318],{"type":34,"value":424},{"type":29,"tag":88,"props":21320,"children":21321},{"class":90,"line":436},[21322],{"type":29,"tag":88,"props":21323,"children":21324},{"style":122},[21325],{"type":34,"value":433},{"type":29,"tag":88,"props":21327,"children":21328},{"class":90,"line":767},[21329],{"type":29,"tag":88,"props":21330,"children":21331},{"style":122},[21332],{"type":34,"value":442},{"type":29,"tag":88,"props":21334,"children":21335},{"class":90,"line":792},[21336],{"type":29,"tag":88,"props":21337,"children":21338},{"emptyLinePlaceholder":13},[21339],{"type":34,"value":134},{"type":29,"tag":88,"props":21341,"children":21342},{"class":90,"line":817},[21343,21347,21351,21356],{"type":29,"tag":88,"props":21344,"children":21345},{"style":105},[21346],{"type":34,"value":108},{"type":29,"tag":88,"props":21348,"children":21349},{"style":105},[21350],{"type":34,"value":601},{"type":29,"tag":88,"props":21352,"children":21353},{"style":116},[21354],{"type":34,"value":21355}," ComptePort",{"type":29,"tag":88,"props":21357,"children":21358},{"style":122},[21359],{"type":34,"value":125},{"type":29,"tag":88,"props":21361,"children":21362},{"class":90,"line":825},[21363,21368,21373,21377,21381,21385],{"type":29,"tag":88,"props":21364,"children":21365},{"style":151},[21366],{"type":34,"value":21367},"    Compte",{"type":29,"tag":88,"props":21369,"children":21370},{"style":174},[21371],{"type":34,"value":21372}," obtenirCompteParId",{"type":29,"tag":88,"props":21374,"children":21375},{"style":122},[21376],{"type":34,"value":181},{"type":29,"tag":88,"props":21378,"children":21379},{"style":151},[21380],{"type":34,"value":695},{"type":29,"tag":88,"props":21382,"children":21383},{"style":298},[21384],{"type":34,"value":3435},{"type":29,"tag":88,"props":21386,"children":21387},{"style":122},[21388],{"type":34,"value":357},{"type":29,"tag":88,"props":21390,"children":21391},{"class":90,"line":869},[21392],{"type":29,"tag":88,"props":21393,"children":21394},{"style":122},[21395],{"type":34,"value":442},{"type":29,"tag":88,"props":21397,"children":21398},{"class":90,"line":900},[21399],{"type":29,"tag":88,"props":21400,"children":21401},{"emptyLinePlaceholder":13},[21402],{"type":34,"value":134},{"type":29,"tag":88,"props":21404,"children":21405},{"class":90,"line":929},[21406,21410,21414,21419],{"type":29,"tag":88,"props":21407,"children":21408},{"style":105},[21409],{"type":34,"value":108},{"type":29,"tag":88,"props":21411,"children":21412},{"style":105},[21413],{"type":34,"value":113},{"type":29,"tag":88,"props":21415,"children":21416},{"style":116},[21417],{"type":34,"value":21418}," ServiceBancaire",{"type":29,"tag":88,"props":21420,"children":21421},{"style":122},[21422],{"type":34,"value":125},{"type":29,"tag":88,"props":21424,"children":21425},{"class":90,"line":937},[21426,21430,21434,21439],{"type":29,"tag":88,"props":21427,"children":21428},{"style":105},[21429],{"type":34,"value":143},{"type":29,"tag":88,"props":21431,"children":21432},{"style":151},[21433],{"type":34,"value":21355},{"type":29,"tag":88,"props":21435,"children":21436},{"style":157},[21437],{"type":34,"value":21438}," comptePort",{"type":29,"tag":88,"props":21440,"children":21441},{"style":122},[21442],{"type":34,"value":424},{"type":29,"tag":88,"props":21444,"children":21445},{"class":90,"line":945},[21446],{"type":29,"tag":88,"props":21447,"children":21448},{"emptyLinePlaceholder":13},[21449],{"type":34,"value":134},{"type":29,"tag":88,"props":21451,"children":21452},{"class":90,"line":981},[21453,21457,21461,21465,21470,21474,21478],{"type":29,"tag":88,"props":21454,"children":21455},{"style":105},[21456],{"type":34,"value":276},{"type":29,"tag":88,"props":21458,"children":21459},{"style":174},[21460],{"type":34,"value":21418},{"type":29,"tag":88,"props":21462,"children":21463},{"style":122},[21464],{"type":34,"value":181},{"type":29,"tag":88,"props":21466,"children":21467},{"style":151},[21468],{"type":34,"value":21469},"ComptePort",{"type":29,"tag":88,"props":21471,"children":21472},{"style":298},[21473],{"type":34,"value":21438},{"type":29,"tag":88,"props":21475,"children":21476},{"style":122},[21477],{"type":34,"value":306},{"type":29,"tag":88,"props":21479,"children":21480},{"style":122},[21481],{"type":34,"value":125},{"type":29,"tag":88,"props":21483,"children":21484},{"class":90,"line":1021},[21485,21489,21493,21498,21502,21506],{"type":29,"tag":88,"props":21486,"children":21487},{"style":873},[21488],{"type":34,"value":876},{"type":29,"tag":88,"props":21490,"children":21491},{"style":122},[21492],{"type":34,"value":338},{"type":29,"tag":88,"props":21494,"children":21495},{"style":157},[21496],{"type":34,"value":21497},"comptePort ",{"type":29,"tag":88,"props":21499,"children":21500},{"style":163},[21501],{"type":34,"value":166},{"type":29,"tag":88,"props":21503,"children":21504},{"style":157},[21505],{"type":34,"value":21438},{"type":29,"tag":88,"props":21507,"children":21508},{"style":122},[21509],{"type":34,"value":424},{"type":29,"tag":88,"props":21511,"children":21512},{"class":90,"line":1066},[21513],{"type":29,"tag":88,"props":21514,"children":21515},{"style":122},[21516],{"type":34,"value":433},{"type":29,"tag":88,"props":21518,"children":21519},{"class":90,"line":1082},[21520],{"type":29,"tag":88,"props":21521,"children":21522},{"emptyLinePlaceholder":13},[21523],{"type":34,"value":134},{"type":29,"tag":88,"props":21525,"children":21526},{"class":90,"line":1090},[21527,21531,21535,21540,21544,21548,21553,21557],{"type":29,"tag":88,"props":21528,"children":21529},{"style":105},[21530],{"type":34,"value":276},{"type":29,"tag":88,"props":21532,"children":21533},{"style":105},[21534],{"type":34,"value":11179},{"type":29,"tag":88,"props":21536,"children":21537},{"style":174},[21538],{"type":34,"value":21539}," consulterSolde",{"type":29,"tag":88,"props":21541,"children":21542},{"style":122},[21543],{"type":34,"value":181},{"type":29,"tag":88,"props":21545,"children":21546},{"style":151},[21547],{"type":34,"value":695},{"type":29,"tag":88,"props":21549,"children":21550},{"style":298},[21551],{"type":34,"value":21552}," idCompte",{"type":29,"tag":88,"props":21554,"children":21555},{"style":122},[21556],{"type":34,"value":306},{"type":29,"tag":88,"props":21558,"children":21559},{"style":122},[21560],{"type":34,"value":125},{"type":29,"tag":88,"props":21562,"children":21563},{"class":90,"line":1098},[21564,21569,21574,21578,21582,21586,21591,21595,21600],{"type":29,"tag":88,"props":21565,"children":21566},{"style":151},[21567],{"type":34,"value":21568},"        Compte",{"type":29,"tag":88,"props":21570,"children":21571},{"style":157},[21572],{"type":34,"value":21573}," compte ",{"type":29,"tag":88,"props":21575,"children":21576},{"style":163},[21577],{"type":34,"value":166},{"type":29,"tag":88,"props":21579,"children":21580},{"style":157},[21581],{"type":34,"value":21438},{"type":29,"tag":88,"props":21583,"children":21584},{"style":122},[21585],{"type":34,"value":338},{"type":29,"tag":88,"props":21587,"children":21588},{"style":174},[21589],{"type":34,"value":21590},"obtenirCompteParId",{"type":29,"tag":88,"props":21592,"children":21593},{"style":122},[21594],{"type":34,"value":181},{"type":29,"tag":88,"props":21596,"children":21597},{"style":157},[21598],{"type":34,"value":21599},"idCompte",{"type":29,"tag":88,"props":21601,"children":21602},{"style":122},[21603],{"type":34,"value":357},{"type":29,"tag":88,"props":21605,"children":21606},{"class":90,"line":1106},[21607,21611,21615,21620,21625,21630,21634],{"type":29,"tag":88,"props":21608,"children":21609},{"style":105},[21610],{"type":34,"value":2886},{"type":29,"tag":88,"props":21612,"children":21613},{"style":122},[21614],{"type":34,"value":2891},{"type":29,"tag":88,"props":21616,"children":21617},{"style":157},[21618],{"type":34,"value":21619},"compte ",{"type":29,"tag":88,"props":21621,"children":21622},{"style":163},[21623],{"type":34,"value":21624},"==",{"type":29,"tag":88,"props":21626,"children":21627},{"style":873},[21628],{"type":34,"value":21629}," null",{"type":29,"tag":88,"props":21631,"children":21632},{"style":122},[21633],{"type":34,"value":306},{"type":29,"tag":88,"props":21635,"children":21636},{"style":122},[21637],{"type":34,"value":125},{"type":29,"tag":88,"props":21639,"children":21640},{"class":90,"line":1115},[21641,21645,21649,21654,21658,21663],{"type":29,"tag":88,"props":21642,"children":21643},{"style":105},[21644],{"type":34,"value":2927},{"type":29,"tag":88,"props":21646,"children":21647},{"style":105},[21648],{"type":34,"value":171},{"type":29,"tag":88,"props":21650,"children":21651},{"style":174},[21652],{"type":34,"value":21653}," RuntimeException",{"type":29,"tag":88,"props":21655,"children":21656},{"style":122},[21657],{"type":34,"value":181},{"type":29,"tag":88,"props":21659,"children":21660},{"style":184},[21661],{"type":34,"value":21662},"\"Compte non trouvé !\"",{"type":29,"tag":88,"props":21664,"children":21665},{"style":122},[21666],{"type":34,"value":357},{"type":29,"tag":88,"props":21668,"children":21669},{"class":90,"line":11},[21670],{"type":29,"tag":88,"props":21671,"children":21672},{"style":122},[21673],{"type":34,"value":2966},{"type":29,"tag":88,"props":21675,"children":21676},{"class":90,"line":1180},[21677,21681,21686,21690,21695],{"type":29,"tag":88,"props":21678,"children":21679},{"style":105},[21680],{"type":34,"value":415},{"type":29,"tag":88,"props":21682,"children":21683},{"style":157},[21684],{"type":34,"value":21685}," compte",{"type":29,"tag":88,"props":21687,"children":21688},{"style":122},[21689],{"type":34,"value":338},{"type":29,"tag":88,"props":21691,"children":21692},{"style":174},[21693],{"type":34,"value":21694},"obtenirSolde",{"type":29,"tag":88,"props":21696,"children":21697},{"style":122},[21698],{"type":34,"value":1810},{"type":29,"tag":88,"props":21700,"children":21701},{"class":90,"line":1240},[21702],{"type":29,"tag":88,"props":21703,"children":21704},{"style":122},[21705],{"type":34,"value":433},{"type":29,"tag":88,"props":21707,"children":21708},{"class":90,"line":1248},[21709],{"type":29,"tag":88,"props":21710,"children":21711},{"style":122},[21712],{"type":34,"value":442},{"type":29,"tag":30,"props":21714,"children":21715},{},[21716,21721],{"type":29,"tag":447,"props":21717,"children":21718},{},[21719],{"type":34,"value":21720},"L’implémentation de l'Adapter dans l'infrastructure (Infra)",{"type":34,"value":5854},{"type":29,"tag":77,"props":21723,"children":21725},{"className":81,"code":21724,"language":80,"meta":8,"style":8},"public class CompteAdapter implements ComptePort {\n    private Map\u003CString, Compte> baseDeDonnees;\n\n    public CompteAdapter() {\n        baseDeDonnees = new HashMap\u003C>();\n        baseDeDonnees.put(\"123\", new Compte(\"123\", 1500.0));\n        baseDeDonnees.put(\"456\", new Compte(\"456\", 2500.0));\n    }\n\n    @Override\n    public Compte obtenirCompteParId(String id) {\n        return baseDeDonnees.get(id);\n    }\n}\n",[21726],{"type":29,"tag":84,"props":21727,"children":21728},{"__ignoreMap":8},[21729,21757,21797,21804,21823,21847,21905,21962,21969,21976,21987,22022,22053,22060],{"type":29,"tag":88,"props":21730,"children":21731},{"class":90,"line":91},[21732,21736,21740,21745,21749,21753],{"type":29,"tag":88,"props":21733,"children":21734},{"style":105},[21735],{"type":34,"value":108},{"type":29,"tag":88,"props":21737,"children":21738},{"style":105},[21739],{"type":34,"value":113},{"type":29,"tag":88,"props":21741,"children":21742},{"style":116},[21743],{"type":34,"value":21744}," CompteAdapter",{"type":29,"tag":88,"props":21746,"children":21747},{"style":105},[21748],{"type":34,"value":1134},{"type":29,"tag":88,"props":21750,"children":21751},{"style":116},[21752],{"type":34,"value":21355},{"type":29,"tag":88,"props":21754,"children":21755},{"style":122},[21756],{"type":34,"value":125},{"type":29,"tag":88,"props":21758,"children":21759},{"class":90,"line":101},[21760,21764,21768,21772,21776,21780,21784,21788,21793],{"type":29,"tag":88,"props":21761,"children":21762},{"style":105},[21763],{"type":34,"value":143},{"type":29,"tag":88,"props":21765,"children":21766},{"style":151},[21767],{"type":34,"value":1384},{"type":29,"tag":88,"props":21769,"children":21770},{"style":122},[21771],{"type":34,"value":1683},{"type":29,"tag":88,"props":21773,"children":21774},{"style":105},[21775],{"type":34,"value":695},{"type":29,"tag":88,"props":21777,"children":21778},{"style":122},[21779],{"type":34,"value":192},{"type":29,"tag":88,"props":21781,"children":21782},{"style":105},[21783],{"type":34,"value":21107},{"type":29,"tag":88,"props":21785,"children":21786},{"style":122},[21787],{"type":34,"value":1701},{"type":29,"tag":88,"props":21789,"children":21790},{"style":157},[21791],{"type":34,"value":21792}," baseDeDonnees",{"type":29,"tag":88,"props":21794,"children":21795},{"style":122},[21796],{"type":34,"value":424},{"type":29,"tag":88,"props":21798,"children":21799},{"class":90,"line":128},[21800],{"type":29,"tag":88,"props":21801,"children":21802},{"emptyLinePlaceholder":13},[21803],{"type":34,"value":134},{"type":29,"tag":88,"props":21805,"children":21806},{"class":90,"line":137},[21807,21811,21815,21819],{"type":29,"tag":88,"props":21808,"children":21809},{"style":105},[21810],{"type":34,"value":276},{"type":29,"tag":88,"props":21812,"children":21813},{"style":174},[21814],{"type":34,"value":21744},{"type":29,"tag":88,"props":21816,"children":21817},{"style":122},[21818],{"type":34,"value":1470},{"type":29,"tag":88,"props":21820,"children":21821},{"style":122},[21822],{"type":34,"value":125},{"type":29,"tag":88,"props":21824,"children":21825},{"class":90,"line":211},[21826,21831,21835,21839,21843],{"type":29,"tag":88,"props":21827,"children":21828},{"style":157},[21829],{"type":34,"value":21830},"        baseDeDonnees ",{"type":29,"tag":88,"props":21832,"children":21833},{"style":163},[21834],{"type":34,"value":166},{"type":29,"tag":88,"props":21836,"children":21837},{"style":105},[21838],{"type":34,"value":171},{"type":29,"tag":88,"props":21840,"children":21841},{"style":151},[21842],{"type":34,"value":1719},{"type":29,"tag":88,"props":21844,"children":21845},{"style":122},[21846],{"type":34,"value":1724},{"type":29,"tag":88,"props":21848,"children":21849},{"class":90,"line":262},[21850,21855,21859,21863,21867,21872,21876,21880,21884,21888,21892,21896,21901],{"type":29,"tag":88,"props":21851,"children":21852},{"style":157},[21853],{"type":34,"value":21854},"        baseDeDonnees",{"type":29,"tag":88,"props":21856,"children":21857},{"style":122},[21858],{"type":34,"value":338},{"type":29,"tag":88,"props":21860,"children":21861},{"style":174},[21862],{"type":34,"value":1827},{"type":29,"tag":88,"props":21864,"children":21865},{"style":122},[21866],{"type":34,"value":181},{"type":29,"tag":88,"props":21868,"children":21869},{"style":184},[21870],{"type":34,"value":21871},"\"123\"",{"type":29,"tag":88,"props":21873,"children":21874},{"style":122},[21875],{"type":34,"value":192},{"type":29,"tag":88,"props":21877,"children":21878},{"style":105},[21879],{"type":34,"value":171},{"type":29,"tag":88,"props":21881,"children":21882},{"style":174},[21883],{"type":34,"value":21107},{"type":29,"tag":88,"props":21885,"children":21886},{"style":122},[21887],{"type":34,"value":181},{"type":29,"tag":88,"props":21889,"children":21890},{"style":184},[21891],{"type":34,"value":21871},{"type":29,"tag":88,"props":21893,"children":21894},{"style":122},[21895],{"type":34,"value":192},{"type":29,"tag":88,"props":21897,"children":21898},{"style":195},[21899],{"type":34,"value":21900}," 1500.0",{"type":29,"tag":88,"props":21902,"children":21903},{"style":122},[21904],{"type":34,"value":1415},{"type":29,"tag":88,"props":21906,"children":21907},{"class":90,"line":270},[21908,21912,21916,21920,21924,21929,21933,21937,21941,21945,21949,21953,21958],{"type":29,"tag":88,"props":21909,"children":21910},{"style":157},[21911],{"type":34,"value":21854},{"type":29,"tag":88,"props":21913,"children":21914},{"style":122},[21915],{"type":34,"value":338},{"type":29,"tag":88,"props":21917,"children":21918},{"style":174},[21919],{"type":34,"value":1827},{"type":29,"tag":88,"props":21921,"children":21922},{"style":122},[21923],{"type":34,"value":181},{"type":29,"tag":88,"props":21925,"children":21926},{"style":184},[21927],{"type":34,"value":21928},"\"456\"",{"type":29,"tag":88,"props":21930,"children":21931},{"style":122},[21932],{"type":34,"value":192},{"type":29,"tag":88,"props":21934,"children":21935},{"style":105},[21936],{"type":34,"value":171},{"type":29,"tag":88,"props":21938,"children":21939},{"style":174},[21940],{"type":34,"value":21107},{"type":29,"tag":88,"props":21942,"children":21943},{"style":122},[21944],{"type":34,"value":181},{"type":29,"tag":88,"props":21946,"children":21947},{"style":184},[21948],{"type":34,"value":21928},{"type":29,"tag":88,"props":21950,"children":21951},{"style":122},[21952],{"type":34,"value":192},{"type":29,"tag":88,"props":21954,"children":21955},{"style":195},[21956],{"type":34,"value":21957}," 2500.0",{"type":29,"tag":88,"props":21959,"children":21960},{"style":122},[21961],{"type":34,"value":1415},{"type":29,"tag":88,"props":21963,"children":21964},{"class":90,"line":313},[21965],{"type":29,"tag":88,"props":21966,"children":21967},{"style":122},[21968],{"type":34,"value":433},{"type":29,"tag":88,"props":21970,"children":21971},{"class":90,"line":360},[21972],{"type":29,"tag":88,"props":21973,"children":21974},{"emptyLinePlaceholder":13},[21975],{"type":34,"value":134},{"type":29,"tag":88,"props":21977,"children":21978},{"class":90,"line":409},[21979,21983],{"type":29,"tag":88,"props":21980,"children":21981},{"style":1974},[21982],{"type":34,"value":3302},{"type":29,"tag":88,"props":21984,"children":21985},{"style":1980},[21986],{"type":34,"value":3307},{"type":29,"tag":88,"props":21988,"children":21989},{"class":90,"line":427},[21990,21994,21998,22002,22006,22010,22014,22018],{"type":29,"tag":88,"props":21991,"children":21992},{"style":105},[21993],{"type":34,"value":276},{"type":29,"tag":88,"props":21995,"children":21996},{"style":151},[21997],{"type":34,"value":21107},{"type":29,"tag":88,"props":21999,"children":22000},{"style":174},[22001],{"type":34,"value":21372},{"type":29,"tag":88,"props":22003,"children":22004},{"style":122},[22005],{"type":34,"value":181},{"type":29,"tag":88,"props":22007,"children":22008},{"style":151},[22009],{"type":34,"value":695},{"type":29,"tag":88,"props":22011,"children":22012},{"style":298},[22013],{"type":34,"value":3435},{"type":29,"tag":88,"props":22015,"children":22016},{"style":122},[22017],{"type":34,"value":306},{"type":29,"tag":88,"props":22019,"children":22020},{"style":122},[22021],{"type":34,"value":125},{"type":29,"tag":88,"props":22023,"children":22024},{"class":90,"line":436},[22025,22029,22033,22037,22041,22045,22049],{"type":29,"tag":88,"props":22026,"children":22027},{"style":105},[22028],{"type":34,"value":415},{"type":29,"tag":88,"props":22030,"children":22031},{"style":157},[22032],{"type":34,"value":21792},{"type":29,"tag":88,"props":22034,"children":22035},{"style":122},[22036],{"type":34,"value":338},{"type":29,"tag":88,"props":22038,"children":22039},{"style":174},[22040],{"type":34,"value":3555},{"type":29,"tag":88,"props":22042,"children":22043},{"style":122},[22044],{"type":34,"value":181},{"type":29,"tag":88,"props":22046,"children":22047},{"style":157},[22048],{"type":34,"value":3410},{"type":29,"tag":88,"props":22050,"children":22051},{"style":122},[22052],{"type":34,"value":357},{"type":29,"tag":88,"props":22054,"children":22055},{"class":90,"line":767},[22056],{"type":29,"tag":88,"props":22057,"children":22058},{"style":122},[22059],{"type":34,"value":433},{"type":29,"tag":88,"props":22061,"children":22062},{"class":90,"line":792},[22063],{"type":29,"tag":88,"props":22064,"children":22065},{"style":122},[22066],{"type":34,"value":442},{"type":29,"tag":30,"props":22068,"children":22069},{},[22070,22075],{"type":29,"tag":447,"props":22071,"children":22072},{},[22073],{"type":34,"value":22074},"Application principale (Main)",{"type":34,"value":5854},{"type":29,"tag":77,"props":22077,"children":22079},{"className":81,"code":22078,"language":80,"meta":8,"style":8},"public class Main {\n    public static void main(String[] args) {\n        CompteAdapter compteAdapter = new CompteAdapter();\n        ServiceBancaire serviceBancaire = new ServiceBancaire(compteAdapter);\n\n        String idCompte = \"123\";\n        double solde = serviceBancaire.consulterSolde(idCompte);\n\n        System.out.println(\"Le solde du compte \" + idCompte + \" est de \" + solde + \" €.\");\n    }\n}\n",[22080],{"type":29,"tag":84,"props":22081,"children":22082},{"__ignoreMap":8},[22083,22103,22150,22179,22217,22224,22249,22291,22298,22371,22378],{"type":29,"tag":88,"props":22084,"children":22085},{"class":90,"line":91},[22086,22090,22094,22099],{"type":29,"tag":88,"props":22087,"children":22088},{"style":105},[22089],{"type":34,"value":108},{"type":29,"tag":88,"props":22091,"children":22092},{"style":105},[22093],{"type":34,"value":113},{"type":29,"tag":88,"props":22095,"children":22096},{"style":116},[22097],{"type":34,"value":22098}," Main",{"type":29,"tag":88,"props":22100,"children":22101},{"style":122},[22102],{"type":34,"value":125},{"type":29,"tag":88,"props":22104,"children":22105},{"class":90,"line":101},[22106,22110,22115,22119,22124,22128,22132,22137,22142,22146],{"type":29,"tag":88,"props":22107,"children":22108},{"style":105},[22109],{"type":34,"value":276},{"type":29,"tag":88,"props":22111,"children":22112},{"style":105},[22113],{"type":34,"value":22114}," static",{"type":29,"tag":88,"props":22116,"children":22117},{"style":105},[22118],{"type":34,"value":1303},{"type":29,"tag":88,"props":22120,"children":22121},{"style":174},[22122],{"type":34,"value":22123}," main",{"type":29,"tag":88,"props":22125,"children":22126},{"style":122},[22127],{"type":34,"value":181},{"type":29,"tag":88,"props":22129,"children":22130},{"style":105},[22131],{"type":34,"value":695},{"type":29,"tag":88,"props":22133,"children":22134},{"style":122},[22135],{"type":34,"value":22136},"[]",{"type":29,"tag":88,"props":22138,"children":22139},{"style":298},[22140],{"type":34,"value":22141}," args",{"type":29,"tag":88,"props":22143,"children":22144},{"style":122},[22145],{"type":34,"value":306},{"type":29,"tag":88,"props":22147,"children":22148},{"style":122},[22149],{"type":34,"value":125},{"type":29,"tag":88,"props":22151,"children":22152},{"class":90,"line":128},[22153,22158,22163,22167,22171,22175],{"type":29,"tag":88,"props":22154,"children":22155},{"style":151},[22156],{"type":34,"value":22157},"        CompteAdapter",{"type":29,"tag":88,"props":22159,"children":22160},{"style":157},[22161],{"type":34,"value":22162}," compteAdapter ",{"type":29,"tag":88,"props":22164,"children":22165},{"style":163},[22166],{"type":34,"value":166},{"type":29,"tag":88,"props":22168,"children":22169},{"style":105},[22170],{"type":34,"value":171},{"type":29,"tag":88,"props":22172,"children":22173},{"style":174},[22174],{"type":34,"value":21744},{"type":29,"tag":88,"props":22176,"children":22177},{"style":122},[22178],{"type":34,"value":1810},{"type":29,"tag":88,"props":22180,"children":22181},{"class":90,"line":137},[22182,22187,22192,22196,22200,22204,22208,22213],{"type":29,"tag":88,"props":22183,"children":22184},{"style":151},[22185],{"type":34,"value":22186},"        ServiceBancaire",{"type":29,"tag":88,"props":22188,"children":22189},{"style":157},[22190],{"type":34,"value":22191}," serviceBancaire ",{"type":29,"tag":88,"props":22193,"children":22194},{"style":163},[22195],{"type":34,"value":166},{"type":29,"tag":88,"props":22197,"children":22198},{"style":105},[22199],{"type":34,"value":171},{"type":29,"tag":88,"props":22201,"children":22202},{"style":174},[22203],{"type":34,"value":21418},{"type":29,"tag":88,"props":22205,"children":22206},{"style":122},[22207],{"type":34,"value":181},{"type":29,"tag":88,"props":22209,"children":22210},{"style":157},[22211],{"type":34,"value":22212},"compteAdapter",{"type":29,"tag":88,"props":22214,"children":22215},{"style":122},[22216],{"type":34,"value":357},{"type":29,"tag":88,"props":22218,"children":22219},{"class":90,"line":211},[22220],{"type":29,"tag":88,"props":22221,"children":22222},{"emptyLinePlaceholder":13},[22223],{"type":34,"value":134},{"type":29,"tag":88,"props":22225,"children":22226},{"class":90,"line":262},[22227,22231,22236,22240,22245],{"type":29,"tag":88,"props":22228,"children":22229},{"style":151},[22230],{"type":34,"value":319},{"type":29,"tag":88,"props":22232,"children":22233},{"style":157},[22234],{"type":34,"value":22235}," idCompte ",{"type":29,"tag":88,"props":22237,"children":22238},{"style":163},[22239],{"type":34,"value":166},{"type":29,"tag":88,"props":22241,"children":22242},{"style":184},[22243],{"type":34,"value":22244}," \"123\"",{"type":29,"tag":88,"props":22246,"children":22247},{"style":122},[22248],{"type":34,"value":424},{"type":29,"tag":88,"props":22250,"children":22251},{"class":90,"line":270},[22252,22256,22261,22265,22270,22274,22279,22283,22287],{"type":29,"tag":88,"props":22253,"children":22254},{"style":105},[22255],{"type":34,"value":15719},{"type":29,"tag":88,"props":22257,"children":22258},{"style":157},[22259],{"type":34,"value":22260}," solde ",{"type":29,"tag":88,"props":22262,"children":22263},{"style":163},[22264],{"type":34,"value":166},{"type":29,"tag":88,"props":22266,"children":22267},{"style":157},[22268],{"type":34,"value":22269}," serviceBancaire",{"type":29,"tag":88,"props":22271,"children":22272},{"style":122},[22273],{"type":34,"value":338},{"type":29,"tag":88,"props":22275,"children":22276},{"style":174},[22277],{"type":34,"value":22278},"consulterSolde",{"type":29,"tag":88,"props":22280,"children":22281},{"style":122},[22282],{"type":34,"value":181},{"type":29,"tag":88,"props":22284,"children":22285},{"style":157},[22286],{"type":34,"value":21599},{"type":29,"tag":88,"props":22288,"children":22289},{"style":122},[22290],{"type":34,"value":357},{"type":29,"tag":88,"props":22292,"children":22293},{"class":90,"line":313},[22294],{"type":29,"tag":88,"props":22295,"children":22296},{"emptyLinePlaceholder":13},[22297],{"type":34,"value":134},{"type":29,"tag":88,"props":22299,"children":22300},{"class":90,"line":360},[22301,22306,22310,22315,22319,22324,22328,22333,22337,22341,22345,22350,22354,22358,22362,22367],{"type":29,"tag":88,"props":22302,"children":22303},{"style":157},[22304],{"type":34,"value":22305},"        System",{"type":29,"tag":88,"props":22307,"children":22308},{"style":122},[22309],{"type":34,"value":338},{"type":29,"tag":88,"props":22311,"children":22312},{"style":157},[22313],{"type":34,"value":22314},"out",{"type":29,"tag":88,"props":22316,"children":22317},{"style":122},[22318],{"type":34,"value":338},{"type":29,"tag":88,"props":22320,"children":22321},{"style":174},[22322],{"type":34,"value":22323},"println",{"type":29,"tag":88,"props":22325,"children":22326},{"style":122},[22327],{"type":34,"value":181},{"type":29,"tag":88,"props":22329,"children":22330},{"style":184},[22331],{"type":34,"value":22332},"\"Le solde du compte \"",{"type":29,"tag":88,"props":22334,"children":22335},{"style":163},[22336],{"type":34,"value":5485},{"type":29,"tag":88,"props":22338,"children":22339},{"style":157},[22340],{"type":34,"value":22235},{"type":29,"tag":88,"props":22342,"children":22343},{"style":163},[22344],{"type":34,"value":5495},{"type":29,"tag":88,"props":22346,"children":22347},{"style":184},[22348],{"type":34,"value":22349}," \" est de \"",{"type":29,"tag":88,"props":22351,"children":22352},{"style":163},[22353],{"type":34,"value":5485},{"type":29,"tag":88,"props":22355,"children":22356},{"style":157},[22357],{"type":34,"value":22260},{"type":29,"tag":88,"props":22359,"children":22360},{"style":163},[22361],{"type":34,"value":5495},{"type":29,"tag":88,"props":22363,"children":22364},{"style":184},[22365],{"type":34,"value":22366}," \" €.\"",{"type":29,"tag":88,"props":22368,"children":22369},{"style":122},[22370],{"type":34,"value":357},{"type":29,"tag":88,"props":22372,"children":22373},{"class":90,"line":409},[22374],{"type":29,"tag":88,"props":22375,"children":22376},{"style":122},[22377],{"type":34,"value":433},{"type":29,"tag":88,"props":22379,"children":22380},{"class":90,"line":427},[22381],{"type":29,"tag":88,"props":22382,"children":22383},{"style":122},[22384],{"type":34,"value":442},{"type":29,"tag":7066,"props":22386,"children":22387},{},[22388],{"type":29,"tag":30,"props":22389,"children":22390},{},[22391,22396,22398,22402],{"type":29,"tag":447,"props":22392,"children":22393},{},[22394],{"type":34,"value":22395},"ALERT :",{"type":34,"value":22397}," N'oubliez pas que les ",{"type":29,"tag":447,"props":22399,"children":22400},{},[22401],{"type":34,"value":21029},{"type":34,"value":22403}," sont des abstractions du domaine métier. Ils doivent rester indépendants des technologies utilisées dans les adapters (comme une base de données). Cela vous évite de lier votre domaine métier à une technologie particulière.",{"type":29,"tag":47,"props":22405,"children":22406},{},[],{"type":29,"tag":2288,"props":22408,"children":22410},{"cta":2290,"href":2291,"title":22409,"type":2293},"Vous voulez savoir où placer la frontière entre domaine et infrastructure sans hésiter ?",[22411,22416],{"type":29,"tag":30,"props":22412,"children":22413},{},[22414],{"type":34,"value":22415},"Découper ports et adapters proprement, ça ne s'apprend pas en recopiant un exemple : ça se travaille sur votre vrai code, avec ses zones grises. En mentoring 1:1, je relis vos couches avec vous, on isole le domaine pas à pas, et vous repartez avec le réflexe de poser les bonnes interfaces avant que le couplage s'installe.",{"type":29,"tag":30,"props":22417,"children":22418},{},[22419],{"type":34,"value":22420},"Vous montez en niveau sur du concret, pas sur des slides.",{"type":29,"tag":51,"props":22422,"children":22424},{"id":22423},"avantages-de-larchitecture-hexagonale",[22425],{"type":29,"tag":447,"props":22426,"children":22427},{},[22428],{"type":34,"value":22429},"Avantages de l'architecture hexagonale",{"type":29,"tag":30,"props":22431,"children":22432},{},[22433],{"type":34,"value":22434},"Les bénéfices concrets observés en adoptant cette architecture sur le terrain.",{"type":29,"tag":6010,"props":22436,"children":22438},{"id":22437},"_1-modularité-et-testabilité",[22439,22441],{"type":34,"value":22440},"1. ",{"type":29,"tag":447,"props":22442,"children":22443},{},[22444],{"type":34,"value":22445},"Modularité et testabilité",{"type":29,"tag":30,"props":22447,"children":22448},{},[22449,22451,22456,22458,22463],{"type":34,"value":22450},"En isolant la logique métier des détails techniques, vous obtenez un code beaucoup plus ",{"type":29,"tag":447,"props":22452,"children":22453},{},[22454],{"type":34,"value":22455},"modulaire",{"type":34,"value":22457},". Vous pouvez remplacer les adaptateurs (comme la base de données) sans toucher à la logique métier. Cela facilite également les tests : vous pouvez ",{"type":29,"tag":447,"props":22459,"children":22460},{},[22461],{"type":34,"value":22462},"mock",{"type":34,"value":22464}," les adaptateurs pour tester votre domaine métier sans avoir besoin d'une vraie base de données.",{"type":29,"tag":7066,"props":22466,"children":22467},{},[22468],{"type":29,"tag":30,"props":22469,"children":22470},{},[22471,22475],{"type":29,"tag":447,"props":22472,"children":22473},{},[22474],{"type":34,"value":21059},{"type":34,"value":22476}," Utiliser des mocks pour simuler vos adapters dans les tests est une excellente pratique. Cela vous permet de tester votre logique métier indépendamment de la configuration des systèmes externes comme les bases de données ou les services tiers.",{"type":29,"tag":6010,"props":22478,"children":22480},{"id":22479},"_2-adaptabilité-et-flexibilité",[22481,22483],{"type":34,"value":22482},"2. ",{"type":29,"tag":447,"props":22484,"children":22485},{},[22486],{"type":34,"value":22487},"Adaptabilité et flexibilité",{"type":29,"tag":30,"props":22489,"children":22490},{},[22491],{"type":34,"value":22492},"L’architecture hexagonale vous permet d'ajouter ou de modifier facilement des composants. Si vous décidez d’ajouter une nouvelle interface utilisateur, par exemple une API REST, il suffit d’ajouter un nouvel adapter pour transformer les requêtes HTTP en appels au domaine.",{"type":29,"tag":6010,"props":22494,"children":22496},{"id":22495},"_3-simplicité-des-changements-dans-linfrastructure",[22497,22499],{"type":34,"value":22498},"3. ",{"type":29,"tag":447,"props":22500,"children":22501},{},[22502],{"type":34,"value":22503},"Simplicité des changements dans l'infrastructure",{"type":29,"tag":30,"props":22505,"children":22506},{},[22507],{"type":34,"value":22508},"Un autre grand avantage est la possibilité de changer l’infrastructure sans impacter le domaine. Si vous devez changer de base de données ou d'outil de communication, le domaine reste intact, et seuls les adaptateurs doivent être modifiés.",{"type":29,"tag":47,"props":22510,"children":22511},{},[],{"type":29,"tag":51,"props":22513,"children":22515},{"id":22514},"bonnes-pratiques-et-pièges-à-éviter",[22516],{"type":29,"tag":447,"props":22517,"children":22518},{},[22519],{"type":34,"value":22520},"Bonnes pratiques et pièges à éviter",{"type":29,"tag":30,"props":22522,"children":22523},{},[22524],{"type":34,"value":22525},"L’architecture hexagonale a de nombreux avantages, mais il est essentiel de l’adopter correctement. Voici quelques bonnes pratiques.",{"type":29,"tag":6010,"props":22527,"children":22529},{"id":22528},"_1-ne-pas-sur-ingénier-le-projet",[22530,22531],{"type":34,"value":22440},{"type":29,"tag":447,"props":22532,"children":22533},{},[22534],{"type":34,"value":22535},"Ne pas sur-ingénier le projet",{"type":29,"tag":30,"props":22537,"children":22538},{},[22539,22541,22546,22547,22552],{"type":34,"value":22540},"N’essayez pas de rendre votre projet inutilement complexe. Si vous commencez à ajouter trop d’interfaces et de couches abstraites, vous risquez de rendre votre code plus difficile à comprendre et à maintenir. Gardez-le ",{"type":29,"tag":447,"props":22542,"children":22543},{},[22544],{"type":34,"value":22545},"simple",{"type":34,"value":18104},{"type":29,"tag":447,"props":22548,"children":22549},{},[22550],{"type":34,"value":22551},"pragmatique",{"type":34,"value":338},{"type":29,"tag":7066,"props":22554,"children":22555},{},[22556],{"type":29,"tag":30,"props":22557,"children":22558},{},[22559,22563],{"type":29,"tag":447,"props":22560,"children":22561},{},[22562],{"type":34,"value":22395},{"type":34,"value":22564}," Ne tombez pas dans le piège de la sur-ingénierie. Si vous avez un projet simple, n'ajoutez pas de couches abstraites inutiles. L'architecture hexagonale doit vous aider, pas vous compliquer la vie.",{"type":29,"tag":6010,"props":22566,"children":22568},{"id":22567},"_2-respecter-les-principes-solid",[22569,22570],{"type":34,"value":22482},{"type":29,"tag":447,"props":22571,"children":22572},{},[22573],{"type":34,"value":22574},"Respecter les principes SOLID",{"type":29,"tag":30,"props":22576,"children":22577},{},[22578,22580,22586,22588,22593,22594,22599,22601,22606],{"type":34,"value":22579},"L’architecture hexagonale s’intègre parfaitement dans les ",{"type":29,"tag":63,"props":22581,"children":22583},{"href":22582},"\u002Ffr\u002Farchitecture-craft\u002Fprincipes-solid-java-exemples",[22584],{"type":34,"value":22585},"principes SOLID",{"type":34,"value":22587},", notamment en respectant le principe de ",{"type":29,"tag":447,"props":22589,"children":22590},{},[22591],{"type":34,"value":22592},"responsabilité unique",{"type":34,"value":10738},{"type":29,"tag":447,"props":22595,"children":22596},{},[22597],{"type":34,"value":22598},"inversion des dépendances",{"type":34,"value":22600},". Assurez-vous que chaque composant a une responsabilité bien définie et que le domaine ne dépend jamais directement de l’infrastructure. Pour aller plus loin sur la règle de dépendance et la direction des flèches dans l’architecture, les ",{"type":29,"tag":63,"props":22602,"children":22603},{"href":65},[22604],{"type":34,"value":22605},"3 règles de la Clean Architecture",{"type":34,"value":22607}," sont complémentaires.",{"type":29,"tag":6010,"props":22609,"children":22611},{"id":22610},"_3-kiss-keep-it-simple-stupid",[22612,22613],{"type":34,"value":22498},{"type":29,"tag":447,"props":22614,"children":22615},{},[22616],{"type":34,"value":22617},"KISS : Keep It Simple, Stupid",{"type":29,"tag":30,"props":22619,"children":22620},{},[22621,22623,22628],{"type":34,"value":22622},"Restez simple. L’objectif est de ",{"type":29,"tag":447,"props":22624,"children":22625},{},[22626],{"type":34,"value":22627},"simplifier",{"type":34,"value":22629}," la maintenance et les changements dans le projet, pas de compliquer inutilement les choses. Si votre projet est petit, ne vous forcez pas à utiliser l’architecture hexagonale partout. Elle doit apporter une valeur ajoutée.",{"type":29,"tag":7066,"props":22631,"children":22632},{},[22633],{"type":29,"tag":30,"props":22634,"children":22635},{},[22636,22640],{"type":29,"tag":447,"props":22637,"children":22638},{},[22639],{"type":34,"value":21059},{"type":34,"value":22641}," Adoptez le principe KISS. L’architecture hexagonale est puissante, mais elle doit rester un outil au service de la simplicité et de la maintenabilité, et non un fardeau architectural.",{"type":29,"tag":2288,"props":22643,"children":22645},{"cta":5629,"href":5630,"title":22644,"type":5632},"L'hexagonale n'est qu'une pratique parmi les 100 qui font le craft",[22646],{"type":29,"tag":30,"props":22647,"children":22648},{},[22649],{"type":34,"value":22650},"Protéger son domaine derrière des ports et adapters, c'est une pièce du puzzle. Le Craft Bundle réunit les 100 pratiques que j'applique pour coder propre au quotidien, du découpage des couches à la discipline de test qui rend cette architecture vraiment payante. Ce sont les réflexes que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vus tenir un système en prod sur la durée.",{"type":29,"tag":47,"props":22652,"children":22653},{},[],{"type":29,"tag":51,"props":22655,"children":22657},{"id":22656},"faq-sur-larchitecture-hexagonale",[22658],{"type":29,"tag":447,"props":22659,"children":22660},{},[22661],{"type":34,"value":22662},"FAQ sur l’architecture hexagonale",{"type":29,"tag":5649,"props":22664,"children":22665},{},[22666,22671],{"type":29,"tag":5653,"props":22667,"children":22668},{},[22669],{"type":34,"value":22670},"1. L’architecture hexagonale est-elle adaptée à tous les projets ?",{"type":29,"tag":30,"props":22672,"children":22673},{},[22674],{"type":34,"value":22675},"Pas nécessairement. Pour les petits projets ou les prototypes simples, elle peut être surdimensionnée. Cependant, elle devient très utile pour des projets plus complexes, ou ceux qui nécessitent de fréquents changements de technologie.",{"type":29,"tag":5649,"props":22677,"children":22678},{},[22679,22684],{"type":29,"tag":5653,"props":22680,"children":22681},{},[22682],{"type":34,"value":22683},"2. Comment commencer dans un projet existant ?",{"type":29,"tag":30,"props":22685,"children":22686},{},[22687],{"type":34,"value":22688},"Vous pouvez commencer progressivement en appliquant les principes hexagonaux à de nouvelles fonctionnalités ou modules, tout en refactorisant doucement l’existant. Cela évite de tout casser d’un coup.",{"type":29,"tag":5649,"props":22690,"children":22691},{},[22692,22697],{"type":29,"tag":5653,"props":22693,"children":22694},{},[22695],{"type":34,"value":22696},"3. Est-ce que ça complique trop les petites applications ?",{"type":29,"tag":30,"props":22698,"children":22699},{},[22700],{"type":34,"value":22701},"Cela dépend de l’application. Si vous prévoyez des évolutions futures importantes, l’architecture hexagonale peut aider dès le début. Pour des projets très simples, une architecture en couches peut parfois suffire.",{"type":29,"tag":5649,"props":22703,"children":22704},{},[22705,22710],{"type":29,"tag":5653,"props":22706,"children":22707},{},[22708],{"type":34,"value":22709},"4. Quels outils Java facilitent la mise en œuvre ?",{"type":29,"tag":30,"props":22711,"children":22712},{},[22713,22715,22720,22722,22727,22728,22733],{"type":34,"value":22714},"Java propose de nombreux frameworks qui s’intègrent bien avec cette architecture. ",{"type":29,"tag":447,"props":22716,"children":22717},{},[22718],{"type":34,"value":22719},"Spring",{"type":34,"value":22721}," est souvent utilisé pour implémenter les ports et adaptateurs, en particulier avec sa gestion des dépendances. Les tests peuvent être facilement gérés avec ",{"type":29,"tag":447,"props":22723,"children":22724},{},[22725],{"type":34,"value":22726},"JUnit",{"type":34,"value":18104},{"type":29,"tag":447,"props":22729,"children":22730},{},[22731],{"type":34,"value":22732},"Mockito",{"type":34,"value":338},{"type":29,"tag":2288,"props":22735,"children":22738},{"cta":22736,"href":16240,"title":22737,"type":5755},"Accéder à l'assessment gratuit →","Ressource gratuite : Votre équipe livre-t-elle aussi vite qu'elle le pourrait ?",[22739],{"type":29,"tag":30,"props":22740,"children":22741},{},[22742],{"type":34,"value":22743},"30 questions, 5 dimensions, score sur 100. Mesurez la maturité engineering de votre équipe avec le benchmark utilisé dans des DSI de 50 à 800+ développeurs, et identifiez vos 3 chantiers prioritaires.",{"type":29,"tag":5763,"props":22745,"children":22746},{},[22747],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":22749},[22750,22751,22756,22764,22772],{"id":20938,"depth":101,"text":20944},{"id":20965,"depth":101,"text":20971,"children":22752},[22753,22754,22755],{"id":20993,"depth":128,"text":20999},{"id":21007,"depth":128,"text":21013},{"id":21064,"depth":128,"text":21070},{"id":22423,"depth":101,"text":22429,"children":22757},[22758,22760,22762],{"id":22437,"depth":128,"text":22759},"1. Modularité et testabilité",{"id":22479,"depth":128,"text":22761},"2. Adaptabilité et flexibilité",{"id":22495,"depth":128,"text":22763},"3. Simplicité des changements dans l'infrastructure",{"id":22514,"depth":101,"text":22520,"children":22765},[22766,22768,22770],{"id":22528,"depth":128,"text":22767},"1. Ne pas sur-ingénier le projet",{"id":22567,"depth":128,"text":22769},"2. Respecter les principes SOLID",{"id":22610,"depth":128,"text":22771},"3. KISS : Keep It Simple, Stupid",{"id":22656,"depth":101,"text":22662},"content:fr:architecture-craft:architecture-hexagonale-java-exemples-bonnes-pratiques.md","fr\u002Farchitecture-craft\u002Farchitecture-hexagonale-java-exemples-bonnes-pratiques.md","fr\u002Farchitecture-craft\u002Farchitecture-hexagonale-java-exemples-bonnes-pratiques",{"_path":22777,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":22778,"description":10681,"id":3519,"date":22779,"listed":13,"nocomments":7,"hidden":7,"categories":22780,"tags":22781,"cover":22782,"readingTime":22783,"body":22787,"_type":5777,"_id":25449,"_source":5779,"_file":25450,"_stem":25451,"_extension":5782},"\u002Ffr\u002Farchitecture-craft\u002Fdecouvrir-domain-driven-design-ddd-avantages-exemples-java","Découvrir le Domain-Driven Design (DDD), Avantages, Bonnes Pratiques et Exemples en Java","2024-07-23",[6],[17,10685],"covers\u002Farticles\u002Fdomain-driven-design.jpg",{"text":21,"minutes":22784,"time":22785,"words":22786},8.055,483300,1611,{"type":26,"children":22788,"toc":25418},[22789,22795,22806,22811,22816,22819,22825,22837,22848,22854,22886,22891,22894,22908,22914,22919,22929,22941,22947,23268,23277,23287,23299,23304,23995,24004,24014,24032,24037,24447,24457,24468,24479,24484,24613,24622,24633,24645,24650,24741,24750,24753,24759,24764,24774,24785,24795,24800,24810,24815,24821,24829,24839,24844,24854,24865,24871,25283,25292,25295,25304,25307,25313,25326,25339,25352,25365,25378,25391,25404,25414],{"type":29,"tag":51,"props":22790,"children":22792},{"id":22791},"introduction-au-domain-driven-design-ddd",[22793],{"type":34,"value":22794},"Introduction au Domain-Driven Design (DDD)",{"type":29,"tag":30,"props":22796,"children":22797},{},[22798,22800,22804],{"type":34,"value":22799},"Un code qui paraît compliqué sans qu'on sache pourquoi. La logique métier dispersée partout, mélangée à des détails techniques. Le ",{"type":29,"tag":447,"props":22801,"children":22802},{},[22803],{"type":34,"value":10729},{"type":34,"value":22805}," s'attaque précisément à ce problème.",{"type":29,"tag":30,"props":22807,"children":22808},{},[22809],{"type":34,"value":22810},"L'objectif est simple : aligner le code sur la réalité métier du projet. Chaque entité, chaque service, fait exactement ce qu'il est censé faire. Ajouter une fonctionnalité devient prévisible, et le risque de régression chute. Je l'ai constaté à plusieurs reprises en mission, notamment chez des clients bancaires et assurantiels.",{"type":29,"tag":30,"props":22812,"children":22813},{},[22814],{"type":34,"value":22815},"Cet article explique ce qu'est réellement le DDD, en quoi il transforme la manière de construire un logiciel, et comment l'appliquer en Java avec des exemples concrets. Eric Evans a formalisé cette approche dans son ouvrage \"Domain-Driven Design\" (2003), qui reste la référence incontournable sur le sujet.",{"type":29,"tag":47,"props":22817,"children":22818},{},[],{"type":29,"tag":51,"props":22820,"children":22822},{"id":22821},"pourquoi-le-domain-driven-design-ddd-est-il-important-dans-la-conception-logicielle",[22823],{"type":34,"value":22824},"Pourquoi le Domain-Driven Design (DDD) est-il important dans la conception logicielle ?",{"type":29,"tag":30,"props":22826,"children":22827},{},[22828,22830,22835],{"type":34,"value":22829},"Le DDD répond à un problème récurrent : dans un projet complexe, ",{"type":29,"tag":447,"props":22831,"children":22832},{},[22833],{"type":34,"value":22834},"la logique métier",{"type":34,"value":22836}," finit souvent dispersée dans des considérations techniques. On manipule plus de \"comment\" que de \"quoi\" et \"pourquoi\". Les conséquences sont mécaniques : bugs, incompréhensions, code difficile à maintenir. J'ai observé ce schéma dans des dizaines d'équipes : les coûts de maintenance explosent précisément parce que la logique métier est diluée dans tout le code.",{"type":29,"tag":30,"props":22838,"children":22839},{},[22840,22842,22846],{"type":34,"value":22841},"Le DDD inverse cette logique en plaçant le ",{"type":29,"tag":447,"props":22843,"children":22844},{},[22845],{"type":34,"value":20988},{"type":34,"value":22847}," au centre de la conception. Il structure le code autour des règles spécifiques au domaine, et pas autour des technologies utilisées. Un point systématiquement sous-estimé dans les grandes DSI où j'interviens : on modélise les tables de base de données avant le domaine, et on le regrette des mois plus tard.",{"type":29,"tag":6010,"props":22849,"children":22851},{"id":22850},"un-exemple-concret-la-gestion-dune-bibliothèque",[22852],{"type":34,"value":22853},"Un exemple concret : La gestion d'une bibliothèque",{"type":29,"tag":30,"props":22855,"children":22856},{},[22857,22859,22864,22866,22871,22872,22877,22879,22884],{"type":34,"value":22858},"Prenons un exemple : un système de gestion pour une bibliothèque. Vous avez des ",{"type":29,"tag":447,"props":22860,"children":22861},{},[22862],{"type":34,"value":22863},"livres",{"type":34,"value":22865},", des ",{"type":29,"tag":447,"props":22867,"children":22868},{},[22869],{"type":34,"value":22870},"emprunts",{"type":34,"value":22865},{"type":29,"tag":447,"props":22873,"children":22874},{},[22875],{"type":34,"value":22876},"abonnés",{"type":34,"value":22878},", et des ",{"type":29,"tag":447,"props":22880,"children":22881},{},[22882],{"type":34,"value":22883},"règles métier",{"type":34,"value":22885}," comme \"un abonné ne peut pas emprunter plus de 5 livres\". Sans discipline, ces règles finissent enterrées entre les classes de gestion de base de données et les classes de validation. Plus personne ne sait où elles vivent vraiment.",{"type":29,"tag":30,"props":22887,"children":22888},{},[22889],{"type":34,"value":22890},"Le DDD demande de modéliser ces concepts (livres, abonnés, emprunts) explicitement, avec des objets métier qui représentent ces réalités. Le code devient plus facile à lire, à maintenir et à faire évoluer. Les règles vivent là où elles doivent : dans le domaine métier. Concrètement, cela se traduit par des cycles de livraison plus courts et moins d'erreurs métier en production.",{"type":29,"tag":47,"props":22892,"children":22893},{},[],{"type":29,"tag":2288,"props":22895,"children":22897},{"cta":2290,"href":2291,"title":22896,"type":2293},"Vous voulez savoir modéliser un agrégat propre au lieu d'empiler les classes ?",[22898,22903],{"type":29,"tag":30,"props":22899,"children":22900},{},[22901],{"type":34,"value":22902},"Identifier où vivent vraiment les règles métier, découper un agrégat sans le faire exploser, nommer les concepts comme un expert du domaine : ça ne s'apprend pas en lisant un article, ça se travaille. En mentoring 1:1, je relis votre code avec vous et on remodélise ensemble une partie réelle de votre projet.",{"type":29,"tag":30,"props":22904,"children":22905},{},[22906],{"type":34,"value":22907},"Vous repartez avec le réflexe de placer le domaine au centre, sur vos propres classes, pas sur un exemple de bibliothèque.",{"type":29,"tag":51,"props":22909,"children":22911},{"id":22910},"les-concepts-clés-du-domain-driven-design-ddd",[22912],{"type":34,"value":22913},"Les concepts clés du Domain-Driven Design (DDD)",{"type":29,"tag":30,"props":22915,"children":22916},{},[22917],{"type":34,"value":22918},"Le DDD, ce n’est pas juste une nouvelle façon de coder. Avant de maîtriser ces approches, voici les concepts de base à comprendre, avec des explications simples et des exemples en Java pour illustrer le tout.",{"type":29,"tag":6010,"props":22920,"children":22922},{"id":22921},"_1-entité",[22923,22924],{"type":34,"value":22440},{"type":29,"tag":447,"props":22925,"children":22926},{},[22927],{"type":34,"value":22928},"Entité",{"type":29,"tag":30,"props":22930,"children":22931},{},[22932,22934,22939],{"type":34,"value":22933},"Une ",{"type":29,"tag":447,"props":22935,"children":22936},{},[22937],{"type":34,"value":22938},"entité",{"type":34,"value":22940}," est un objet qui possède une identité unique qui le distingue des autres, même si ses attributs peuvent changer. Autrement dit, deux objets avec les mêmes données peuvent être considérés comme différents s'ils ont des identités distinctes.",{"type":29,"tag":12165,"props":22942,"children":22944},{"id":22943},"exemple-en-java",[22945],{"type":34,"value":22946},"Exemple en Java :",{"type":29,"tag":77,"props":22948,"children":22950},{"code":22949,"language":80,"meta":8,"className":81,"style":8},"public class Abonne {\n    private final String id;  \u002F\u002F Identité unique\n    private String nom;\n    private String adresse;\n\n    public Abonne(String id, String nom, String adresse) {\n        this.id = id;\n        this.nom = nom;\n        this.adresse = adresse;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    \u002F\u002F getters et setters...\n}\n",[22951],{"type":29,"tag":84,"props":22952,"children":22953},{"__ignoreMap":8},[22954,22974,23002,23022,23042,23049,23104,23131,23159,23187,23194,23201,23224,23239,23246,23253,23261],{"type":29,"tag":88,"props":22955,"children":22956},{"class":90,"line":91},[22957,22961,22965,22970],{"type":29,"tag":88,"props":22958,"children":22959},{"style":105},[22960],{"type":34,"value":108},{"type":29,"tag":88,"props":22962,"children":22963},{"style":105},[22964],{"type":34,"value":113},{"type":29,"tag":88,"props":22966,"children":22967},{"style":116},[22968],{"type":34,"value":22969}," Abonne",{"type":29,"tag":88,"props":22971,"children":22972},{"style":122},[22973],{"type":34,"value":125},{"type":29,"tag":88,"props":22975,"children":22976},{"class":90,"line":101},[22977,22981,22985,22989,22993,22997],{"type":29,"tag":88,"props":22978,"children":22979},{"style":105},[22980],{"type":34,"value":143},{"type":29,"tag":88,"props":22982,"children":22983},{"style":105},[22984],{"type":34,"value":148},{"type":29,"tag":88,"props":22986,"children":22987},{"style":151},[22988],{"type":34,"value":281},{"type":29,"tag":88,"props":22990,"children":22991},{"style":157},[22992],{"type":34,"value":3435},{"type":29,"tag":88,"props":22994,"children":22995},{"style":122},[22996],{"type":34,"value":5893},{"type":29,"tag":88,"props":22998,"children":22999},{"style":95},[23000],{"type":34,"value":23001},"  \u002F\u002F Identité unique\n",{"type":29,"tag":88,"props":23003,"children":23004},{"class":90,"line":128},[23005,23009,23013,23018],{"type":29,"tag":88,"props":23006,"children":23007},{"style":105},[23008],{"type":34,"value":143},{"type":29,"tag":88,"props":23010,"children":23011},{"style":151},[23012],{"type":34,"value":281},{"type":29,"tag":88,"props":23014,"children":23015},{"style":157},[23016],{"type":34,"value":23017}," nom",{"type":29,"tag":88,"props":23019,"children":23020},{"style":122},[23021],{"type":34,"value":424},{"type":29,"tag":88,"props":23023,"children":23024},{"class":90,"line":137},[23025,23029,23033,23038],{"type":29,"tag":88,"props":23026,"children":23027},{"style":105},[23028],{"type":34,"value":143},{"type":29,"tag":88,"props":23030,"children":23031},{"style":151},[23032],{"type":34,"value":281},{"type":29,"tag":88,"props":23034,"children":23035},{"style":157},[23036],{"type":34,"value":23037}," adresse",{"type":29,"tag":88,"props":23039,"children":23040},{"style":122},[23041],{"type":34,"value":424},{"type":29,"tag":88,"props":23043,"children":23044},{"class":90,"line":211},[23045],{"type":29,"tag":88,"props":23046,"children":23047},{"emptyLinePlaceholder":13},[23048],{"type":34,"value":134},{"type":29,"tag":88,"props":23050,"children":23051},{"class":90,"line":262},[23052,23056,23060,23064,23068,23072,23076,23080,23084,23088,23092,23096,23100],{"type":29,"tag":88,"props":23053,"children":23054},{"style":105},[23055],{"type":34,"value":276},{"type":29,"tag":88,"props":23057,"children":23058},{"style":174},[23059],{"type":34,"value":22969},{"type":29,"tag":88,"props":23061,"children":23062},{"style":122},[23063],{"type":34,"value":181},{"type":29,"tag":88,"props":23065,"children":23066},{"style":151},[23067],{"type":34,"value":695},{"type":29,"tag":88,"props":23069,"children":23070},{"style":298},[23071],{"type":34,"value":3435},{"type":29,"tag":88,"props":23073,"children":23074},{"style":122},[23075],{"type":34,"value":192},{"type":29,"tag":88,"props":23077,"children":23078},{"style":151},[23079],{"type":34,"value":281},{"type":29,"tag":88,"props":23081,"children":23082},{"style":298},[23083],{"type":34,"value":23017},{"type":29,"tag":88,"props":23085,"children":23086},{"style":122},[23087],{"type":34,"value":192},{"type":29,"tag":88,"props":23089,"children":23090},{"style":151},[23091],{"type":34,"value":281},{"type":29,"tag":88,"props":23093,"children":23094},{"style":298},[23095],{"type":34,"value":23037},{"type":29,"tag":88,"props":23097,"children":23098},{"style":122},[23099],{"type":34,"value":306},{"type":29,"tag":88,"props":23101,"children":23102},{"style":122},[23103],{"type":34,"value":125},{"type":29,"tag":88,"props":23105,"children":23106},{"class":90,"line":270},[23107,23111,23115,23119,23123,23127],{"type":29,"tag":88,"props":23108,"children":23109},{"style":873},[23110],{"type":34,"value":876},{"type":29,"tag":88,"props":23112,"children":23113},{"style":122},[23114],{"type":34,"value":338},{"type":29,"tag":88,"props":23116,"children":23117},{"style":157},[23118],{"type":34,"value":8325},{"type":29,"tag":88,"props":23120,"children":23121},{"style":163},[23122],{"type":34,"value":166},{"type":29,"tag":88,"props":23124,"children":23125},{"style":157},[23126],{"type":34,"value":3435},{"type":29,"tag":88,"props":23128,"children":23129},{"style":122},[23130],{"type":34,"value":424},{"type":29,"tag":88,"props":23132,"children":23133},{"class":90,"line":313},[23134,23138,23142,23147,23151,23155],{"type":29,"tag":88,"props":23135,"children":23136},{"style":873},[23137],{"type":34,"value":876},{"type":29,"tag":88,"props":23139,"children":23140},{"style":122},[23141],{"type":34,"value":338},{"type":29,"tag":88,"props":23143,"children":23144},{"style":157},[23145],{"type":34,"value":23146},"nom ",{"type":29,"tag":88,"props":23148,"children":23149},{"style":163},[23150],{"type":34,"value":166},{"type":29,"tag":88,"props":23152,"children":23153},{"style":157},[23154],{"type":34,"value":23017},{"type":29,"tag":88,"props":23156,"children":23157},{"style":122},[23158],{"type":34,"value":424},{"type":29,"tag":88,"props":23160,"children":23161},{"class":90,"line":360},[23162,23166,23170,23175,23179,23183],{"type":29,"tag":88,"props":23163,"children":23164},{"style":873},[23165],{"type":34,"value":876},{"type":29,"tag":88,"props":23167,"children":23168},{"style":122},[23169],{"type":34,"value":338},{"type":29,"tag":88,"props":23171,"children":23172},{"style":157},[23173],{"type":34,"value":23174},"adresse ",{"type":29,"tag":88,"props":23176,"children":23177},{"style":163},[23178],{"type":34,"value":166},{"type":29,"tag":88,"props":23180,"children":23181},{"style":157},[23182],{"type":34,"value":23037},{"type":29,"tag":88,"props":23184,"children":23185},{"style":122},[23186],{"type":34,"value":424},{"type":29,"tag":88,"props":23188,"children":23189},{"class":90,"line":409},[23190],{"type":29,"tag":88,"props":23191,"children":23192},{"style":122},[23193],{"type":34,"value":433},{"type":29,"tag":88,"props":23195,"children":23196},{"class":90,"line":427},[23197],{"type":29,"tag":88,"props":23198,"children":23199},{"emptyLinePlaceholder":13},[23200],{"type":34,"value":134},{"type":29,"tag":88,"props":23202,"children":23203},{"class":90,"line":436},[23204,23208,23212,23216,23220],{"type":29,"tag":88,"props":23205,"children":23206},{"style":105},[23207],{"type":34,"value":276},{"type":29,"tag":88,"props":23209,"children":23210},{"style":151},[23211],{"type":34,"value":281},{"type":29,"tag":88,"props":23213,"children":23214},{"style":174},[23215],{"type":34,"value":20214},{"type":29,"tag":88,"props":23217,"children":23218},{"style":122},[23219],{"type":34,"value":1470},{"type":29,"tag":88,"props":23221,"children":23222},{"style":122},[23223],{"type":34,"value":125},{"type":29,"tag":88,"props":23225,"children":23226},{"class":90,"line":767},[23227,23231,23235],{"type":29,"tag":88,"props":23228,"children":23229},{"style":105},[23230],{"type":34,"value":415},{"type":29,"tag":88,"props":23232,"children":23233},{"style":157},[23234],{"type":34,"value":3435},{"type":29,"tag":88,"props":23236,"children":23237},{"style":122},[23238],{"type":34,"value":424},{"type":29,"tag":88,"props":23240,"children":23241},{"class":90,"line":792},[23242],{"type":29,"tag":88,"props":23243,"children":23244},{"style":122},[23245],{"type":34,"value":433},{"type":29,"tag":88,"props":23247,"children":23248},{"class":90,"line":817},[23249],{"type":29,"tag":88,"props":23250,"children":23251},{"emptyLinePlaceholder":13},[23252],{"type":34,"value":134},{"type":29,"tag":88,"props":23254,"children":23255},{"class":90,"line":825},[23256],{"type":29,"tag":88,"props":23257,"children":23258},{"style":95},[23259],{"type":34,"value":23260},"    \u002F\u002F getters et setters...\n",{"type":29,"tag":88,"props":23262,"children":23263},{"class":90,"line":869},[23264],{"type":29,"tag":88,"props":23265,"children":23266},{"style":122},[23267],{"type":34,"value":442},{"type":29,"tag":30,"props":23269,"children":23270},{},[23271,23275],{"type":29,"tag":447,"props":23272,"children":23273},{},[23274],{"type":34,"value":17780},{"type":34,"value":23276}," Les entités doivent avoir une identité claire. Je vous recommande d'utiliser un identifiant unique (comme un UUID) pour chaque entité afin de les différencier facilement dans votre domaine.",{"type":29,"tag":6010,"props":23278,"children":23280},{"id":23279},"_2-objet-de-valeur-value-object",[23281,23282],{"type":34,"value":22482},{"type":29,"tag":447,"props":23283,"children":23284},{},[23285],{"type":34,"value":23286},"Objet de valeur (Value Object)",{"type":29,"tag":30,"props":23288,"children":23289},{},[23290,23292,23297],{"type":34,"value":23291},"Un ",{"type":29,"tag":447,"props":23293,"children":23294},{},[23295],{"type":34,"value":23296},"objet de valeur",{"type":34,"value":23298}," est un objet qui n'a pas d'identité propre. Il est défini uniquement par ses attributs. Si deux objets ont les mêmes attributs, ils sont considérés comme identiques.",{"type":29,"tag":12165,"props":23300,"children":23302},{"id":23301},"exemple-en-java-1",[23303],{"type":34,"value":22946},{"type":29,"tag":77,"props":23305,"children":23307},{"code":23306,"language":80,"meta":8,"className":81,"style":8},"public class Adresse {\n    private String rue;\n    private String ville;\n    private String codePostal;\n\n    public Adresse(String rue, String ville, String codePostal) {\n        this.rue = rue;\n        this.ville = ville;\n        this.codePostal = codePostal;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        Adresse adresse = (Adresse) o;\n        return rue.equals(adresse.rue) && ville.equals(adresse.ville) && codePostal.equals(adresse.codePostal);\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(rue, ville, codePostal);\n    }\n\n    \u002F\u002F getters et setters...\n}\n",[23308],{"type":29,"tag":84,"props":23309,"children":23310},{"__ignoreMap":8},[23311,23331,23351,23371,23391,23398,23453,23481,23509,23537,23544,23551,23562,23600,23642,23714,23752,23869,23876,23883,23894,23918,23967,23974,23981,23988],{"type":29,"tag":88,"props":23312,"children":23313},{"class":90,"line":91},[23314,23318,23322,23327],{"type":29,"tag":88,"props":23315,"children":23316},{"style":105},[23317],{"type":34,"value":108},{"type":29,"tag":88,"props":23319,"children":23320},{"style":105},[23321],{"type":34,"value":113},{"type":29,"tag":88,"props":23323,"children":23324},{"style":116},[23325],{"type":34,"value":23326}," Adresse",{"type":29,"tag":88,"props":23328,"children":23329},{"style":122},[23330],{"type":34,"value":125},{"type":29,"tag":88,"props":23332,"children":23333},{"class":90,"line":101},[23334,23338,23342,23347],{"type":29,"tag":88,"props":23335,"children":23336},{"style":105},[23337],{"type":34,"value":143},{"type":29,"tag":88,"props":23339,"children":23340},{"style":151},[23341],{"type":34,"value":281},{"type":29,"tag":88,"props":23343,"children":23344},{"style":157},[23345],{"type":34,"value":23346}," rue",{"type":29,"tag":88,"props":23348,"children":23349},{"style":122},[23350],{"type":34,"value":424},{"type":29,"tag":88,"props":23352,"children":23353},{"class":90,"line":128},[23354,23358,23362,23367],{"type":29,"tag":88,"props":23355,"children":23356},{"style":105},[23357],{"type":34,"value":143},{"type":29,"tag":88,"props":23359,"children":23360},{"style":151},[23361],{"type":34,"value":281},{"type":29,"tag":88,"props":23363,"children":23364},{"style":157},[23365],{"type":34,"value":23366}," ville",{"type":29,"tag":88,"props":23368,"children":23369},{"style":122},[23370],{"type":34,"value":424},{"type":29,"tag":88,"props":23372,"children":23373},{"class":90,"line":137},[23374,23378,23382,23387],{"type":29,"tag":88,"props":23375,"children":23376},{"style":105},[23377],{"type":34,"value":143},{"type":29,"tag":88,"props":23379,"children":23380},{"style":151},[23381],{"type":34,"value":281},{"type":29,"tag":88,"props":23383,"children":23384},{"style":157},[23385],{"type":34,"value":23386}," codePostal",{"type":29,"tag":88,"props":23388,"children":23389},{"style":122},[23390],{"type":34,"value":424},{"type":29,"tag":88,"props":23392,"children":23393},{"class":90,"line":211},[23394],{"type":29,"tag":88,"props":23395,"children":23396},{"emptyLinePlaceholder":13},[23397],{"type":34,"value":134},{"type":29,"tag":88,"props":23399,"children":23400},{"class":90,"line":262},[23401,23405,23409,23413,23417,23421,23425,23429,23433,23437,23441,23445,23449],{"type":29,"tag":88,"props":23402,"children":23403},{"style":105},[23404],{"type":34,"value":276},{"type":29,"tag":88,"props":23406,"children":23407},{"style":174},[23408],{"type":34,"value":23326},{"type":29,"tag":88,"props":23410,"children":23411},{"style":122},[23412],{"type":34,"value":181},{"type":29,"tag":88,"props":23414,"children":23415},{"style":151},[23416],{"type":34,"value":695},{"type":29,"tag":88,"props":23418,"children":23419},{"style":298},[23420],{"type":34,"value":23346},{"type":29,"tag":88,"props":23422,"children":23423},{"style":122},[23424],{"type":34,"value":192},{"type":29,"tag":88,"props":23426,"children":23427},{"style":151},[23428],{"type":34,"value":281},{"type":29,"tag":88,"props":23430,"children":23431},{"style":298},[23432],{"type":34,"value":23366},{"type":29,"tag":88,"props":23434,"children":23435},{"style":122},[23436],{"type":34,"value":192},{"type":29,"tag":88,"props":23438,"children":23439},{"style":151},[23440],{"type":34,"value":281},{"type":29,"tag":88,"props":23442,"children":23443},{"style":298},[23444],{"type":34,"value":23386},{"type":29,"tag":88,"props":23446,"children":23447},{"style":122},[23448],{"type":34,"value":306},{"type":29,"tag":88,"props":23450,"children":23451},{"style":122},[23452],{"type":34,"value":125},{"type":29,"tag":88,"props":23454,"children":23455},{"class":90,"line":270},[23456,23460,23464,23469,23473,23477],{"type":29,"tag":88,"props":23457,"children":23458},{"style":873},[23459],{"type":34,"value":876},{"type":29,"tag":88,"props":23461,"children":23462},{"style":122},[23463],{"type":34,"value":338},{"type":29,"tag":88,"props":23465,"children":23466},{"style":157},[23467],{"type":34,"value":23468},"rue ",{"type":29,"tag":88,"props":23470,"children":23471},{"style":163},[23472],{"type":34,"value":166},{"type":29,"tag":88,"props":23474,"children":23475},{"style":157},[23476],{"type":34,"value":23346},{"type":29,"tag":88,"props":23478,"children":23479},{"style":122},[23480],{"type":34,"value":424},{"type":29,"tag":88,"props":23482,"children":23483},{"class":90,"line":313},[23484,23488,23492,23497,23501,23505],{"type":29,"tag":88,"props":23485,"children":23486},{"style":873},[23487],{"type":34,"value":876},{"type":29,"tag":88,"props":23489,"children":23490},{"style":122},[23491],{"type":34,"value":338},{"type":29,"tag":88,"props":23493,"children":23494},{"style":157},[23495],{"type":34,"value":23496},"ville ",{"type":29,"tag":88,"props":23498,"children":23499},{"style":163},[23500],{"type":34,"value":166},{"type":29,"tag":88,"props":23502,"children":23503},{"style":157},[23504],{"type":34,"value":23366},{"type":29,"tag":88,"props":23506,"children":23507},{"style":122},[23508],{"type":34,"value":424},{"type":29,"tag":88,"props":23510,"children":23511},{"class":90,"line":360},[23512,23516,23520,23525,23529,23533],{"type":29,"tag":88,"props":23513,"children":23514},{"style":873},[23515],{"type":34,"value":876},{"type":29,"tag":88,"props":23517,"children":23518},{"style":122},[23519],{"type":34,"value":338},{"type":29,"tag":88,"props":23521,"children":23522},{"style":157},[23523],{"type":34,"value":23524},"codePostal ",{"type":29,"tag":88,"props":23526,"children":23527},{"style":163},[23528],{"type":34,"value":166},{"type":29,"tag":88,"props":23530,"children":23531},{"style":157},[23532],{"type":34,"value":23386},{"type":29,"tag":88,"props":23534,"children":23535},{"style":122},[23536],{"type":34,"value":424},{"type":29,"tag":88,"props":23538,"children":23539},{"class":90,"line":409},[23540],{"type":29,"tag":88,"props":23541,"children":23542},{"style":122},[23543],{"type":34,"value":433},{"type":29,"tag":88,"props":23545,"children":23546},{"class":90,"line":427},[23547],{"type":29,"tag":88,"props":23548,"children":23549},{"emptyLinePlaceholder":13},[23550],{"type":34,"value":134},{"type":29,"tag":88,"props":23552,"children":23553},{"class":90,"line":436},[23554,23558],{"type":29,"tag":88,"props":23555,"children":23556},{"style":1974},[23557],{"type":34,"value":3302},{"type":29,"tag":88,"props":23559,"children":23560},{"style":1980},[23561],{"type":34,"value":3307},{"type":29,"tag":88,"props":23563,"children":23564},{"class":90,"line":767},[23565,23569,23573,23578,23582,23587,23592,23596],{"type":29,"tag":88,"props":23566,"children":23567},{"style":105},[23568],{"type":34,"value":276},{"type":29,"tag":88,"props":23570,"children":23571},{"style":105},[23572],{"type":34,"value":1889},{"type":29,"tag":88,"props":23574,"children":23575},{"style":174},[23576],{"type":34,"value":23577}," equals",{"type":29,"tag":88,"props":23579,"children":23580},{"style":122},[23581],{"type":34,"value":181},{"type":29,"tag":88,"props":23583,"children":23584},{"style":151},[23585],{"type":34,"value":23586},"Object",{"type":29,"tag":88,"props":23588,"children":23589},{"style":298},[23590],{"type":34,"value":23591}," o",{"type":29,"tag":88,"props":23593,"children":23594},{"style":122},[23595],{"type":34,"value":306},{"type":29,"tag":88,"props":23597,"children":23598},{"style":122},[23599],{"type":34,"value":125},{"type":29,"tag":88,"props":23601,"children":23602},{"class":90,"line":792},[23603,23607,23611,23615,23620,23624,23628,23633,23638],{"type":29,"tag":88,"props":23604,"children":23605},{"style":105},[23606],{"type":34,"value":2886},{"type":29,"tag":88,"props":23608,"children":23609},{"style":122},[23610],{"type":34,"value":2891},{"type":29,"tag":88,"props":23612,"children":23613},{"style":873},[23614],{"type":34,"value":8447},{"type":29,"tag":88,"props":23616,"children":23617},{"style":163},[23618],{"type":34,"value":23619}," ==",{"type":29,"tag":88,"props":23621,"children":23622},{"style":157},[23623],{"type":34,"value":23591},{"type":29,"tag":88,"props":23625,"children":23626},{"style":122},[23627],{"type":34,"value":306},{"type":29,"tag":88,"props":23629,"children":23630},{"style":105},[23631],{"type":34,"value":23632}," return",{"type":29,"tag":88,"props":23634,"children":23635},{"style":873},[23636],{"type":34,"value":23637}," true",{"type":29,"tag":88,"props":23639,"children":23640},{"style":122},[23641],{"type":34,"value":424},{"type":29,"tag":88,"props":23643,"children":23644},{"class":90,"line":817},[23645,23649,23653,23658,23662,23666,23671,23676,23680,23685,23689,23693,23698,23702,23706,23710],{"type":29,"tag":88,"props":23646,"children":23647},{"style":105},[23648],{"type":34,"value":2886},{"type":29,"tag":88,"props":23650,"children":23651},{"style":122},[23652],{"type":34,"value":2891},{"type":29,"tag":88,"props":23654,"children":23655},{"style":157},[23656],{"type":34,"value":23657},"o ",{"type":29,"tag":88,"props":23659,"children":23660},{"style":163},[23661],{"type":34,"value":21624},{"type":29,"tag":88,"props":23663,"children":23664},{"style":873},[23665],{"type":34,"value":21629},{"type":29,"tag":88,"props":23667,"children":23668},{"style":163},[23669],{"type":34,"value":23670}," ||",{"type":29,"tag":88,"props":23672,"children":23673},{"style":174},[23674],{"type":34,"value":23675}," getClass",{"type":29,"tag":88,"props":23677,"children":23678},{"style":122},[23679],{"type":34,"value":1470},{"type":29,"tag":88,"props":23681,"children":23682},{"style":163},[23683],{"type":34,"value":23684}," !=",{"type":29,"tag":88,"props":23686,"children":23687},{"style":157},[23688],{"type":34,"value":23591},{"type":29,"tag":88,"props":23690,"children":23691},{"style":122},[23692],{"type":34,"value":338},{"type":29,"tag":88,"props":23694,"children":23695},{"style":174},[23696],{"type":34,"value":23697},"getClass",{"type":29,"tag":88,"props":23699,"children":23700},{"style":122},[23701],{"type":34,"value":2915},{"type":29,"tag":88,"props":23703,"children":23704},{"style":105},[23705],{"type":34,"value":23632},{"type":29,"tag":88,"props":23707,"children":23708},{"style":873},[23709],{"type":34,"value":8096},{"type":29,"tag":88,"props":23711,"children":23712},{"style":122},[23713],{"type":34,"value":424},{"type":29,"tag":88,"props":23715,"children":23716},{"class":90,"line":825},[23717,23722,23727,23731,23735,23740,23744,23748],{"type":29,"tag":88,"props":23718,"children":23719},{"style":151},[23720],{"type":34,"value":23721},"        Adresse",{"type":29,"tag":88,"props":23723,"children":23724},{"style":157},[23725],{"type":34,"value":23726}," adresse ",{"type":29,"tag":88,"props":23728,"children":23729},{"style":163},[23730],{"type":34,"value":166},{"type":29,"tag":88,"props":23732,"children":23733},{"style":122},[23734],{"type":34,"value":2891},{"type":29,"tag":88,"props":23736,"children":23737},{"style":157},[23738],{"type":34,"value":23739},"Adresse",{"type":29,"tag":88,"props":23741,"children":23742},{"style":122},[23743],{"type":34,"value":306},{"type":29,"tag":88,"props":23745,"children":23746},{"style":157},[23747],{"type":34,"value":23591},{"type":29,"tag":88,"props":23749,"children":23750},{"style":122},[23751],{"type":34,"value":424},{"type":29,"tag":88,"props":23753,"children":23754},{"class":90,"line":869},[23755,23759,23763,23767,23772,23776,23781,23785,23790,23794,23799,23803,23807,23811,23815,23819,23823,23828,23832,23836,23840,23844,23848,23852,23856,23860,23865],{"type":29,"tag":88,"props":23756,"children":23757},{"style":105},[23758],{"type":34,"value":415},{"type":29,"tag":88,"props":23760,"children":23761},{"style":157},[23762],{"type":34,"value":23346},{"type":29,"tag":88,"props":23764,"children":23765},{"style":122},[23766],{"type":34,"value":338},{"type":29,"tag":88,"props":23768,"children":23769},{"style":174},[23770],{"type":34,"value":23771},"equals",{"type":29,"tag":88,"props":23773,"children":23774},{"style":122},[23775],{"type":34,"value":181},{"type":29,"tag":88,"props":23777,"children":23778},{"style":157},[23779],{"type":34,"value":23780},"adresse",{"type":29,"tag":88,"props":23782,"children":23783},{"style":122},[23784],{"type":34,"value":338},{"type":29,"tag":88,"props":23786,"children":23787},{"style":157},[23788],{"type":34,"value":23789},"rue",{"type":29,"tag":88,"props":23791,"children":23792},{"style":122},[23793],{"type":34,"value":306},{"type":29,"tag":88,"props":23795,"children":23796},{"style":163},[23797],{"type":34,"value":23798}," &&",{"type":29,"tag":88,"props":23800,"children":23801},{"style":157},[23802],{"type":34,"value":23366},{"type":29,"tag":88,"props":23804,"children":23805},{"style":122},[23806],{"type":34,"value":338},{"type":29,"tag":88,"props":23808,"children":23809},{"style":174},[23810],{"type":34,"value":23771},{"type":29,"tag":88,"props":23812,"children":23813},{"style":122},[23814],{"type":34,"value":181},{"type":29,"tag":88,"props":23816,"children":23817},{"style":157},[23818],{"type":34,"value":23780},{"type":29,"tag":88,"props":23820,"children":23821},{"style":122},[23822],{"type":34,"value":338},{"type":29,"tag":88,"props":23824,"children":23825},{"style":157},[23826],{"type":34,"value":23827},"ville",{"type":29,"tag":88,"props":23829,"children":23830},{"style":122},[23831],{"type":34,"value":306},{"type":29,"tag":88,"props":23833,"children":23834},{"style":163},[23835],{"type":34,"value":23798},{"type":29,"tag":88,"props":23837,"children":23838},{"style":157},[23839],{"type":34,"value":23386},{"type":29,"tag":88,"props":23841,"children":23842},{"style":122},[23843],{"type":34,"value":338},{"type":29,"tag":88,"props":23845,"children":23846},{"style":174},[23847],{"type":34,"value":23771},{"type":29,"tag":88,"props":23849,"children":23850},{"style":122},[23851],{"type":34,"value":181},{"type":29,"tag":88,"props":23853,"children":23854},{"style":157},[23855],{"type":34,"value":23780},{"type":29,"tag":88,"props":23857,"children":23858},{"style":122},[23859],{"type":34,"value":338},{"type":29,"tag":88,"props":23861,"children":23862},{"style":157},[23863],{"type":34,"value":23864},"codePostal",{"type":29,"tag":88,"props":23866,"children":23867},{"style":122},[23868],{"type":34,"value":357},{"type":29,"tag":88,"props":23870,"children":23871},{"class":90,"line":900},[23872],{"type":29,"tag":88,"props":23873,"children":23874},{"style":122},[23875],{"type":34,"value":433},{"type":29,"tag":88,"props":23877,"children":23878},{"class":90,"line":929},[23879],{"type":29,"tag":88,"props":23880,"children":23881},{"emptyLinePlaceholder":13},[23882],{"type":34,"value":134},{"type":29,"tag":88,"props":23884,"children":23885},{"class":90,"line":937},[23886,23890],{"type":29,"tag":88,"props":23887,"children":23888},{"style":1974},[23889],{"type":34,"value":3302},{"type":29,"tag":88,"props":23891,"children":23892},{"style":1980},[23893],{"type":34,"value":3307},{"type":29,"tag":88,"props":23895,"children":23896},{"class":90,"line":945},[23897,23901,23905,23910,23914],{"type":29,"tag":88,"props":23898,"children":23899},{"style":105},[23900],{"type":34,"value":276},{"type":29,"tag":88,"props":23902,"children":23903},{"style":105},[23904],{"type":34,"value":20031},{"type":29,"tag":88,"props":23906,"children":23907},{"style":174},[23908],{"type":34,"value":23909}," hashCode",{"type":29,"tag":88,"props":23911,"children":23912},{"style":122},[23913],{"type":34,"value":1470},{"type":29,"tag":88,"props":23915,"children":23916},{"style":122},[23917],{"type":34,"value":125},{"type":29,"tag":88,"props":23919,"children":23920},{"class":90,"line":981},[23921,23925,23930,23934,23939,23943,23947,23951,23955,23959,23963],{"type":29,"tag":88,"props":23922,"children":23923},{"style":105},[23924],{"type":34,"value":415},{"type":29,"tag":88,"props":23926,"children":23927},{"style":157},[23928],{"type":34,"value":23929}," Objects",{"type":29,"tag":88,"props":23931,"children":23932},{"style":122},[23933],{"type":34,"value":338},{"type":29,"tag":88,"props":23935,"children":23936},{"style":174},[23937],{"type":34,"value":23938},"hash",{"type":29,"tag":88,"props":23940,"children":23941},{"style":122},[23942],{"type":34,"value":181},{"type":29,"tag":88,"props":23944,"children":23945},{"style":157},[23946],{"type":34,"value":23789},{"type":29,"tag":88,"props":23948,"children":23949},{"style":122},[23950],{"type":34,"value":192},{"type":29,"tag":88,"props":23952,"children":23953},{"style":157},[23954],{"type":34,"value":23366},{"type":29,"tag":88,"props":23956,"children":23957},{"style":122},[23958],{"type":34,"value":192},{"type":29,"tag":88,"props":23960,"children":23961},{"style":157},[23962],{"type":34,"value":23386},{"type":29,"tag":88,"props":23964,"children":23965},{"style":122},[23966],{"type":34,"value":357},{"type":29,"tag":88,"props":23968,"children":23969},{"class":90,"line":1021},[23970],{"type":29,"tag":88,"props":23971,"children":23972},{"style":122},[23973],{"type":34,"value":433},{"type":29,"tag":88,"props":23975,"children":23976},{"class":90,"line":1066},[23977],{"type":29,"tag":88,"props":23978,"children":23979},{"emptyLinePlaceholder":13},[23980],{"type":34,"value":134},{"type":29,"tag":88,"props":23982,"children":23983},{"class":90,"line":1082},[23984],{"type":29,"tag":88,"props":23985,"children":23986},{"style":95},[23987],{"type":34,"value":23260},{"type":29,"tag":88,"props":23989,"children":23990},{"class":90,"line":1090},[23991],{"type":29,"tag":88,"props":23992,"children":23993},{"style":122},[23994],{"type":34,"value":442},{"type":29,"tag":30,"props":23996,"children":23997},{},[23998,24002],{"type":29,"tag":447,"props":23999,"children":24000},{},[24001],{"type":34,"value":17780},{"type":34,"value":24003}," Les objets de valeur sont parfaits pour modéliser des concepts immuables, comme des adresses ou des coordonnées. Ils doivent être comparés par valeur, pas par référence.",{"type":29,"tag":6010,"props":24005,"children":24007},{"id":24006},"_3-agrégat",[24008,24009],{"type":34,"value":22498},{"type":29,"tag":447,"props":24010,"children":24011},{},[24012],{"type":34,"value":24013},"Agrégat",{"type":29,"tag":30,"props":24015,"children":24016},{},[24017,24018,24023,24025,24030],{"type":34,"value":23291},{"type":29,"tag":447,"props":24019,"children":24020},{},[24021],{"type":34,"value":24022},"agrégat",{"type":34,"value":24024}," est un groupe d’entités et d’objets de valeur qui forment un ensemble cohérent. Il a une ",{"type":29,"tag":447,"props":24026,"children":24027},{},[24028],{"type":34,"value":24029},"racine d'agrégat",{"type":34,"value":24031},", qui est l’entité principale, responsable de l’intégrité de l'ensemble.",{"type":29,"tag":12165,"props":24033,"children":24035},{"id":24034},"exemple-en-java-2",[24036],{"type":34,"value":22946},{"type":29,"tag":77,"props":24038,"children":24040},{"code":24039,"language":80,"meta":8,"className":81,"style":8},"public class Emprunt {\n    private final String id;\n    private Abonne abonne;\n    private List\u003CLivre> livresEmpruntes = new ArrayList\u003C>();\n\n    public Emprunt(String id, Abonne abonne) {\n        this.id = id;\n        this.abonne = abonne;\n    }\n\n    public void ajouterLivre(Livre livre) {\n        if (livresEmpruntes.size() >= 5) {\n            throw new RuntimeException(\"Un abonné ne peut pas emprunter plus de 5 livres.\");\n        }\n        livresEmpruntes.add(livre);\n    }\n\n    \u002F\u002F getters et setters...\n}\n",[24041],{"type":29,"tag":84,"props":24042,"children":24043},{"__ignoreMap":8},[24044,24064,24087,24107,24152,24159,24202,24229,24257,24264,24271,24308,24355,24383,24390,24419,24426,24433,24440],{"type":29,"tag":88,"props":24045,"children":24046},{"class":90,"line":91},[24047,24051,24055,24060],{"type":29,"tag":88,"props":24048,"children":24049},{"style":105},[24050],{"type":34,"value":108},{"type":29,"tag":88,"props":24052,"children":24053},{"style":105},[24054],{"type":34,"value":113},{"type":29,"tag":88,"props":24056,"children":24057},{"style":116},[24058],{"type":34,"value":24059}," Emprunt",{"type":29,"tag":88,"props":24061,"children":24062},{"style":122},[24063],{"type":34,"value":125},{"type":29,"tag":88,"props":24065,"children":24066},{"class":90,"line":101},[24067,24071,24075,24079,24083],{"type":29,"tag":88,"props":24068,"children":24069},{"style":105},[24070],{"type":34,"value":143},{"type":29,"tag":88,"props":24072,"children":24073},{"style":105},[24074],{"type":34,"value":148},{"type":29,"tag":88,"props":24076,"children":24077},{"style":151},[24078],{"type":34,"value":281},{"type":29,"tag":88,"props":24080,"children":24081},{"style":157},[24082],{"type":34,"value":3435},{"type":29,"tag":88,"props":24084,"children":24085},{"style":122},[24086],{"type":34,"value":424},{"type":29,"tag":88,"props":24088,"children":24089},{"class":90,"line":128},[24090,24094,24098,24103],{"type":29,"tag":88,"props":24091,"children":24092},{"style":105},[24093],{"type":34,"value":143},{"type":29,"tag":88,"props":24095,"children":24096},{"style":151},[24097],{"type":34,"value":22969},{"type":29,"tag":88,"props":24099,"children":24100},{"style":157},[24101],{"type":34,"value":24102}," abonne",{"type":29,"tag":88,"props":24104,"children":24105},{"style":122},[24106],{"type":34,"value":424},{"type":29,"tag":88,"props":24108,"children":24109},{"class":90,"line":137},[24110,24114,24118,24122,24127,24131,24136,24140,24144,24148],{"type":29,"tag":88,"props":24111,"children":24112},{"style":105},[24113],{"type":34,"value":143},{"type":29,"tag":88,"props":24115,"children":24116},{"style":151},[24117],{"type":34,"value":5355},{"type":29,"tag":88,"props":24119,"children":24120},{"style":122},[24121],{"type":34,"value":1683},{"type":29,"tag":88,"props":24123,"children":24124},{"style":105},[24125],{"type":34,"value":24126},"Livre",{"type":29,"tag":88,"props":24128,"children":24129},{"style":122},[24130],{"type":34,"value":1701},{"type":29,"tag":88,"props":24132,"children":24133},{"style":157},[24134],{"type":34,"value":24135}," livresEmpruntes ",{"type":29,"tag":88,"props":24137,"children":24138},{"style":163},[24139],{"type":34,"value":166},{"type":29,"tag":88,"props":24141,"children":24142},{"style":105},[24143],{"type":34,"value":171},{"type":29,"tag":88,"props":24145,"children":24146},{"style":151},[24147],{"type":34,"value":5385},{"type":29,"tag":88,"props":24149,"children":24150},{"style":122},[24151],{"type":34,"value":1724},{"type":29,"tag":88,"props":24153,"children":24154},{"class":90,"line":211},[24155],{"type":29,"tag":88,"props":24156,"children":24157},{"emptyLinePlaceholder":13},[24158],{"type":34,"value":134},{"type":29,"tag":88,"props":24160,"children":24161},{"class":90,"line":262},[24162,24166,24170,24174,24178,24182,24186,24190,24194,24198],{"type":29,"tag":88,"props":24163,"children":24164},{"style":105},[24165],{"type":34,"value":276},{"type":29,"tag":88,"props":24167,"children":24168},{"style":174},[24169],{"type":34,"value":24059},{"type":29,"tag":88,"props":24171,"children":24172},{"style":122},[24173],{"type":34,"value":181},{"type":29,"tag":88,"props":24175,"children":24176},{"style":151},[24177],{"type":34,"value":695},{"type":29,"tag":88,"props":24179,"children":24180},{"style":298},[24181],{"type":34,"value":3435},{"type":29,"tag":88,"props":24183,"children":24184},{"style":122},[24185],{"type":34,"value":192},{"type":29,"tag":88,"props":24187,"children":24188},{"style":151},[24189],{"type":34,"value":22969},{"type":29,"tag":88,"props":24191,"children":24192},{"style":298},[24193],{"type":34,"value":24102},{"type":29,"tag":88,"props":24195,"children":24196},{"style":122},[24197],{"type":34,"value":306},{"type":29,"tag":88,"props":24199,"children":24200},{"style":122},[24201],{"type":34,"value":125},{"type":29,"tag":88,"props":24203,"children":24204},{"class":90,"line":270},[24205,24209,24213,24217,24221,24225],{"type":29,"tag":88,"props":24206,"children":24207},{"style":873},[24208],{"type":34,"value":876},{"type":29,"tag":88,"props":24210,"children":24211},{"style":122},[24212],{"type":34,"value":338},{"type":29,"tag":88,"props":24214,"children":24215},{"style":157},[24216],{"type":34,"value":8325},{"type":29,"tag":88,"props":24218,"children":24219},{"style":163},[24220],{"type":34,"value":166},{"type":29,"tag":88,"props":24222,"children":24223},{"style":157},[24224],{"type":34,"value":3435},{"type":29,"tag":88,"props":24226,"children":24227},{"style":122},[24228],{"type":34,"value":424},{"type":29,"tag":88,"props":24230,"children":24231},{"class":90,"line":313},[24232,24236,24240,24245,24249,24253],{"type":29,"tag":88,"props":24233,"children":24234},{"style":873},[24235],{"type":34,"value":876},{"type":29,"tag":88,"props":24237,"children":24238},{"style":122},[24239],{"type":34,"value":338},{"type":29,"tag":88,"props":24241,"children":24242},{"style":157},[24243],{"type":34,"value":24244},"abonne ",{"type":29,"tag":88,"props":24246,"children":24247},{"style":163},[24248],{"type":34,"value":166},{"type":29,"tag":88,"props":24250,"children":24251},{"style":157},[24252],{"type":34,"value":24102},{"type":29,"tag":88,"props":24254,"children":24255},{"style":122},[24256],{"type":34,"value":424},{"type":29,"tag":88,"props":24258,"children":24259},{"class":90,"line":360},[24260],{"type":29,"tag":88,"props":24261,"children":24262},{"style":122},[24263],{"type":34,"value":433},{"type":29,"tag":88,"props":24265,"children":24266},{"class":90,"line":409},[24267],{"type":29,"tag":88,"props":24268,"children":24269},{"emptyLinePlaceholder":13},[24270],{"type":34,"value":134},{"type":29,"tag":88,"props":24272,"children":24273},{"class":90,"line":427},[24274,24278,24282,24287,24291,24295,24300,24304],{"type":29,"tag":88,"props":24275,"children":24276},{"style":105},[24277],{"type":34,"value":276},{"type":29,"tag":88,"props":24279,"children":24280},{"style":105},[24281],{"type":34,"value":1303},{"type":29,"tag":88,"props":24283,"children":24284},{"style":174},[24285],{"type":34,"value":24286}," ajouterLivre",{"type":29,"tag":88,"props":24288,"children":24289},{"style":122},[24290],{"type":34,"value":181},{"type":29,"tag":88,"props":24292,"children":24293},{"style":151},[24294],{"type":34,"value":24126},{"type":29,"tag":88,"props":24296,"children":24297},{"style":298},[24298],{"type":34,"value":24299}," livre",{"type":29,"tag":88,"props":24301,"children":24302},{"style":122},[24303],{"type":34,"value":306},{"type":29,"tag":88,"props":24305,"children":24306},{"style":122},[24307],{"type":34,"value":125},{"type":29,"tag":88,"props":24309,"children":24310},{"class":90,"line":436},[24311,24315,24319,24324,24328,24333,24337,24342,24347,24351],{"type":29,"tag":88,"props":24312,"children":24313},{"style":105},[24314],{"type":34,"value":2886},{"type":29,"tag":88,"props":24316,"children":24317},{"style":122},[24318],{"type":34,"value":2891},{"type":29,"tag":88,"props":24320,"children":24321},{"style":157},[24322],{"type":34,"value":24323},"livresEmpruntes",{"type":29,"tag":88,"props":24325,"children":24326},{"style":122},[24327],{"type":34,"value":338},{"type":29,"tag":88,"props":24329,"children":24330},{"style":174},[24331],{"type":34,"value":24332},"size",{"type":29,"tag":88,"props":24334,"children":24335},{"style":122},[24336],{"type":34,"value":1470},{"type":29,"tag":88,"props":24338,"children":24339},{"style":163},[24340],{"type":34,"value":24341}," >=",{"type":29,"tag":88,"props":24343,"children":24344},{"style":195},[24345],{"type":34,"value":24346}," 5",{"type":29,"tag":88,"props":24348,"children":24349},{"style":122},[24350],{"type":34,"value":306},{"type":29,"tag":88,"props":24352,"children":24353},{"style":122},[24354],{"type":34,"value":125},{"type":29,"tag":88,"props":24356,"children":24357},{"class":90,"line":767},[24358,24362,24366,24370,24374,24379],{"type":29,"tag":88,"props":24359,"children":24360},{"style":105},[24361],{"type":34,"value":2927},{"type":29,"tag":88,"props":24363,"children":24364},{"style":105},[24365],{"type":34,"value":171},{"type":29,"tag":88,"props":24367,"children":24368},{"style":174},[24369],{"type":34,"value":21653},{"type":29,"tag":88,"props":24371,"children":24372},{"style":122},[24373],{"type":34,"value":181},{"type":29,"tag":88,"props":24375,"children":24376},{"style":184},[24377],{"type":34,"value":24378},"\"Un abonné ne peut pas emprunter plus de 5 livres.\"",{"type":29,"tag":88,"props":24380,"children":24381},{"style":122},[24382],{"type":34,"value":357},{"type":29,"tag":88,"props":24384,"children":24385},{"class":90,"line":792},[24386],{"type":29,"tag":88,"props":24387,"children":24388},{"style":122},[24389],{"type":34,"value":2966},{"type":29,"tag":88,"props":24391,"children":24392},{"class":90,"line":817},[24393,24398,24402,24406,24410,24415],{"type":29,"tag":88,"props":24394,"children":24395},{"style":157},[24396],{"type":34,"value":24397},"        livresEmpruntes",{"type":29,"tag":88,"props":24399,"children":24400},{"style":122},[24401],{"type":34,"value":338},{"type":29,"tag":88,"props":24403,"children":24404},{"style":174},[24405],{"type":34,"value":5471},{"type":29,"tag":88,"props":24407,"children":24408},{"style":122},[24409],{"type":34,"value":181},{"type":29,"tag":88,"props":24411,"children":24412},{"style":157},[24413],{"type":34,"value":24414},"livre",{"type":29,"tag":88,"props":24416,"children":24417},{"style":122},[24418],{"type":34,"value":357},{"type":29,"tag":88,"props":24420,"children":24421},{"class":90,"line":825},[24422],{"type":29,"tag":88,"props":24423,"children":24424},{"style":122},[24425],{"type":34,"value":433},{"type":29,"tag":88,"props":24427,"children":24428},{"class":90,"line":869},[24429],{"type":29,"tag":88,"props":24430,"children":24431},{"emptyLinePlaceholder":13},[24432],{"type":34,"value":134},{"type":29,"tag":88,"props":24434,"children":24435},{"class":90,"line":900},[24436],{"type":29,"tag":88,"props":24437,"children":24438},{"style":95},[24439],{"type":34,"value":23260},{"type":29,"tag":88,"props":24441,"children":24442},{"class":90,"line":929},[24443],{"type":29,"tag":88,"props":24444,"children":24445},{"style":122},[24446],{"type":34,"value":442},{"type":29,"tag":30,"props":24448,"children":24449},{},[24450,24455],{"type":29,"tag":447,"props":24451,"children":24452},{},[24453],{"type":34,"value":24454},"Alerte :",{"type":34,"value":24456}," Faites attention à ne pas créer des agrégats trop grands ou complexes. Ils doivent rester simples et gérables. Un agrégat ne doit pas avoir trop de dépendances. C'est exactement ce que j'ai observé dans une équipe que j'accompagnais chez un client dans le secteur bancaire : un agrégat \"Contrat\" regroupait une vingtaine d'entités et devenait impossible à tester.",{"type":29,"tag":6010,"props":24458,"children":24460},{"id":24459},"_4-service-de-domaine",[24461,24463],{"type":34,"value":24462},"4. ",{"type":29,"tag":447,"props":24464,"children":24465},{},[24466],{"type":34,"value":24467},"Service de domaine",{"type":29,"tag":30,"props":24469,"children":24470},{},[24471,24472,24477],{"type":34,"value":23291},{"type":29,"tag":447,"props":24473,"children":24474},{},[24475],{"type":34,"value":24476},"service de domaine",{"type":34,"value":24478}," encapsule la logique métier qui concerne plusieurs entités à la fois, mais ne possède pas de données propres.",{"type":29,"tag":12165,"props":24480,"children":24482},{"id":24481},"exemple-en-java-3",[24483],{"type":34,"value":22946},{"type":29,"tag":77,"props":24485,"children":24487},{"code":24486,"language":80,"meta":8,"className":81,"style":8},"public class ServiceBibliotheque {\n    public void enregistrerEmprunt(Emprunt emprunt, Livre livre) {\n        emprunt.ajouterLivre(livre);\n        \u002F\u002F Logique supplémentaire, comme la mise à jour des stocks de livres...\n    }\n}\n",[24488],{"type":29,"tag":84,"props":24489,"children":24490},{"__ignoreMap":8},[24491,24511,24562,24591,24599,24606],{"type":29,"tag":88,"props":24492,"children":24493},{"class":90,"line":91},[24494,24498,24502,24507],{"type":29,"tag":88,"props":24495,"children":24496},{"style":105},[24497],{"type":34,"value":108},{"type":29,"tag":88,"props":24499,"children":24500},{"style":105},[24501],{"type":34,"value":113},{"type":29,"tag":88,"props":24503,"children":24504},{"style":116},[24505],{"type":34,"value":24506}," ServiceBibliotheque",{"type":29,"tag":88,"props":24508,"children":24509},{"style":122},[24510],{"type":34,"value":125},{"type":29,"tag":88,"props":24512,"children":24513},{"class":90,"line":101},[24514,24518,24522,24527,24531,24536,24541,24545,24550,24554,24558],{"type":29,"tag":88,"props":24515,"children":24516},{"style":105},[24517],{"type":34,"value":276},{"type":29,"tag":88,"props":24519,"children":24520},{"style":105},[24521],{"type":34,"value":1303},{"type":29,"tag":88,"props":24523,"children":24524},{"style":174},[24525],{"type":34,"value":24526}," enregistrerEmprunt",{"type":29,"tag":88,"props":24528,"children":24529},{"style":122},[24530],{"type":34,"value":181},{"type":29,"tag":88,"props":24532,"children":24533},{"style":151},[24534],{"type":34,"value":24535},"Emprunt",{"type":29,"tag":88,"props":24537,"children":24538},{"style":298},[24539],{"type":34,"value":24540}," emprunt",{"type":29,"tag":88,"props":24542,"children":24543},{"style":122},[24544],{"type":34,"value":192},{"type":29,"tag":88,"props":24546,"children":24547},{"style":151},[24548],{"type":34,"value":24549}," Livre",{"type":29,"tag":88,"props":24551,"children":24552},{"style":298},[24553],{"type":34,"value":24299},{"type":29,"tag":88,"props":24555,"children":24556},{"style":122},[24557],{"type":34,"value":306},{"type":29,"tag":88,"props":24559,"children":24560},{"style":122},[24561],{"type":34,"value":125},{"type":29,"tag":88,"props":24563,"children":24564},{"class":90,"line":128},[24565,24570,24574,24579,24583,24587],{"type":29,"tag":88,"props":24566,"children":24567},{"style":157},[24568],{"type":34,"value":24569},"        emprunt",{"type":29,"tag":88,"props":24571,"children":24572},{"style":122},[24573],{"type":34,"value":338},{"type":29,"tag":88,"props":24575,"children":24576},{"style":174},[24577],{"type":34,"value":24578},"ajouterLivre",{"type":29,"tag":88,"props":24580,"children":24581},{"style":122},[24582],{"type":34,"value":181},{"type":29,"tag":88,"props":24584,"children":24585},{"style":157},[24586],{"type":34,"value":24414},{"type":29,"tag":88,"props":24588,"children":24589},{"style":122},[24590],{"type":34,"value":357},{"type":29,"tag":88,"props":24592,"children":24593},{"class":90,"line":137},[24594],{"type":29,"tag":88,"props":24595,"children":24596},{"style":95},[24597],{"type":34,"value":24598},"        \u002F\u002F Logique supplémentaire, comme la mise à jour des stocks de livres...\n",{"type":29,"tag":88,"props":24600,"children":24601},{"class":90,"line":211},[24602],{"type":29,"tag":88,"props":24603,"children":24604},{"style":122},[24605],{"type":34,"value":433},{"type":29,"tag":88,"props":24607,"children":24608},{"class":90,"line":262},[24609],{"type":29,"tag":88,"props":24610,"children":24611},{"style":122},[24612],{"type":34,"value":442},{"type":29,"tag":30,"props":24614,"children":24615},{},[24616,24620],{"type":29,"tag":447,"props":24617,"children":24618},{},[24619],{"type":34,"value":17780},{"type":34,"value":24621}," Un service de domaine doit rester simple et concentré sur une tâche spécifique qui ne peut pas être facilement modélisée dans une entité ou un objet de valeur.",{"type":29,"tag":6010,"props":24623,"children":24625},{"id":24624},"_5-référentiel-repository",[24626,24628],{"type":34,"value":24627},"5. ",{"type":29,"tag":447,"props":24629,"children":24630},{},[24631],{"type":34,"value":24632},"Référentiel (Repository)",{"type":29,"tag":30,"props":24634,"children":24635},{},[24636,24638,24643],{"type":34,"value":24637},"Les ",{"type":29,"tag":447,"props":24639,"children":24640},{},[24641],{"type":34,"value":24642},"référentiels",{"type":34,"value":24644}," sont chargés de la persistance des agrégats. Ils fournissent des méthodes pour récupérer et stocker des agrégats, tout en masquant les détails techniques de la persistance.",{"type":29,"tag":12165,"props":24646,"children":24648},{"id":24647},"exemple-en-java-4",[24649],{"type":34,"value":22946},{"type":29,"tag":77,"props":24651,"children":24653},{"code":24652,"language":80,"meta":8,"className":81,"style":8},"public interface EmpruntRepository {\n    Emprunt trouverParId(String id);\n    void sauvegarder(Emprunt emprunt);\n}\n",[24654],{"type":29,"tag":84,"props":24655,"children":24656},{"__ignoreMap":8},[24657,24677,24706,24734],{"type":29,"tag":88,"props":24658,"children":24659},{"class":90,"line":91},[24660,24664,24668,24673],{"type":29,"tag":88,"props":24661,"children":24662},{"style":105},[24663],{"type":34,"value":108},{"type":29,"tag":88,"props":24665,"children":24666},{"style":105},[24667],{"type":34,"value":601},{"type":29,"tag":88,"props":24669,"children":24670},{"style":116},[24671],{"type":34,"value":24672}," EmpruntRepository",{"type":29,"tag":88,"props":24674,"children":24675},{"style":122},[24676],{"type":34,"value":125},{"type":29,"tag":88,"props":24678,"children":24679},{"class":90,"line":101},[24680,24685,24690,24694,24698,24702],{"type":29,"tag":88,"props":24681,"children":24682},{"style":151},[24683],{"type":34,"value":24684},"    Emprunt",{"type":29,"tag":88,"props":24686,"children":24687},{"style":174},[24688],{"type":34,"value":24689}," trouverParId",{"type":29,"tag":88,"props":24691,"children":24692},{"style":122},[24693],{"type":34,"value":181},{"type":29,"tag":88,"props":24695,"children":24696},{"style":151},[24697],{"type":34,"value":695},{"type":29,"tag":88,"props":24699,"children":24700},{"style":298},[24701],{"type":34,"value":3435},{"type":29,"tag":88,"props":24703,"children":24704},{"style":122},[24705],{"type":34,"value":357},{"type":29,"tag":88,"props":24707,"children":24708},{"class":90,"line":128},[24709,24713,24718,24722,24726,24730],{"type":29,"tag":88,"props":24710,"children":24711},{"style":105},[24712],{"type":34,"value":681},{"type":29,"tag":88,"props":24714,"children":24715},{"style":174},[24716],{"type":34,"value":24717}," sauvegarder",{"type":29,"tag":88,"props":24719,"children":24720},{"style":122},[24721],{"type":34,"value":181},{"type":29,"tag":88,"props":24723,"children":24724},{"style":151},[24725],{"type":34,"value":24535},{"type":29,"tag":88,"props":24727,"children":24728},{"style":298},[24729],{"type":34,"value":24540},{"type":29,"tag":88,"props":24731,"children":24732},{"style":122},[24733],{"type":34,"value":357},{"type":29,"tag":88,"props":24735,"children":24736},{"class":90,"line":137},[24737],{"type":29,"tag":88,"props":24738,"children":24739},{"style":122},[24740],{"type":34,"value":442},{"type":29,"tag":30,"props":24742,"children":24743},{},[24744,24748],{"type":29,"tag":447,"props":24745,"children":24746},{},[24747],{"type":34,"value":24454},{"type":34,"value":24749}," Ne mettez pas de logique métier dans les référentiels. Ils doivent se limiter à la persistance des agrégats, sans interférer avec le domaine.",{"type":29,"tag":47,"props":24751,"children":24752},{},[],{"type":29,"tag":51,"props":24754,"children":24756},{"id":24755},"les-meilleures-pratiques-pour-implémenter-ddd",[24757],{"type":34,"value":24758},"Les meilleures pratiques pour implémenter DDD",{"type":29,"tag":30,"props":24760,"children":24761},{},[24762],{"type":34,"value":24763},"Quelques principes essentiels pour implémenter DDD de manière efficace dans vos projets Java.",{"type":29,"tag":6010,"props":24765,"children":24767},{"id":24766},"_1-commencez-par-le-domaine-pas-par-la-technologie",[24768,24769],{"type":34,"value":22440},{"type":29,"tag":447,"props":24770,"children":24771},{},[24772],{"type":34,"value":24773},"Commencez par le domaine, pas par la technologie",{"type":29,"tag":30,"props":24775,"children":24776},{},[24777,24779,24783],{"type":34,"value":24778},"Avant de vous plonger dans les frameworks ou les bases de données, assurez-vous de bien comprendre le domaine métier. Prenez le temps de discuter avec les experts du domaine pour modéliser les concepts clés de manière claire. L'",{"type":29,"tag":63,"props":24780,"children":24781},{"href":10798},[24782],{"type":34,"value":10801},{"type":34,"value":24784}," est la méthode la plus efficace pour aligner développeurs et experts métier en quelques heures et identifier les Bounded Contexts.",{"type":29,"tag":6010,"props":24786,"children":24788},{"id":24787},"_2-utilisez-des-schémas-pour-visualiser-les-agrégats",[24789,24790],{"type":34,"value":22482},{"type":29,"tag":447,"props":24791,"children":24792},{},[24793],{"type":34,"value":24794},"Utilisez des schémas pour visualiser les agrégats",{"type":29,"tag":30,"props":24796,"children":24797},{},[24798],{"type":34,"value":24799},"Les agrégats sont le cœur de votre modèle métier. Utilisez des schémas pour représenter les entités et objets de valeur qui les composent et leurs relations.",{"type":29,"tag":6010,"props":24801,"children":24803},{"id":24802},"_3-adoptez-une-approche-modulaire",[24804,24805],{"type":34,"value":22498},{"type":29,"tag":447,"props":24806,"children":24807},{},[24808],{"type":34,"value":24809},"Adoptez une approche modulaire",{"type":29,"tag":30,"props":24811,"children":24812},{},[24813],{"type":34,"value":24814},"Organisez votre application en modules correspondant aux sous-domaines. Cela vous permet de garder une structure claire et maintenable.",{"type":29,"tag":12165,"props":24816,"children":24818},{"id":24817},"exemple-de-structure-en-java",[24819],{"type":34,"value":24820},"Exemple de structure en Java :",{"type":29,"tag":77,"props":24822,"children":24824},{"code":24823},"\n\nsrc\u002F\n└── main\u002F\n    └── java\u002F\n        └── com\u002F\n            └── ma_bibliotheque\u002F\n                ├── emprunts\u002F\n                ├── abonnés\u002F\n                └── livres\u002F\n",[24825],{"type":29,"tag":84,"props":24826,"children":24827},{"__ignoreMap":8},[24828],{"type":34,"value":24823},{"type":29,"tag":6010,"props":24830,"children":24832},{"id":24831},"_4-gardez-vos-services-de-domaine-fins-et-spécifiques",[24833,24834],{"type":34,"value":24462},{"type":29,"tag":447,"props":24835,"children":24836},{},[24837],{"type":34,"value":24838},"Gardez vos services de domaine fins et spécifiques",{"type":29,"tag":30,"props":24840,"children":24841},{},[24842],{"type":34,"value":24843},"Chaque service de domaine doit être responsable d’une seule tâche métier spécifique. Cela vous aidera à garder une architecture claire et flexible.",{"type":29,"tag":6010,"props":24845,"children":24847},{"id":24846},"_5-testez-vos-domaines-métiers-de-manière-exhaustive",[24848,24849],{"type":34,"value":24627},{"type":29,"tag":447,"props":24850,"children":24851},{},[24852],{"type":34,"value":24853},"Testez vos domaines métiers de manière exhaustive",{"type":29,"tag":30,"props":24855,"children":24856},{},[24857,24859,24863],{"type":34,"value":24858},"Les tests unitaires sont essentiels pour vous assurer que votre logique métier fonctionne correctement. Je vous recommande de tester chaque agrégat et service de manière isolée. Pour que ces tests soient rapides et sans infrastructure, le ",{"type":29,"tag":63,"props":24860,"children":24861},{"href":5},[24862],{"type":34,"value":7328},{"type":34,"value":24864}," est indispensable : le domaine ne doit pas dépendre directement des implémentations concrètes.",{"type":29,"tag":12165,"props":24866,"children":24868},{"id":24867},"exemple-en-java-avec-junit",[24869],{"type":34,"value":24870},"Exemple en Java avec JUnit :",{"type":29,"tag":77,"props":24872,"children":24874},{"code":24873,"language":80,"meta":8,"className":81,"style":8},"public class EmpruntTest {\n    \n    @Test\n    public void ne_peut_pas_emprunter_plus_de_5_livres() {\n        Abonne abonne = new Abonne(\"123\", \"Jean Dupont\", \"1 Rue de Paris\");\n        Emprunt emprunt = new Emprunt(\"emprunt1\", abonne);\n        \n        for (int i = 0; i \u003C 5; i++) {\n            emprunt.ajouterLivre(new Livre(\"Livre \" + i));\n        }\n        \n        assertThrows(RuntimeException.class, () -> {\n            emprunt.ajouterLivre(new Livre(\"Livre 6\"));\n        });\n    }\n}\n",[24875],{"type":29,"tag":84,"props":24876,"children":24877},{"__ignoreMap":8},[24878,24898,24906,24917,24941,24996,25042,25050,25118,25167,25174,25181,25221,25261,25269,25276],{"type":29,"tag":88,"props":24879,"children":24880},{"class":90,"line":91},[24881,24885,24889,24894],{"type":29,"tag":88,"props":24882,"children":24883},{"style":105},[24884],{"type":34,"value":108},{"type":29,"tag":88,"props":24886,"children":24887},{"style":105},[24888],{"type":34,"value":113},{"type":29,"tag":88,"props":24890,"children":24891},{"style":116},[24892],{"type":34,"value":24893}," EmpruntTest",{"type":29,"tag":88,"props":24895,"children":24896},{"style":122},[24897],{"type":34,"value":125},{"type":29,"tag":88,"props":24899,"children":24900},{"class":90,"line":101},[24901],{"type":29,"tag":88,"props":24902,"children":24903},{"style":157},[24904],{"type":34,"value":24905},"    \n",{"type":29,"tag":88,"props":24907,"children":24908},{"class":90,"line":128},[24909,24913],{"type":29,"tag":88,"props":24910,"children":24911},{"style":1974},[24912],{"type":34,"value":3302},{"type":29,"tag":88,"props":24914,"children":24915},{"style":1980},[24916],{"type":34,"value":1983},{"type":29,"tag":88,"props":24918,"children":24919},{"class":90,"line":137},[24920,24924,24928,24933,24937],{"type":29,"tag":88,"props":24921,"children":24922},{"style":105},[24923],{"type":34,"value":276},{"type":29,"tag":88,"props":24925,"children":24926},{"style":105},[24927],{"type":34,"value":1303},{"type":29,"tag":88,"props":24929,"children":24930},{"style":174},[24931],{"type":34,"value":24932}," ne_peut_pas_emprunter_plus_de_5_livres",{"type":29,"tag":88,"props":24934,"children":24935},{"style":122},[24936],{"type":34,"value":1470},{"type":29,"tag":88,"props":24938,"children":24939},{"style":122},[24940],{"type":34,"value":125},{"type":29,"tag":88,"props":24942,"children":24943},{"class":90,"line":211},[24944,24949,24954,24958,24962,24966,24970,24974,24978,24983,24987,24992],{"type":29,"tag":88,"props":24945,"children":24946},{"style":151},[24947],{"type":34,"value":24948},"        Abonne",{"type":29,"tag":88,"props":24950,"children":24951},{"style":157},[24952],{"type":34,"value":24953}," abonne ",{"type":29,"tag":88,"props":24955,"children":24956},{"style":163},[24957],{"type":34,"value":166},{"type":29,"tag":88,"props":24959,"children":24960},{"style":105},[24961],{"type":34,"value":171},{"type":29,"tag":88,"props":24963,"children":24964},{"style":174},[24965],{"type":34,"value":22969},{"type":29,"tag":88,"props":24967,"children":24968},{"style":122},[24969],{"type":34,"value":181},{"type":29,"tag":88,"props":24971,"children":24972},{"style":184},[24973],{"type":34,"value":21871},{"type":29,"tag":88,"props":24975,"children":24976},{"style":122},[24977],{"type":34,"value":192},{"type":29,"tag":88,"props":24979,"children":24980},{"style":184},[24981],{"type":34,"value":24982}," \"Jean Dupont\"",{"type":29,"tag":88,"props":24984,"children":24985},{"style":122},[24986],{"type":34,"value":192},{"type":29,"tag":88,"props":24988,"children":24989},{"style":184},[24990],{"type":34,"value":24991}," \"1 Rue de Paris\"",{"type":29,"tag":88,"props":24993,"children":24994},{"style":122},[24995],{"type":34,"value":357},{"type":29,"tag":88,"props":24997,"children":24998},{"class":90,"line":262},[24999,25004,25009,25013,25017,25021,25025,25030,25034,25038],{"type":29,"tag":88,"props":25000,"children":25001},{"style":151},[25002],{"type":34,"value":25003},"        Emprunt",{"type":29,"tag":88,"props":25005,"children":25006},{"style":157},[25007],{"type":34,"value":25008}," emprunt ",{"type":29,"tag":88,"props":25010,"children":25011},{"style":163},[25012],{"type":34,"value":166},{"type":29,"tag":88,"props":25014,"children":25015},{"style":105},[25016],{"type":34,"value":171},{"type":29,"tag":88,"props":25018,"children":25019},{"style":174},[25020],{"type":34,"value":24059},{"type":29,"tag":88,"props":25022,"children":25023},{"style":122},[25024],{"type":34,"value":181},{"type":29,"tag":88,"props":25026,"children":25027},{"style":184},[25028],{"type":34,"value":25029},"\"emprunt1\"",{"type":29,"tag":88,"props":25031,"children":25032},{"style":122},[25033],{"type":34,"value":192},{"type":29,"tag":88,"props":25035,"children":25036},{"style":157},[25037],{"type":34,"value":24102},{"type":29,"tag":88,"props":25039,"children":25040},{"style":122},[25041],{"type":34,"value":357},{"type":29,"tag":88,"props":25043,"children":25044},{"class":90,"line":270},[25045],{"type":29,"tag":88,"props":25046,"children":25047},{"style":157},[25048],{"type":34,"value":25049},"        \n",{"type":29,"tag":88,"props":25051,"children":25052},{"class":90,"line":313},[25053,25058,25062,25066,25071,25075,25080,25084,25088,25092,25096,25100,25105,25110,25114],{"type":29,"tag":88,"props":25054,"children":25055},{"style":105},[25056],{"type":34,"value":25057},"        for",{"type":29,"tag":88,"props":25059,"children":25060},{"style":122},[25061],{"type":34,"value":2891},{"type":29,"tag":88,"props":25063,"children":25064},{"style":105},[25065],{"type":34,"value":20086},{"type":29,"tag":88,"props":25067,"children":25068},{"style":157},[25069],{"type":34,"value":25070}," i ",{"type":29,"tag":88,"props":25072,"children":25073},{"style":163},[25074],{"type":34,"value":166},{"type":29,"tag":88,"props":25076,"children":25077},{"style":195},[25078],{"type":34,"value":25079}," 0",{"type":29,"tag":88,"props":25081,"children":25082},{"style":122},[25083],{"type":34,"value":5893},{"type":29,"tag":88,"props":25085,"children":25086},{"style":157},[25087],{"type":34,"value":25070},{"type":29,"tag":88,"props":25089,"children":25090},{"style":163},[25091],{"type":34,"value":1683},{"type":29,"tag":88,"props":25093,"children":25094},{"style":195},[25095],{"type":34,"value":24346},{"type":29,"tag":88,"props":25097,"children":25098},{"style":122},[25099],{"type":34,"value":5893},{"type":29,"tag":88,"props":25101,"children":25102},{"style":157},[25103],{"type":34,"value":25104}," i",{"type":29,"tag":88,"props":25106,"children":25107},{"style":163},[25108],{"type":34,"value":25109},"++",{"type":29,"tag":88,"props":25111,"children":25112},{"style":122},[25113],{"type":34,"value":306},{"type":29,"tag":88,"props":25115,"children":25116},{"style":122},[25117],{"type":34,"value":125},{"type":29,"tag":88,"props":25119,"children":25120},{"class":90,"line":360},[25121,25126,25130,25134,25138,25142,25146,25150,25155,25159,25163],{"type":29,"tag":88,"props":25122,"children":25123},{"style":157},[25124],{"type":34,"value":25125},"            emprunt",{"type":29,"tag":88,"props":25127,"children":25128},{"style":122},[25129],{"type":34,"value":338},{"type":29,"tag":88,"props":25131,"children":25132},{"style":174},[25133],{"type":34,"value":24578},{"type":29,"tag":88,"props":25135,"children":25136},{"style":122},[25137],{"type":34,"value":181},{"type":29,"tag":88,"props":25139,"children":25140},{"style":105},[25141],{"type":34,"value":2151},{"type":29,"tag":88,"props":25143,"children":25144},{"style":174},[25145],{"type":34,"value":24549},{"type":29,"tag":88,"props":25147,"children":25148},{"style":122},[25149],{"type":34,"value":181},{"type":29,"tag":88,"props":25151,"children":25152},{"style":184},[25153],{"type":34,"value":25154},"\"Livre \"",{"type":29,"tag":88,"props":25156,"children":25157},{"style":163},[25158],{"type":34,"value":5485},{"type":29,"tag":88,"props":25160,"children":25161},{"style":157},[25162],{"type":34,"value":25104},{"type":29,"tag":88,"props":25164,"children":25165},{"style":122},[25166],{"type":34,"value":1415},{"type":29,"tag":88,"props":25168,"children":25169},{"class":90,"line":409},[25170],{"type":29,"tag":88,"props":25171,"children":25172},{"style":122},[25173],{"type":34,"value":2966},{"type":29,"tag":88,"props":25175,"children":25176},{"class":90,"line":427},[25177],{"type":29,"tag":88,"props":25178,"children":25179},{"style":157},[25180],{"type":34,"value":25049},{"type":29,"tag":88,"props":25182,"children":25183},{"class":90,"line":436},[25184,25188,25192,25197,25201,25205,25209,25213,25217],{"type":29,"tag":88,"props":25185,"children":25186},{"style":174},[25187],{"type":34,"value":4465},{"type":29,"tag":88,"props":25189,"children":25190},{"style":122},[25191],{"type":34,"value":181},{"type":29,"tag":88,"props":25193,"children":25194},{"style":157},[25195],{"type":34,"value":25196},"RuntimeException",{"type":29,"tag":88,"props":25198,"children":25199},{"style":122},[25200],{"type":34,"value":338},{"type":29,"tag":88,"props":25202,"children":25203},{"style":157},[25204],{"type":34,"value":1225},{"type":29,"tag":88,"props":25206,"children":25207},{"style":122},[25208],{"type":34,"value":192},{"type":29,"tag":88,"props":25210,"children":25211},{"style":122},[25212],{"type":34,"value":4491},{"type":29,"tag":88,"props":25214,"children":25215},{"style":105},[25216],{"type":34,"value":3147},{"type":29,"tag":88,"props":25218,"children":25219},{"style":122},[25220],{"type":34,"value":125},{"type":29,"tag":88,"props":25222,"children":25223},{"class":90,"line":767},[25224,25228,25232,25236,25240,25244,25248,25252,25257],{"type":29,"tag":88,"props":25225,"children":25226},{"style":157},[25227],{"type":34,"value":25125},{"type":29,"tag":88,"props":25229,"children":25230},{"style":122},[25231],{"type":34,"value":338},{"type":29,"tag":88,"props":25233,"children":25234},{"style":174},[25235],{"type":34,"value":24578},{"type":29,"tag":88,"props":25237,"children":25238},{"style":122},[25239],{"type":34,"value":181},{"type":29,"tag":88,"props":25241,"children":25242},{"style":105},[25243],{"type":34,"value":2151},{"type":29,"tag":88,"props":25245,"children":25246},{"style":174},[25247],{"type":34,"value":24549},{"type":29,"tag":88,"props":25249,"children":25250},{"style":122},[25251],{"type":34,"value":181},{"type":29,"tag":88,"props":25253,"children":25254},{"style":184},[25255],{"type":34,"value":25256},"\"Livre 6\"",{"type":29,"tag":88,"props":25258,"children":25259},{"style":122},[25260],{"type":34,"value":1415},{"type":29,"tag":88,"props":25262,"children":25263},{"class":90,"line":792},[25264],{"type":29,"tag":88,"props":25265,"children":25266},{"style":122},[25267],{"type":34,"value":25268},"        });\n",{"type":29,"tag":88,"props":25270,"children":25271},{"class":90,"line":817},[25272],{"type":29,"tag":88,"props":25273,"children":25274},{"style":122},[25275],{"type":34,"value":433},{"type":29,"tag":88,"props":25277,"children":25278},{"class":90,"line":825},[25279],{"type":29,"tag":88,"props":25280,"children":25281},{"style":122},[25282],{"type":34,"value":442},{"type":29,"tag":30,"props":25284,"children":25285},{},[25286,25290],{"type":29,"tag":447,"props":25287,"children":25288},{},[25289],{"type":34,"value":17780},{"type":34,"value":25291}," Les tests doivent couvrir toutes les règles métier importantes. Ils vous aideront à repérer rapidement les régressions lorsque vous faites des modifications dans votre code.",{"type":29,"tag":47,"props":25293,"children":25294},{},[],{"type":29,"tag":2288,"props":25296,"children":25298},{"cta":5629,"href":5630,"title":25297,"type":5632},"Modéliser le domaine n'est qu'une des 100 pratiques qui séparent le code junior du code senior",[25299],{"type":29,"tag":30,"props":25300,"children":25301},{},[25302],{"type":34,"value":25303},"Placer le domaine au centre, comme le montre cet article, c'est une seule pratique craft. Le Craft Bundle réunit les 100 pratiques que j'applique pour concevoir un code propre et maintenable, de la modélisation métier au découpage des agrégats jusqu'aux tests qui protègent vos règles. Ce sont les réflexes que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vus tenir un domaine complexe en production.",{"type":29,"tag":47,"props":25305,"children":25306},{},[],{"type":29,"tag":51,"props":25308,"children":25310},{"id":25309},"faq-sur-le-domain-driven-design-ddd",[25311],{"type":34,"value":25312},"FAQ sur le Domain-Driven Design (DDD)",{"type":29,"tag":5649,"props":25314,"children":25315},{},[25316,25321],{"type":29,"tag":5653,"props":25317,"children":25318},{},[25319],{"type":34,"value":25320},"1. Est-ce que le DDD est trop complexe pour les petits projets ?",{"type":29,"tag":30,"props":25322,"children":25323},{},[25324],{"type":34,"value":25325},"Pas nécessairement. Le DDD est plus adapté aux projets complexes, mais certains de ses principes peuvent être utiles même dans de plus petits projets pour organiser votre code.",{"type":29,"tag":5649,"props":25327,"children":25328},{},[25329,25334],{"type":29,"tag":5653,"props":25330,"children":25331},{},[25332],{"type":34,"value":25333},"2. Dois-je utiliser tous les concepts du DDD dès le début ?",{"type":29,"tag":30,"props":25335,"children":25336},{},[25337],{"type":34,"value":25338},"Non, vous pouvez les introduire progressivement en fonction de vos besoins.",{"type":29,"tag":5649,"props":25340,"children":25341},{},[25342,25347],{"type":29,"tag":5653,"props":25343,"children":25344},{},[25345],{"type":34,"value":25346},"3. Est-ce que je dois utiliser un framework spécifique pour appliquer DDD en Java ?",{"type":29,"tag":30,"props":25348,"children":25349},{},[25350],{"type":34,"value":25351},"Non. Vous pouvez utiliser des bibliothèques comme Spring ou Hibernate tout en organisant votre code selon les principes de DDD.",{"type":29,"tag":5649,"props":25353,"children":25354},{},[25355,25360],{"type":29,"tag":5653,"props":25356,"children":25357},{},[25358],{"type":34,"value":25359},"4. Comment savoir si j’ai correctement modélisé mon domaine ?",{"type":29,"tag":30,"props":25361,"children":25362},{},[25363],{"type":34,"value":25364},"Si un expert métier peut comprendre votre modèle sans difficultés, c’est un bon signe.",{"type":29,"tag":5649,"props":25366,"children":25367},{},[25368,25373],{"type":29,"tag":5653,"props":25369,"children":25370},{},[25371],{"type":34,"value":25372},"5. Comment éviter que les agrégats deviennent trop gros ?",{"type":29,"tag":30,"props":25374,"children":25375},{},[25376],{"type":34,"value":25377},"Divisez-les si nécessaire. Un agrégat doit rester cohérent et ne contenir que les entités nécessaires à son bon fonctionnement.",{"type":29,"tag":5649,"props":25379,"children":25380},{},[25381,25386],{"type":29,"tag":5653,"props":25382,"children":25383},{},[25384],{"type":34,"value":25385},"6. Et si l’équipe métier change souvent d’avis ?",{"type":29,"tag":30,"props":25387,"children":25388},{},[25389],{"type":34,"value":25390},"DDD permet de mieux gérer les changements car la logique métier est bien isolée dans le code, ce qui facilite les modifications.",{"type":29,"tag":5649,"props":25392,"children":25393},{},[25394,25399],{"type":29,"tag":5653,"props":25395,"children":25396},{},[25397],{"type":34,"value":25398},"7. Combien de temps faut-il pour maîtriser le DDD ?",{"type":29,"tag":30,"props":25400,"children":25401},{},[25402],{"type":34,"value":25403},"Cela dépend de votre expérience, mais en commençant avec les bases, vous pouvez progresser rapidement.",{"type":29,"tag":2288,"props":25405,"children":25408},{"cta":25406,"href":16240,"title":25407,"type":5755},"Télécharger le diagnostic gratuit →","Ressource gratuite : 10 signaux que votre équipe tech est en danger",[25409],{"type":29,"tag":30,"props":25410,"children":25411},{},[25412],{"type":34,"value":25413},"10 signaux d'alarme pour identifier les problèmes systémiques cachés dans votre équipe avant qu'ils deviennent critiques. Auto-diagnostic inclus : 5 minutes pour savoir où vous en êtes.",{"type":29,"tag":5763,"props":25415,"children":25416},{},[25417],{"type":34,"value":5767},{"title":8,"searchDepth":101,"depth":101,"links":25419},[25420,25421,25424,25436,25448],{"id":22791,"depth":101,"text":22794},{"id":22821,"depth":101,"text":22824,"children":25422},[25423],{"id":22850,"depth":128,"text":22853},{"id":22910,"depth":101,"text":22913,"children":25425},[25426,25428,25430,25432,25434],{"id":22921,"depth":128,"text":25427},"1. Entité",{"id":23279,"depth":128,"text":25429},"2. Objet de valeur (Value Object)",{"id":24006,"depth":128,"text":25431},"3. Agrégat",{"id":24459,"depth":128,"text":25433},"4. Service de domaine",{"id":24624,"depth":128,"text":25435},"5. Référentiel (Repository)",{"id":24755,"depth":101,"text":24758,"children":25437},[25438,25440,25442,25444,25446],{"id":24766,"depth":128,"text":25439},"1. Commencez par le domaine, pas par la technologie",{"id":24787,"depth":128,"text":25441},"2. Utilisez des schémas pour visualiser les agrégats",{"id":24802,"depth":128,"text":25443},"3. Adoptez une approche modulaire",{"id":24831,"depth":128,"text":25445},"4. Gardez vos services de domaine fins et spécifiques",{"id":24846,"depth":128,"text":25447},"5. Testez vos domaines métiers de manière exhaustive",{"id":25309,"depth":101,"text":25312},"content:fr:architecture-craft:decouvrir-domain-driven-design-ddd-avantages-exemples-java.md","fr\u002Farchitecture-craft\u002Fdecouvrir-domain-driven-design-ddd-avantages-exemples-java.md","fr\u002Farchitecture-craft\u002Fdecouvrir-domain-driven-design-ddd-avantages-exemples-java",1784113937498]