DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Software Design and Architecture
  3. Microservices
  4. Building Microservices Through Event-Driven Architecture, Part 2: Domain Objects and Business Rules

Building Microservices Through Event-Driven Architecture, Part 2: Domain Objects and Business Rules

In this tutorial, an architect explores how microservices teams can work with domain objects while creating an event-driven architecture for their app.

Gora LEYE user avatar by
Gora LEYE
·
Apr. 04, 19 · Tutorial
Like (10)
Save
Tweet
Share
18.40K Views

Join the DZone community and get the full member experience.

Join For Free

this tutorial is the second part of a series: building microservices through event driven architecture .

during this journey, i will implement the domain model: edusync.speech.domain,

this is the innermost layer that holds the core domain. it contains our domain objects and business rules. and defines our external interfaces.

databases, network connections, filesystem, ui or special frameworks are not allowed.

the core domain has no knowledge of anything outside of itself.

those dependencies and their implementations are injected into our core domain using interfaces.

at the end of the previous step, we ended up with an anemic domain model. so let's start by enriching it.

rich domain model

an anemic domain model is an antipattern in the world of ddd, so, in this section, i will decouple the domain model from data contracts using value object.

an anemic domain model is a domain model where data and operations upon that data are separated from each other. in other words, a class with only properties and methods that treat these properties are located in other classes.

as a result, these other classes can read the data but also modify it. so the domain class must have public setters. this is a lack of encapsulation antipattern:

let us begin by validation the title.

my first test will be: the title length must be greater than 10 characters and less than 60 characters

.

the test will fail, so let us implement title validation.

title value object

the main difference between the entity and value object is how to identify them.

an entity is identified by reference equality and identifier equality.

a value object is identified by reference equality and structural equality

  • reference equality: two objects are equal if they reference the same object in memory.
  • identifier equality: two objects are equal if they have the same identity.
  • structural equality: two objects are equal if all their members are equals.

an entity has an id field and is mutable while a value object have no id field and is immutable.

a value object does not make sense without an entity, as it must belong to an entity.

consider the following situation:

  • two vehicles of the same model, that have the same colors, are the same age, etc. are always two different vehicles because each vehicle has its own identifier: 'vehicle' is an entity.
  • two addresses that have all their fields equals (same street number, same city, same country, etc.) are exactly the same address: 'adress' is a value object.

my first implementation of title looks like this:

let us fix the test:

remember that a value object is identified by reference equality and structural equality.

so right-click the title class and select generate equals and gethashcode.

title has only one value, so select it and click ok

the title is now a value object and it's final implementation will look like this

here is the unit test of the title value object. i should verify that two titles are equal if they have the same values, and different if not.

url value object

all the logic to validate a url is implemented inside a value object whose name is urlvalue .

type value object

all the logic to validate a speech type is implemented inside a value object whose name is speechtype .

and the speech domain object looks like this:

entities and aggregates

remember that an entity is identified by reference equality and identifier equality and has an id field. so let us create a base entity class : entity<t> , and generate equals and gethashcode on the id field. if two entities, e1 and e2, have the same id, then e1==e2 should return true

"a ddd aggregate is a cluster of domain objects that can be treated as a single unit. an example may be an order and its line-items, these will be separate objects, but it's useful to treat the order (together with its line items) as a single aggregate." - martin fowler

an aggregate should be always in a valid state and each aggregate should have a root which is an entity, and classes that do not belong to this aggregate can only reference the aggregate root.

so, let us create a base class, aggregateroot<t> , that inherits from entity<t> . i make it generic because t is the type of the id field. and it can vary according to these entities:

domain events

domain events enable communication between bounded contexts by avoiding direct calls. so a bounded context, b1, raises an event and one or more bounded contexts, b2...bn subcribers to this event, should handle the event to consume it.

so let us create a base class called domainevent :

but here, because of my strategy of implementing event sourcing, all the events produced by my bounded context will be saved in my eventstore. and other bounded contexts, services or other programs interested in these events will have to subscribe to a service bus.

for example, each time i create a new speech, then i will create a speechcreatedevent event:

the speechcreatedevent class must inherit from the domainevent base class:

the final implementation of my aggregateroot will look like this :

and because speech entity is the aggregate root, let us go ahead and inherit it from aggregateroot<guid>, use the id field of speech entity as a guide:

let us add a few tests to cover domain events:

logcorner.edusync.speech.application and logcorner.edusync.speech.domain yield 100 percent code coverage:

thank you for reading!

the source code is availabe here: registerspeechdomain .

Object (computer science) Database Event-driven architecture microservice Domain model Event unit test Architecture

Published at DZone with permission of Gora LEYE, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • [DZone Survey] Share Your Expertise and Take our 2023 Web, Mobile, and Low-Code Apps Survey
  • 10 Easy Steps To Start Using Git and GitHub
  • Use Golang for Data Processing With Amazon Kinesis and AWS Lambda
  • How To Build an Effective CI/CD Pipeline

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: