Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/josecelano/ddd-aggregates-and-zombies
Use case for DDD aggregates without persisting objects in DB.
https://github.com/josecelano/ddd-aggregates-and-zombies
aggregates ddd nodejs
Last synced: about 1 month ago
JSON representation
Use case for DDD aggregates without persisting objects in DB.
- Host: GitHub
- URL: https://github.com/josecelano/ddd-aggregates-and-zombies
- Owner: josecelano
- Created: 2021-05-22T20:23:24.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2021-06-25T12:45:25.000Z (over 3 years ago)
- Last Synced: 2024-12-17T06:07:38.775Z (about 1 month ago)
- Topics: aggregates, ddd, nodejs
- Language: JavaScript
- Homepage:
- Size: 576 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# DDD aggregates & zombies
![example workflow](https://github.com/josecelano/ddd-aggregates-and-zombies/actions/workflows/main.yml/badge.svg)
![Screenshot](doc/img/screenshot.png)
Why this repo? I think there are two main sources to learn about DDD agregates or at least those were the sources where I got a better understanding about aggregates from. In both cases the authors use an example with database and transactions. I wonder if:
* DDD aggregates design makes sense without persisting objects. I mean, can we use the same design principles to keep consistency only having objects in memory?
* Can I came up with a simpler sample to explain DDD agregates without using databases?I decided to write this small sample to learn more about DDD aggregates. I think the problem they solve it's a generic concurrency problem, in the sense of having 2 entities trying to update a shared state in a context where race conditions can happen. My idea was:
1. First, try to reproduce such scenario where I have a domain invariant and 2 objects updating a shared state.
2. Second, try to find out if what I learnt from both articles also apply only to objects in memory and if I can keep domain invariant designing the rigth aggregates.
3. Finally, if they also apply, try to explain the example step by step in order to have the most simple possible example about DDD aggregates (withput involving databases).Althougth the sample is finished the resoning about this topic (or learning) is a WIP. I would like to write the:
[Full explanation about this example](doc/ddd-agregates.md)
## Requirements
* Node 14.17.0
* Docker 20.10.5## Run
With docker:
```
docker run --rm -it josecelano/ddd-aggregates-and-zombies
```Dockerhub image: https://hub.docker.com/r/josecelano/ddd-aggregates-and-zombies
You can also install the project (clone, build and run).
## Install
From repo:
```
git clone [email protected]:josecelano/ddd-aggregates-and-zombies.git
./bin/docker/build.sh
./bin/docker/run.sh
```## Development
Build docker image:
```
./bin/docker/build.sh
```Run app with concurrency problem:
```
./bin/docker/run.sh
```After some seconds you will get this error:
```
/usr/src/app/lib/apocalyptic_world.js:83
throw new RangeError(`The cell ${coordinate.toString()} is already occupied by another zombie`);
^RangeError: The cell (7,17) is already occupied by another zombie
at ApocalypticWorld.guardThatCellIsNotMarkedAsOccupiedTwice (/usr/src/app/lib/apocalyptic_world.js:83:13)
at ApocalypticWorld.markCellAsOccupiedByAZombie (/usr/src/app/lib/apocalyptic_world.js:51:10)
at ApocalypticWorld.moveZombie (/usr/src/app/lib/apocalyptic_world.js:38:10)
at Timeout._onTimeout (/usr/src/app/lib/game.js:76:20)
at listOnTimeout (internal/timers.js:557:17)
at processTimers (internal/timers.js:498:7)
error Command failed with exit code 1.
```Run app with mutual exclusivity to avoid race contitions using the Game aggregate:
```
./bin/docker/run-aggregate.sh
```Run and connect to docker image on development environment:
```
./bin/docker/up.sh
```Run tests:
```
./bin/docker/test.sh
```## Links
* [Vaughn Vernon - Effective Aggregate Design](https://www.dddcommunity.org/library/vernon_2011/)
* [Buenosvinos/Soronellas/Akbary - DDD in PHP book](https://leanpub.com/ddd-in-php)## TODO
* Add missing tests for new changes.
* Code review: add a wrapper method to the world for `zombie.thinkWhereToWalk(world);` like this `world.makeZombieWalk(zombie)`
* Code review: rename `world.moveZombie(zombie);` to `world.makeZombieWalk(zombie);`?
* Test intervals. The current test coverage report shows that the intervals functions are not being covered althougth in fact, they are:```
--------------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------------|---------|----------|---------|---------|-------------------
All files | 95.68 | 93.48 | 97.26 | 96.13 |
apocalyptic_world.js | 100 | 100 | 100 | 100 |
coordinate.js | 100 | 100 | 100 | 100 |
coordinate_collection.js | 100 | 100 | 100 | 100 |
game.js | 85.11 | 62.5 | 89.47 | 86.96 | 61,73-79
grid.js | 100 | 100 | 100 | 100 |
print_world.js | 100 | 100 | 100 | 100 |
random.js | 100 | 100 | 100 | 100 |
zombie.js | 100 | 100 | 100 | 100 |
--------------------------|---------|----------|---------|---------|-------------------
```