{"id":21540511,"url":"https://github.com/othercodes/complexheart","last_synced_at":"2025-10-28T02:17:23.442Z","repository":{"id":45595793,"uuid":"315932890","full_name":"othercodes/ComplexHeart","owner":"othercodes","description":"Provide a set of useful classes and tools to ease the adoption of Domain Driven Design into your project.","archived":false,"fork":false,"pushed_at":"2023-09-11T13:03:22.000Z","size":101,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2024-04-16T02:21:54.871Z","etag":null,"topics":["aggregates","commandbus","cqrs","ddd","domain-driven-design","entities","eventbus","hexagonal-architecture","querybus","value-object"],"latest_commit_sha":null,"homepage":"","language":"PHP","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/othercodes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2020-11-25T12:29:15.000Z","updated_at":"2023-02-19T16:35:42.000Z","dependencies_parsed_at":"2023-02-08T19:00:42.007Z","dependency_job_id":null,"html_url":"https://github.com/othercodes/ComplexHeart","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othercodes%2FComplexHeart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othercodes%2FComplexHeart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othercodes%2FComplexHeart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othercodes%2FComplexHeart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/othercodes","download_url":"https://codeload.github.com/othercodes/ComplexHeart/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226123407,"owners_count":17577040,"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":["aggregates","commandbus","cqrs","ddd","domain-driven-design","entities","eventbus","hexagonal-architecture","querybus","value-object"],"created_at":"2024-11-24T04:19:13.651Z","updated_at":"2025-10-28T02:17:23.333Z","avatar_url":"https://github.com/othercodes.png","language":"PHP","readme":"# ComplexHeart\n\n[![Latest Stable Version](https://poser.pugx.org/othercode/complex-heart/v)](//packagist.org/packages/othercode/complex-heart)\n[![License](https://poser.pugx.org/othercode/complex-heart/license)](//packagist.org/packages/othercode/complex-heart)\n![Tests](https://github.com/othercodes/ComplexHeart/workflows/Tests/badge.svg)\n[![codecov](https://codecov.io/gh/othercodes/ComplexHeart/branch/main/graph/badge.svg?token=wL3xLFaT22)](https://codecov.io/gh/othercodes/ComplexHeart)\n\n## About\n\nThe **Complex Heart** name stands from \"_Domain-Driven Design: Tackling Complexity in the Heart of Software_\" Eric Evans\nBook. This project intends to provide a set of useful classes and tools to ease the adoption of Domain Driven Design\ninto your project.\n\n## Domain Modeling: Aggregates, Entities and Value Objects\n\nComplex Heart allows you to model your domain Aggregates, Entities, and Value Objects using a set of traits. Great, but\nwhy traits and not classes? Well, sometimes you have some kind of inheritance in your classes. Being forced to use a\ncertain base class is too invasive and personally, I don't like it. By using a set of traits and interfaces you have all\nthe functionality you need without compromising the essence of your own domain.\n\nLet's see a very basic example:\n\n```php\nuse OtherCode\\ComplexHeart\\Domain\\Contracts\\ValueObject;\nuse OtherCode\\ComplexHeart\\Domain\\Traits\\IsValueObject;\n\n/**\n * Class Color\n * @method string value()\n */\nfinal class Color implements ValueObject \n{\n    use IsValueObject;\n    \n    private string $value;\n \n    public function __construct(string $value) {\n        $this-\u003einitialize(['value' =\u003e $value]);\n    }\n    \n    protected function invariantValueMustBeHexadecimal(): bool {\n        return preg_match('/^#(?:[0-9a-fA-F]{3}){1,2}$/', $this-\u003evalue) === 1;\n    }\n    \n    public function __toString(): string {\n        return $this-\u003evalue();\n    }\n}\n\n$red = new Color('#ff0000');\n$red-\u003eequals(new Color('#00ff00')); // false\n$red-\u003evalue(); // #ff0000\n$magenta = new Color('ff00ff'); // Exception InvariantViolation: Value must be hexadecimal.\n```\n\nTo define a Value Object you only need to use the `IsValueObject` trait, this will allow you to use some functions like\n`equals()` that will automatically compare the value of the objects or `initialize()` that will allow you to run\ninvariant validations against the object values. Optionally, and recommended, you can use the `ValueObject` interface.\n\nThe available traits are:\n\n- `HasAttributes` Provide some functionality to manage attributes.\n- `HasEquality` Provide functionality to handle equality between objects.\n- `HasInvariants` Allow invariant checking on instantiation (Guard Clause).\n- `HasIdentity` Define the Entity/Aggregate identity.\n- `HasDomainEvents` Provide domain event management.\n\nOn top of those base traits **Complex Heart** provide ready to use compositions:\n\n- `IsModel` composed by `HasAttributes` and `HasInvariants`\n- `IsValueObject` composed by `IsModel` and `HasEquality`\n- `IsEntity` composed by `IsModel`, `HasIdentity`, `HasEquality`\n- `IsAggregate` composed by `IsEntity`, `HasDomainEvents`\n\n## Service Bus: Commands, Queries and Events\n\nThe Service Bus integration contains some basic interfaces (`ServiceBus`, `CommandBus`, `QueryBus`, and `EventBus`) and\nclasses to build on top of them.\n\n- `Message` Base DTO to transfer objects between layers.\n    - `Request`\n        - `Command` Command DTO.\n        - `Event` Event DTO.\n        - `Query` Query DTO.\n    - `Response`\n\nCheck this small example of the usage:\n\n```php \n$response = $queryBus-\u003eask(new GetUserQuery('some-uuid-value'));\n```\n\nCheck the [wiki](https://github.com/othercodes/ComplexHeart/wiki) for more detailed examples.\n\n## References\n\n- [Pro Codely TV](https://pro.codely.tv/library/)\n- [martinFowler.com](https://martinfowler.com/tags/domain%20driven%20design.html)\n- [Clean Architecture](https://amzn.to/2ImCugP)\n- [Clean Code](https://amzn.to/3goF2HK)\n- [Domain-Driven Design: Tackling Complexity in the Heart of Software](https://amzn.to/2K0gJ6S)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fothercodes%2Fcomplexheart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fothercodes%2Fcomplexheart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fothercodes%2Fcomplexheart/lists"}