{"id":13516315,"url":"https://github.com/ddd-by-examples/factory","last_synced_at":"2025-05-16T04:05:46.331Z","repository":{"id":38485837,"uuid":"113012366","full_name":"ddd-by-examples/factory","owner":"ddd-by-examples","description":"The missing, complete example of Domain-Driven Design enterprise application backed by Spring stack","archived":false,"fork":false,"pushed_at":"2022-03-10T00:14:10.000Z","size":9782,"stargazers_count":1356,"open_issues_count":3,"forks_count":272,"subscribers_count":122,"default_branch":"master","last_synced_at":"2025-04-08T14:11:09.296Z","etag":null,"topics":["aggregate","cqrs","crud","domain-driven-design","domain-events","domain-knowledge","domain-model","enterprise-applications","event-storming","hexagon","invariants","ports-and-adapters"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ddd-by-examples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-04T07:53:57.000Z","updated_at":"2025-04-02T08:12:31.000Z","dependencies_parsed_at":"2022-08-09T04:31:14.691Z","dependency_job_id":null,"html_url":"https://github.com/ddd-by-examples/factory","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddd-by-examples%2Ffactory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddd-by-examples%2Ffactory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddd-by-examples%2Ffactory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddd-by-examples%2Ffactory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ddd-by-examples","download_url":"https://codeload.github.com/ddd-by-examples/factory/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254464895,"owners_count":22075570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aggregate","cqrs","crud","domain-driven-design","domain-events","domain-knowledge","domain-model","enterprise-applications","event-storming","hexagon","invariants","ports-and-adapters"],"created_at":"2024-08-01T05:01:21.264Z","updated_at":"2025-05-16T04:05:41.321Z","avatar_url":"https://github.com/ddd-by-examples.png","language":"Java","readme":"# The missing, complete example of Domain-Driven Design enterprise application\n\n[![Licence MIT](http://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)\n[![Build Status](https://travis-ci.org/ddd-by-examples/factory.svg?branch=master)](https://travis-ci.org/ddd-by-examples/factory)\n[![Code Coverage](https://codecov.io/gh/ddd-by-examples/factory/branch/master/graph/badge.svg)](https://codecov.io/gh/ddd-by-examples/factory)\n\n## Command Query CRUD Responsibility Segregation\nNot every piece of software is equally important...\nNot every piece will decide about company / product success or can cause not reversible\nnegative business consequences like materialise brand risk or money loses.\nOn the other hand scalability or non functional requirements are different for different activities in software.\n\nTo accommodate to those differences, separate architectural patterns are applied:\n\n![Command Query CRUD Responsibility Segregation](command-query-crud.png)\n\n**Simple Create Read Update Delete functionality** are exposed with leverage of CRUD framework.\n\nGoals of that approach:\n- fast initial development,\n- fast respond to typical changes (ex. „please add another 2 fields on UI”),\n- exposure of high quality API.\n\nExamples in code:\n- CRUD-able document [ProductDescription](product-management-adapters/src/main/java/io/dddbyexamples/factory/product/management/ProductDescription.java)\n- persistence of document [ProductDescriptionEntity](product-management-adapters/src/main/java/io/dddbyexamples/factory/product/management/ProductDescriptionEntity.java)\n- CRUD exposed as DAO and REST endpoint [ProductDescriptionDao](product-management-adapters/src/main/java/io/dddbyexamples/factory/product/management/ProductDescriptionDao.java)\n\n**Complex Commands (business processing)** expressed in Domain Model which is embedded in hexagonal architecture.\n\nGoals of that approach:\n- enable approach with implementing the Domain Model in the first place, by adding infrastructure adapters later,\n- keeping the Domain Model as simple as possible by protecting it from accidental complexity\ncaused by technological choices or transport models from external services / contexts,\n- make the core business of application technology agnostic, enabling continues technology\nmigration and keeping long living projects up to date with fast evolving frameworks and libraries.\n\nExamples of Domain Model in code:\n- aggregate [ProductDemand](demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/ProductDemand.java)\n- entity [DailyDemand](demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DailyDemand.java)\n- value object [Adjustment](demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/Adjustment.java)\n- policy [ReviewPolicy](demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/ReviewPolicy.java)\n- domain event [DemandedLevelsChanged](shared-kernel-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandedLevelsChanged.java)\n\nExamples of Ports in code:\n- application service (primary port) [DemandService](demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)\n- repository (secondary port) [ProductDemandRepository](demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/ProductDemandRepository.java)\n- domain events handling (secondary port) [DemandEvents](demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandEvents.java)\n\nExamples of Adapters in code:\n- REST endpoint for complex command (driving adapter)\n  - command resource [DemandAdjustmentDao](demand-forecasting-adapters/src/main/java/io/dddbyexamples/factory/demand/forecasting/command/DemandAdjustmentDao.java)\n  - command handler [CommandsHandler](demand-forecasting-adapters/src/main/java/io/dddbyexamples/factory/demand/forecasting/command/CommandsHandler.java)\n- repository implementation (driven adapter) [ProductDemandORMRepository](demand-forecasting-adapters/src/main/java/io/dddbyexamples/factory/demand/forecasting/ProductDemandORMRepository.java)\n- events propagation (driven adapter) [DemandEventsPropagation](app-monolith/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandEventsPropagation.java)\n\n**Complex Query** implemented as direct and simple as possible by:\n- fetching persistent read model expected by consumer, the read model is a projection of past domain event,\n- read model composed at query execution time build directly from persistent form of Domain Model,\n- mix of above: read model composed at query execution time build from pre-calculated persistent projections of domain event.\n\nAdditional complex calculations or projections can be partially delegated to the Domain Model if desired.\n\nGoals of that approach:\n- encapsulation of the Domain Model complexity by providing (simpler) consumer driven or published language API,\n- freeing the Domain Model from exposing data for reads making the Domain Model simpler,\n- improves reads performance and enable horizontal scalability.\n\nExamples in code:\n- projection of domain events to persistent read model [DeliveryForecastProjection](demand-forecasting-adapters/src/main/java/io/dddbyexamples/factory/delivery/planning/projection/DeliveryForecastProjection.java)\n- REST endpoint for persistent read model [DeliveryForecastDao](demand-forecasting-adapters/src/main/java/io/dddbyexamples/factory/delivery/planning/projection/DeliveryForecastDao.java)\n- read model composed at query execution time [StockForecastQuery](app-monolith/src/main/java/io/dddbyexamples/factory/stock/forecast/StockForecastQuery.java)\n- REST resource processor for NOT persistent read model [StockForecastResourceProcessor](app-monolith/src/main/java/io/dddbyexamples/factory/stock/forecast/ressource/StockForecastResourceProcessor.java)\n\n## Hexagonal Architecture\nOnly the most valuable part of that enterprise software is embedded in hexagonal architecture -\ncomplex business processing modeled in form of the Domain Model.\n\n![Domain Model embedded in hexagonal architecture](hexagon.png)\n\n**Application Services** - providing entry point to Domain Model functionality,\nApplication Services are ports for Primary / Driving Adapters like RESTfull endpoints.\n\n**Domain Model** - Object Oriented (in that case) piece of software modeling business rules, invariants,\ncalculations and processing variants.\nThanks to hexagon can be as clean and simple as possible - separating essential complexity of pure business\nfrom accidental complexity of technical choices, free of technical and convention constraints.\n\n**Ports** - contract defined by Domain Model expressing expectations from external resources (services, database or other models).\nDeclared interfaces alongside with IN-OUT parameters are Ports for Secondary / Driven Adapters like repository implementation.\n\n**Adapters** - integration of the technology (REST, database, external services, etc.) with the Domain Model.\nMaking useful application from the Domain Model and the technology.\n\n\n## Implementing Domain Model in the first place\nIn most projects the biggest risk is lack of domain knowledge among developers. We all known Java,\ndatabases and bunch of handy frameworks, but what about: Investment Banking, Automotive Manufacturing or even e-Commerce.\n\nLet's face the risk at first, maintain and explore domain knowledge\nwith **Model Exploration Whirlpool** and build **Ubiquitous Language** with your executable **Domain Model**,\n**Domain Stories** and **Specification by Examples** from day one.\nAdding infrastructure and technology later is easy thanks to Hexagonal Architecture.\n\nSimply starting from ZERO business knowledge through initial domain and opportunity exploration with **Big Picture Event Storming**:\n![Big Picture Event Storming](es-big-picture-original.jpg)\n\nafter cleaning and trimming initial model to most valuable and needed areas: \n![Big Picture Event Storming](es-big-picture-cleaned.jpg)\n\nDeep dive in **Demand Forecasting** sub-domain with **Design Level Event Storming**:\n![Design Level Event Storming - Demand Forecasting](es-design-demand-forecasting.jpg)\n\nis excellent canvas to cooperative exploration of:\n- impacted and required actors,\n- initial / desired system boundaries,\n- actors interactions with system under design.\n\nWith use of **Domain Stories** and **Specification by Examples** it is easy to find:\n- business rules and invariants,\n- acceptance criteria,\n- estimation of Domain Model depth,\n- CRUD-suspected activities,\n- missing parts.\n","funding_links":[],"categories":["Uncategorized","Java","Usage, software implementations using EventStorming","Code Examples"],"sub_categories":["Uncategorized","[CUPID](https://dannorth.net/2022/02/10/cupid-for-joyful-coding/)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddd-by-examples%2Ffactory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fddd-by-examples%2Ffactory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddd-by-examples%2Ffactory/lists"}