Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

  • Contact Us
Oleksandr

Oleksandr Sydorenko

alex@smartphonekey.com

0

Article
Last Month

Oleksandr articles

All Categories
  • All Categories
  • System Architecture

Data Mesh

Published May 5th, 2025 by Oleksandr Sydorenko

The data mesh architecture is, in a sense, domain-driven design for analytical data. As the different patterns of DDD draw boundaries and protect their contents, the data mesh architecture defines and protects model and ownership boundaries for analytical data. The data mesh architecture is based on four core principles: decompose data around domain

1 min

Subdomains

Published May 5th, 2025 by Oleksandr Sydorenko

As you learned in Chapter 1 , there are three types of subdomains— core, supporting, and generic—and it’s important to identify the subdomains at play when designing the solution. It can be challenging to identify a subdomain’s type. As we discussed in Chapter 1 , it’s important to identify the subdomains at the granularity level that is relevant to

2 min

Pragmatic Domain-Driven Design

Published May 5th, 2025 by Oleksandr Sydorenko

As we discussed in this chapter’s introduction, applying domain-driven design is not an all-or-nothing endeavor. You don’t have to apply every tool DDD has to offer. For example, for some reason, the tactical patterns might not work for you. Maybe you prefer to use other design patterns because they work better in your specific domain, or just becau

10 Views 1 min

Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

Bounded contexts, on the other hand, are designed. Choosing models’ boundaries is a strategic design decision. We decide how to divide the business domain into smaller, manageable problem domains.

13 Views 1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which bounded context integration pattern requires implementation of model transformation logic? a. Conformist b. Anticorruption layer c. Open-host service d. B and C 2. What is the goal of the outbox pattern? a. Decouple messaging infrastructure from the system’s business logic layer b. Reliably publish messages c. Support implementation of the

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

This chapter explained the event sourcing pattern and its application for modeling the dimension of time in the domain model’s aggregates. In an event-sourced domain model, all changes to an aggregate’s state are expressed as a series of domain events. That’s in contrast to the more traditional approaches in which a state change just updates a recor

1 min

Implementation

Published May 5th, 2025 by Oleksandr Sydorenko

A domain model is an object model of the domain that incorporates both behavior and data. 1 DDD’s tactical patterns—aggregates, value objects, domain events, and domain services—are the building blocks of such an object model. 2 All of these patterns share a common theme: they put the business logic first. Let’s see how the domain model addresses di

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

Whenever we stumble upon an inherent conflict in the domain experts’ mental mod‐ els, we have to decompose the ubiquitous language into multiple bounded contexts. A ubiquitous language should be consistent within the scope of its bounded context. However, across bounded contexts, the same terms can have different meanings. While subdomains are disco

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which of the following statements is true? a. Value objects can only contain data. b. Value objects can only contain behavior. c. Value objects are immutable. d. Value objects’ state can change. 2. What is the general guiding principle for designing the boundary of an aggregate? a. An aggregate can contain only one entity as only one instance of

1 min

Challenges

Published May 5th, 2025 by Oleksandr Sydorenko

Despite the apparent scaling and performance advantages of the asynchronous pro‐ jection method, it is more prone to the challenges of distributed computing. If the messages are processed out of order or duplicated, inconsistent data will be projected into the read models. This method also makes it more challenging to add new projections or regenera

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which of the discussed patterns should be used for implementing a core subdo‐ main’s business logic? a. Transaction script. b. Active record. c. Neither of these patterns can be used to implement a core subdomain. d. Both can be used to implement a core subdomain. 2. Consider the following code: public void CreateTicket (TicketData data ) { var a

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

Historically, the microservice-based architectural style is deeply interconnected with domain-driven design, so much so that the terms microservice and bounded context are often used interchangeably. In this chapter, we analyzed the connection between the two and saw that they are not the same thing. All microservices are bounded contexts, but not a

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

This chapter connected Parts I and II of the book to a heuristic-based decision frame‐ work. You learned how to apply the knowledge of the business domain and its subdo‐ mains to drive technical decisions: choosing safe bounded context boundaries, modeling the application’s business logic, and determining the architectural pattern needed to orchestr

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. What kind of changes in bounded context integration are often caused by organi‐ zational growth? a. Partnership to customer–supplier (conformist, anticorruption layer, or open- host service) b. Anticorruption layer to open-host service c. Conformist to shared kernel d. Open-host service to shared kernel 2. Assume that the bounded contexts’ integr

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Who should be invited to an EventStorming session? a. Software engineers b. Domain experts c. QA engineers d. All stakeholders having knowledge of the business domain that you want to explore 2. When is it a good opportunity to facilitate an EventStorming session? a. To build a ubiquitous language. b. To explore a new business domain. c. To recov

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

Bounded contexts are not independent. They have to interact with one another. The following patterns define different ways bounded contexts can be integrated: Partnership Bounded contexts are integrated in an ad hoc manner. Shared kernel Two or more bounded contexts are integrated by sharing a limited overlapping model that belongs to all participat

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which of the following statements is correct regarding the relationship between domain events and value objects? a. Domain events use value objects to describe what has happened in the busi‐ ness domain. b. When implementing an event-sourced domain model, value objects should be refactored into event-sourced aggregates. c. Value objects are relev

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which of the discussed architectural patterns can be used with business logic implemented as the active record pattern? a. Layered architecture b. Ports & adapters c. CQRS d. A and C 2. Which of the discussed architectural patterns decouples the business logic from infrastructural concerns? a. Layered architecture b. Ports & adapters c. C

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

In this chapter, you learned the different patterns for integrating a system’s compo‐ nents. The chapter began by exploring patterns for model translations that can be used to implement anticorruption layers or open-host services. We saw that transla‐ tions can be handled on the fly or can follow a more complex logic, requiring state tracking. The o

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which integration pattern should never be used for a core subdomain? a. Shared kernel b. Open-host service c. Anticorruption layer d. Separate ways 2. Which downstream subdomain is more likely to implement an anticorruption layer? a. Core subdomain b. Supporting subdomain c. Generic subdomain d. B and C 3. Which upstream subdomain is more likely

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

In this chapter, we covered two patterns for implementing business logic: Transaction script This pattern organizes the system’s operations as simple, straightforward proce‐ dural scripts. The procedures ensure that each operation is transactional—either it succeeds or it fails. The transaction script pattern lends itself to supporting subdomains, w

1 min

Implementation

Published May 5th, 2025 by Oleksandr Sydorenko

In Part III , we discussed how to turn theory into practice. You learned how to effec‐ tively build a ubiquitous language by facilitating an EventStorming session, how to keep the design in shape as the business domain evolves, and how to introduce and start using domain-driven design in brownfield projects. In Part IV , we discussed the interplay b

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

In this chapter, you learned the different aspects of designing software systems, in particular, defining and managing analytical data. We discussed the predominant models for analytical data, including the star and snowflake schemas, and how the data is traditionally managed in data warehouses and data lakes. The data mesh architecture aims to addr

1 min

EventStorming

Published May 5th, 2025 by Oleksandr Sydorenko

• Brandolini, A. (Not yet published). Introducing EventStorming . Leanpub. Alberto Brandolini is the creator of the EventStorming workshop, and in this book, he explains in detail the process and rationale behind EventStorming. • Rayner, P. (Not yet published). The EventStorming Handbook . Leanpub. Paul Rayner explains how he uses EventStorming in p

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. What is the difference between subdomains and bounded contexts? a. Subdomains are designed, while bounded contexts are discovered. b. Bounded contexts are designed, while subdomains are discovered. c. Bounded contexts and subdomains are essentially the same. d. None of the above is true. 2. A bounded context is a boundary of: a. A model b. A life

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which of the following statements is/are correct regarding the differences between transactional (OLTP) and analytical (OLAP) models? a. OLAP models should expose more flexible querying options than OLTP models. b. OLAP models are expected to undergo more updates than OLTP models, and thus have to be optimized for writes. c. OLTP data is optimize

1 min

Implementation

Published May 5th, 2025 by Oleksandr Sydorenko

Consequently, this pattern uses dedicated objects, known as active records, to repre‐ sent complicated data structures. Apart from the data structure, these objects also implement data access methods for creating, reading, updating, and deleting records—the so-called CRUD operations. As a result, the active record objects are coupled to an object-re

1 min

Open-Host Service

Published May 5th, 2025 by Oleksandr Sydorenko

The open-host service decouples the bounded context’s model of the business domain from the model used for integration with other components of the system, as shown in Figure 14-12 . Introducing the integration-oriented model, the published language, reduces the sys‐ tem’s global complexity. First, it allows us to evolve the service’s implementation

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

The domain model pattern is aimed at cases of complex business logic. It consists of three main building blocks: Value objects Concepts of the business domain that can be identified exclusively by their values and thus do not require an explicit ID field. Since a change in one of the fields semantically creates a new value, value objects are immutab

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

The layered architecture decomposes the codebase based on its technological con‐ cerns. Since this pattern couples business logic with data access implementation, it’s a good fit for active record–based systems. The ports & adapters architecture inverts the relationships: it puts the business logic at the center and decouples it from all infrast

1 min

Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

The microservices and bounded context patterns have a lot in common, so much so that the patterns are often used interchangeably. Let’s see whether that’s really the case: do bounded contexts’ boundaries correlate with the boundaries of effective microservices? Both microservices and bounded contexts are physical boundaries. Microservices, as bounde

1 min

Architectural Patterns

Published May 5th, 2025 by Oleksandr Sydorenko

In Chapter 8 , you learned about the three architectural patterns: layered architecture, ports & adapters, and CQRS. Knowing the intended business logic implementation pattern makes choosing an architectural pattern straightforward: • The event-sourced domain model requires CQRS. Otherwise, the system will be extremely limited in its data queryi

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. What is the relationship between bounded contexts and microservices? a. All microservices are bounded contexts. b. All bounded contexts are microservices. c. Microservices and bounded contexts are different terms for the same concept. d. Microservices and bounded contexts are completely different concepts and cannot be compared. 2. What part of a

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Assume you are implementing WolfDesk’s (see Preface ) ticket lifecycle manage‐ ment system. It’s a core subdomain that requires deep analysis of its behavior so that the algorithm can be further optimized over time. What would be your ini‐ tial strategy implementing the business logic and the component’s architecture? What would be your testing s

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Which of the following statements is/are correct? a. Event-driven architecture defines the events intended to travel across compo‐ nents’ boundaries. b. Event sourcing defines the events that are intended to stay within the bounded context’s boundary. c. Event-driven architecture and event sourcing are different terms for the same pattern. d. A a

1 min

Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

As you’ll recall from Chapter 3 , both wide and narrow boundaries could fit the defi‐ nition of a valid bounded context encompassing a consistent ubiquitous language. But still, what is the optimal size of a bounded context? This question is especially important in light of the frequent equation of bounded contexts with microservices. 2 Should we al

1 min

Implementation

Published May 5th, 2025 by Oleksandr Sydorenko

As the name suggests, the pattern segregates the responsibilities of the system’s mod‐ els. There are two types of models: the command execution model and the read models. Command execution model CQRS devotes a single model to executing operations that modify the system’s state (system commands). This model is used to implement the business logic, v

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

EventStorming is a collaboration-based workshop for modeling business processes. Apart from the resultant models, its primary benefit is knowledge sharing. By the end of the session, all the participants will synchronize their mental models of the busi‐ ness process and take the first steps toward using a ubiquitous language. EventStorming is like r

1 min

Subdomains

Published May 5th, 2025 by Oleksandr Sydorenko

A more balanced heuristic for designing microservices is to align the services with the boundaries of business subdomains. As you learned in Chapter 1 , subdomains are correlated with fine-grained business capabilities. These are the business building blocks required for the company to compete in its business domain(s). From a busi‐ ness domain pers

1 min

Variants

Published May 5th, 2025 by Oleksandr Sydorenko

Alberto Brandolini, the creator of the EventStorming workshop, defines the Event‐ Storming process as guidance, not hard rules. You are free to experiment with the pro‐ cess to find the “recipe” that works best for you. In my experience, when introducing EventStorming in an organization I prefer to start by exploring the big picture of the business

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

That’s it! Thank you so much for reading this book. I hope you enjoyed it and that you will use what you’ve learned from it. What I hope you take away from this book are the logic and the principles behind domain-driven design tools. Don’t follow domain-driven design blindly as a dogma, but rather understand the reasoning it is based on. This unders

1 min

Aggregates

Published May 5th, 2025 by Oleksandr Sydorenko

While bounded contexts impose limits on the widest valid boundaries, the aggregate pattern does the opposite. The aggregate’s boundary is the narrowest boundary possi‐ ble. Decomposing an aggregate into multiple physical services, or bounded contexts, is not only suboptimal but, as you will learn in Appendix A , leads to undesired conse‐ quences, to

1 min

Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

In Chapter 3 , you learned that the bounded context pattern allows us to use different models of the business domain. Instead of building a “jack of all trades, master of none” model, we can build multiple models, each focused on solving a specific problem. As a project evolves and grows, it’s not uncommon for the bounded contexts to lose their focu

1 min

Subdomains

Published May 5th, 2025 by Oleksandr Sydorenko

As we discussed in Chapter 1 , the subdomains’ boundaries can be challenging to identify, and as a result, instead of striving for boundaries that are perfect, we must strive for boundaries that are useful. That is, the subdomains should allow us to 1 Brian Foote and Joseph Yoder. Big Ball of Mud. Fourth Conference on Patterns Languages of Programs

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

In the stories of Marketnovus’s bounded contexts I showed how our understanding of domain-driven design evolved through time (refer to Figure A-6 for a refresher): • We always started by building a ubiquitous language with the domain experts to learn as much as possible about the business domain. • In the case of conflicting models, we decomposed th

1 min

Event-Driven Architecture

Published May 5th, 2025 by Oleksandr Sydorenko

Stated simply, event-driven architecture is an architectural style in which a system’s components communicate with one another asynchronously by exchanging event messages (see Figure 15-1 ). Instead of calling the services’ endpoints synchronously, the components publish events to notify other system elements of changes in the sys‐ tem’s domain. The

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

As Heraclitus famously said, the only constant in life is change. Businesses are no exception. To stay competitive, companies constantly strive to evolve and reinvent themselves. Those changes should be treated as first-class elements of the design process. As the business domain evolves, changes to its subdomains must be identified and acted on in

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

In this chapter, you learned various techniques for leveraging domain-driven design tools in real-life scenarios: when working on brownfield projects and legacy codeba‐ ses, and not necessarily with a team of DDD experts. As in greenfield projects, always start by analyzing the business domain. What are the company’s goals and its strategy for achie

1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

This chapter presented event-driven architecture as an inherent aspect of designing a bounded context’s public interface. You learned the three types of events that can be used for cross-bounded context communication: Event notification A notification that something important has happened, but requiring the con‐ sumer to query the producer for addit

1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Assume you want to introduce domain-driven design tools and practices to a brownfield project. What is going to be your first step? a. Refactor all business logic to the event-sourced domain model. b. Analyze the organization’s business domain and its strategy. c. Improve the system’s components by ensuring that they follow the principles of prop

1 min

Anticorruption Layer

Published May 5th, 2025 by Oleksandr Sydorenko

The anticorruption layer (ACL) pattern works the other way around. It reduces the complexity of integrating the service with other bounded contexts. Traditionally, the anticorruption layer belongs to the bounded context it protects. However, as we dis‐ cussed in Chapter 9 , this notion can be taken a step further and implemented as a standalone serv

1 min

Domain-Driven Design and Microservices’ Boundaries

Published May 5th, 2025 by Oleksandr Sydorenko

As microservices, many of the domain-driven design patterns discussed in the previ‐ ous chapters are about boundaries: the bounded context is the boundary of a model, a subdomain bounds a business capability, while aggregate and value objects are trans‐ actional boundaries. Let’s see which of these boundaries lends itself to the notion of microservi

12 Views 1 min

Integration of Infrastructural Components

Published May 5th, 2025 by Oleksandr Sydorenko

The core goal of the ports & adapters architecture is to decouple the system’s business logic from its infrastructural components. Instead of referencing and calling the infrastructural components directly, the busi‐ ness logic layer defines “ports” that have to be implemented by the infrastructure layer. The infrastructure layer implements “ada

12 Views 1 min

Model Segregation

Published May 5th, 2025 by Oleksandr Sydorenko

In the CQRS architecture, the responsibilities of the system’s models are segregated according to their type. A command can only operate on the strongly consistent com‐ mand execution model. A query cannot directly modify any of the system’s persisted state—neither the read models nor the command execution model. A common misconception about CQRS-ba

12 Views 1 min

Performance

Published May 5th, 2025 by Oleksandr Sydorenko

Reconstituting an aggregate’s state from events will negatively affect the system’s perfor‐ mance. It will degrade as events are added. How can this even work? Projecting events into a state representation indeed requires compute power, and that need will grow as more events are added to an aggregate’s list. It’s important to benchmark a projection’

13 Views 1 min

Business Logic Layer

Published May 5th, 2025 by Oleksandr Sydorenko

As the name suggests, this layer is responsible for implementing and encapsulating the program’s business logic. This is the place where business decisions are imple‐ mented. As Eric Evans says, 1 this layer is the heart of software. This layer is where the business logic patterns described in Chapters 5 – 7 are imple‐ mented—for example, active rec

15 Views 1 min

Stateless Model Translation

Published May 5th, 2025 by Oleksandr Sydorenko

For stateless model translation, the bounded context that owns the translation (OHS for upstream, ACL for downstream) implements the proxy design pattern to interject the incoming and outgoing requests and map the source model to the bounded con‐ text’s target model. This is depicted in Figure 9-1 . Figure 9-1. Model translation by a proxy Implement

12 Views 1 min

Data Access Layer

Published May 5th, 2025 by Oleksandr Sydorenko

The data access layer provides access to persistence mechanisms. In the pattern’s orig‐ inal form, this referred to the system’s database. However, as in the case of the presen‐ tation layer, the layer’s responsibility is broader for modern systems. First, ever since the NoSQL revolution broke out, it is common for a system to work with multiple dat

16 Views 1 min

Spk Glossary

Published May 5th, 2025 by Oleksandr Sydorenko

This is a auto-generated Article of all your definitions within the glossary. Glossary This is a auto-generated Article of all your definitions within the glossary. All

1 min

Buying a Refrigerator

Published May 5th, 2025 by Oleksandr Sydorenko

Finally, let’s see a more earthbound example of real-life bounded contexts. What do you see in Figure 3-9 ? Figure 3-9. A piece of cardboard Is it just a piece of cardboard? No, it’s a model. It’s a model of the Siemens KG86NAI31L refrigerator. If you look it up, you may say the piece of cardboard doesn’t look anything like that fridge. It has no do

1 min

Boundaries

Published May 5th, 2025 by Oleksandr Sydorenko

As Ruth Malan says, architectural design is inherently about boundaries: Architectural design is system design. System design is contextual design—it is inher‐ ently about boundaries (what’s in, what’s out, what spans, what moves between), and about trade-offs. It reshapes what is outside, just as it shapes what is inside. 2 The bounded context patt

12 Views 1 min

Analytical Data Model Versus Transactional Data Model

Published May 5th, 2025 by Oleksandr Sydorenko

They say knowledge is power. Analytical data is the knowledge that gives companies the power to leverage accumulated data to gain insights into how to optimize the business, better understand customers’ needs, and even make automated decisions by training machine learning (ML) models. The analytical models (OLAP) and operational models (OLTP) serve

14 Views 1 min

References

Published May 5th, 2025 by Oleksandr Sydorenko

Brandolini, A. (n.d.). Introducing EventStorming . Leanpub. Brooks, F. P., Jr. (1974). The Mythical Man Month and Other Essays on Software Engi‐ neering . Reading, MA: Addison-Wesley. Eisenhardt, K., & Sull, D. (2016). Simple Rules: How to Succeed in a Complex World . London: John Murray. Esposito, D., & Saltarello, A. (2008). Architecting A

1 min

What Is a Microservice?

Published May 5th, 2025 by Oleksandr Sydorenko

The definition of a microservice is surprisingly simple. Since a service is defined by its public interface, a microservice is a service with a micro-public interface: a micro- front door. Having a micro-public interface makes it easier to understand both the function of a single service and its integration with other system components. Reducing a s

13 Views 1 min

Conclusion

Published May 5th, 2025 by Oleksandr Sydorenko

Effective communication and knowledge sharing are crucial for a successful software project. Software engineers have to understand the business domain in order to design and build a software solution. Domain-driven design’s ubiquitous language is an effective tool for bridging the knowledge gap between domain experts and software engineers. It foste

1 min

There’s much more where this came from.

Published May 5th, 2025 by Oleksandr Sydorenko

Experience books, videos, live online training courses, and more from O’Reilly and our 200+ partners—all in one place. Learn more at oreilly.com/online-learning

1 min

Subdomains

Published May 5th, 2025 by Oleksandr Sydorenko

To comprehend a company’s business strategy, we have to analyze its business domain. According to domain-driven design methodology, the analysis phase involves identifying the different subdomains (core, supporting, and generic). That’s how the organization works and plans its competitive strategy. As you learned in Chapter 1 , a subdomain resembles

10 Views 1 min

Integrating Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

Not only does the bounded context pattern protect the consistency of a ubiquitous language, it also enables modeling. You cannot build a model without specifying its purpose—its boundary. The boundary divides the responsibility of languages. A lan‐ guage in one bounded context can model the business domain to solve a particular problem. Another boun

12 Views 1 min

Step 3: Pain Points

Published May 5th, 2025 by Oleksandr Sydorenko

Once you have the events organized in a timeline, use this broad view to identify points in the process that require attention. These can be bottlenecks, manual steps that require automation, missing documentation, or missing domain knowledge. It’s important to make these inefficiencies explicit so that it will be easy to return to them as the Event

11 Views 1 min

Scope of a Bounded Context

Published May 5th, 2025 by Oleksandr Sydorenko

The example at the beginning of the chapter demonstrated an inherent boundary of the business domain. Different domain experts held conflicting mental models of the same business entity. To model the business domain, we had to divide the model and define a strict applicability context for each fine-grained model—its bounded context. The consistency

26 Views 1 min

Bounded Context #4: Bonuses

Published May 5th, 2025 by Oleksandr Sydorenko

One day, the sales desk managers asked us to automate a simple yet tedious procedure they had been doing manually: calculate the commissions for the sales agents. Again, it started out simple: once a month, just calculate a percentage of each agent’s sales and send the report to the managers. As before, we contemplated whether this was a core subdom

1 min

Bounded Context #3: Event Crunchers

Published May 5th, 2025 by Oleksandr Sydorenko

After the CRM system was rolled out, we suspected that an implicit subdomain was spread across marketing and CRM. Whenever the process of handling incoming cus‐ tomer events had to be modified, we had to introduce changes both in the marketing and CRM bounded contexts. Since conceptually this process didn’t belong to any of them, we decided to extra

1 min

Answers to Exercise Questions

Published May 5th, 2025 by Oleksandr Sydorenko

Chapter 1 1. D: B and C. Only core subdomains provide competitive advantages that differen‐ tiate the company from other players in its industry. 2. B: Generic. Generic subdomains are complex but do not entail any competitive advantage. Hence, it’s preferable to use an existing, battle-proven solution. 3. A: Core. Core subdomains are expected to be

6 min

Challenges

Published May 5th, 2025 by Oleksandr Sydorenko

In theory, cultivating a ubiquitous language sounds like a simple, straightforward process. In practice, it isn’t. The only reliable way to gather domain knowledge is to converse with domain experts. Quite often, the most important knowledge is tacit. It’s not documented or codified but resides only in the minds of domain experts. The only way to ac

13 Views 1 min

Bounded Context #1: Marketing

Published May 5th, 2025 by Oleksandr Sydorenko

The architectural style of our first solution could be neatly summarized as “aggregates everywhere.” Agency, campaign, placement, funnel, publisher: each and every noun in the requirements was proclaimed as an aggregate. All of those so-called aggregates resided in a huge, lone, bounded context. Yes, a big, scary monolith, the kind everyone warns yo

1 min

Implementing Simple Business Logic

Published May 5th, 2025 by Oleksandr Sydorenko

Business logic is the most important part of software. It’s the reason the software is being implemented in the first place. A system’s user interface can be sexy and its database can be blazing fast and scalable. But if the software is not useful for the busi‐ ness, it’s nothing but an expensive technology demo. As we saw in Chapter 2 , not all bus

12 Views 1 min

Boundaries of Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

At Marketnovus, we tried quite a few strategies for setting the boundaries of bounded contexts: • Linguistic boundaries: We split our initial monolith into marketing and CRM contexts to protect their ubiquitous languages. • Subdomain-based boundaries: Many of our subdomains were implemented in their own bounded contexts; for example, event crunchers

1 min

Bounded Context #2: CRM

Published May 5th, 2025 by Oleksandr Sydorenko

Soon after we deployed the campaign management solution, leads started flowing in, and we were in a rush. Our sales agents needed a robust customer relationship man‐ agement (CRM) system to manage the leads and their lifecycles. The CRM had to aggregate all incoming leads, group them based on different param‐ eters, and distribute them across multip

3 min

Tackling Complex Business Logic

Published May 5th, 2025 by Oleksandr Sydorenko

The previous chapter discussed two patterns addressing cases of relatively simple business logic: transaction script and active record. This chapter continues the topic of implementing business logic and introduces a pattern oriented for complicated business logic: the domain model pattern.

13 Views 1 min

Tactical Modernization

Published May 5th, 2025 by Oleksandr Sydorenko

First and foremost, from a tactical standpoint, look for the most “painful” mis‐ matches in business value and implementation strategies, such as core subdomains implementing patterns that don’t match the complexity of the model—transaction script or active record. These system components that directly impact the success of the business have to chan

10 Views 1 min

System Complexity

Published May 5th, 2025 by Oleksandr Sydorenko

Forty years ago, there was no cloud computing, there were no global-scale require‐ ments, and there was no need to deploy a system every 11.7 seconds. But engineers still had to tame systems’ complexity. Even though the tools in those days were differ‐ ent, the challenges—and more importantly, the solution—are relevant nowadays and can be applied to

12 Views 1 min

Domain Knowledge

Published May 5th, 2025 by Oleksandr Sydorenko

As you’ll recall, the core tenet of domain-driven design is that domain knowledge is essential for designing a successful software system. Acquiring domain knowledge is one of the most challenging aspects of software engineering, especially for the core subdomains. A core subdomain’s logic is not only complicated, but also expected to change often.

1 min

Stateful Model Translation

Published May 5th, 2025 by Oleksandr Sydorenko

For more significant model transformations—for example, when the translation mechanism has to aggregate the source data or unify data from multiple sources into a single model—a stateful translation may be required. Let’s discuss each of these use cases in detail. Aggregating incoming data Let’s say a bounded context is interested in aggregating inc

13 Views 1 min

Search

Published May 5th, 2025 by Oleksandr Sydorenko

You have to implement a search. However, since a lead’s contact information can be updated—first name, last name, and phone number—sales agents may not be aware of the changes applied by other agents and may want to locate leads using their con‐ tact information, including historical values. We can easily project the historical information: public c

1 min

Tactical Design Concerns

Published May 5th, 2025 by Oleksandr Sydorenko

The main indicator of a change in a subdomain’s type is the inability of the existing technical design to support current business needs. Let’s go back to the example of a supporting subdomain becoming a core subdomain. Supporting subdomains are implemented with relatively simple design patterns for modeling the business logic: namely, the transacti

11 Views 1 min

Inconsistent Models

Published May 5th, 2025 by Oleksandr Sydorenko

Let’s go back to the example of a telemarketing company from Chapter 2 . The compa‐ ny’s marketing department generates leads through online advertisements. Its sales department is in charge of soliciting prospective customers to buy its products or services, a chain that is shown in Figure 3-1 . Figure 3-1. Example business domain: telemarketing co

2 min

Index

Published May 5th, 2025 by Oleksandr Sydorenko

A accidental complexity case study of applying DDD, 283 growth and, 180 , 181 , 182 active records, 69 - 71 design evolving active record to domain model, 174 transaction script to active record, 174 design heuristics, 161 , 163 Fowler naming, 71 implementation, 70 layered architecture, 124 when to use, 71 aggregates, 84 - 92 about, 88 boundaries, 2

15 min

Modernization of Legacy Systems

Published May 5th, 2025 by Oleksandr Sydorenko

• Kaiser, S. (Expected to be published in 2022). Adaptive Systems with Domain- Driven Design, Wardley Mapping, and Team Topologies . Boston: Addison-Wesley. Susanne Kaiser shares her experience of modernizing legacy systems by leverag‐ ing domain-driven design, Wardley mapping, and team topologies. • Tune, N. (Expected to be published in 2022). Arch

1 min

Building Blocks

Published May 5th, 2025 by Oleksandr Sydorenko

Let’s look at the central domain model building blocks, or tactical patterns, offered by DDD: value objects, aggregates, and domain services. Value object A value object is an object that can be identified by the composition of its values. For example, consider a color object: class Color { int _red ; int _green ; 1 Fowler, M. (2002). Patterns of En

12 Views 15 min

What Is a Service?

Published May 5th, 2025 by Oleksandr Sydorenko

According to OASIS, a service is a mechanism that enables access to one or more capabilities, where the access is provided using a prescribed interface. 1 The prescribed interface is any mechanism for getting data in or out of a service. It can be synchro‐ nous, such as a request/response model, or asynchronous, such as a model that is 1 Reference m

10 Views 1 min

Conformist

Published May 5th, 2025 by Oleksandr Sydorenko

In some cases, the balance of power favors the upstream team, which has no real motivation to support its clients’ needs. Instead, it just provides the integration con‐ tract, defined according to its own model—take it or leave it. Such power imbalances can be caused by integration with service providers that are external to the organiza‐ tion or si

11 Views 1 min

About the Author

Published May 5th, 2025 by Oleksandr Sydorenko

Vlad (Vladik) Khononov is a software engineer with over 20 years of industry expe‐ rience, during which he has worked for companies large and small in roles ranging from webmaster to chief architect. Vlad maintains an active media career as a public speaker, blogger, and author. He travels the world consulting and talking about domain-driven design,

1 min

Strategic Analysis

Published May 5th, 2025 by Oleksandr Sydorenko

Following the order of our exploration of domain-driven design patterns and practi‐ ces, the best starting point for introducing DDD in an organization is to invest time in understanding the organization’s business strategy and the current state of its sys‐ tems’ architecture.

11 Views 1 min

Events, Commands, and Messages

Published May 5th, 2025 by Oleksandr Sydorenko

So far, the definition of an event is similar to the definition of the message pattern. 1 However, the two are different. An event is a message, but a message is not necessar‐ ily an event. There are two types of messages: 1 Hohpe, G., & Woolf, B. (2003). Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions . B

13 Views 1 min

Bounded Context #5: The Marketing Hub

Published May 5th, 2025 by Oleksandr Sydorenko

Our management was looking for a profitable new vertical. They decided to try using our ability to generate a massive number of leads and sell them to smaller clients, ones we hadn’t worked with before. This project was called “marketing hub.” Since management had defined this business domain as a new profit opportunity, it was clearly a core busine

1 min

Step 2: Timelines

Published May 5th, 2025 by Oleksandr Sydorenko

Next, the participants go over the generated domain events and organize them in the order in which they occur in the business domain. The events should start with the “happy path scenario”: the flow that describes a suc‐ cessful business scenario. Once the “happy path” is done, alternative scenarios can be added—for example, paths where errors are e

10 Views 1 min

Saga

Published May 5th, 2025 by Oleksandr Sydorenko

One of the core aggregate design principles is to limit each transaction to a single instance of an aggregate. This ensures that an aggregate’s boundaries are carefully considered and encapsulate a coherent set of business functionality. But there are cases when you have to implement a business process that spans multiple aggregates. Consider the fo

11 Views 2 min

Applying DDD: A Case Study

Published May 5th, 2025 by Oleksandr Sydorenko

In this appendix, I will share how my domain-driven design journey started: the story of a start-up company that, for the purposes of this example, we’ll refer to as “Market‐ novus.” At Marketnovus, we had been employing DDD methodology since the day the company was founded. Over the years, not only had we committed every possible DDD mistake, but w

1 min

Continuous Effort

Published May 5th, 2025 by Oleksandr Sydorenko

Formulation of a ubiquitous language requires interaction with its natural holders, the domain experts. Only interactions with actual domain experts can uncover inac‐ curacies, wrong assumptions, or an overall flawed understanding of the business domain. All stakeholders should consistently use the ubiquitous language in all project-related communic

12 Views 1 min

Testing Strategy

Published May 5th, 2025 by Oleksandr Sydorenko

The knowledge of both the business logic implementation pattern and the architec‐ tural pattern can be used as a heuristic for choosing a testing strategy for the code‐ base. Take a look at the three testing strategies shown in Figure 10-5 . Figure 10-5. Testing strategies The difference between the testing strategies in the figure is their emphasis

10 Views 1 min

Polyglot Modeling

Published May 5th, 2025 by Oleksandr Sydorenko

In many cases, it may be difficult, if not impossible, to use a single model of the sys‐ tem’s business domain to address all of the system’s needs. For example, as discussed in Chapter 7 , online transaction processing (OLTP) and online analytical processing (OLAP) may require different representations of the system’s data. Another reason for worki

1 min

Tactical Design

Published May 5th, 2025 by Oleksandr Sydorenko

In Part I , we discussed the “what” and “why” of software: you learned to analyze busi‐ ness domains, identify subdomains and their strategic value, and turn the knowledge of business domains into the design of bounded contexts—software components implementing different models of the business domain. In this part of the book, we will turn from strat

11 Views 1 min

Managing Domain Complexity

Published May 5th, 2025 by Oleksandr Sydorenko

As you saw in the previous chapter, to ensure a project’s success it’s crucial that you develop a ubiquitous language that can be used for communication by all stakehold‐ ers, from software engineers to domain experts. The language should reflect the domain experts’ mental models of the business domain’s inner workings and underly‐ ing principles. S

12 Views 1 min

Variants

Published May 5th, 2025 by Oleksandr Sydorenko

The ports & adapters architecture is also known as hexagonal architecture, onion architecture, and clean architecture. All of these patterns are based on the same design principles, have the same components, and have the same relationships between them, but as in the case of the layered architecture, the terminology may differ: • Application lay

10 Views 1 min

Ubiquitous Language

Published May 5th, 2025 by Oleksandr Sydorenko

In my experience, ubiquitous language is the “core subdomain” of domain-driven design. The ability to speak the same language with our domain experts has been indispensable to us. It turned out to be a much more effective way to share knowledge than tests or documents. Moreover, the presence of a ubiquitous language has been a major predictor of a p

1 min

The Interplay Between Subdomains and Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

Theoretically, though impractically, a single model could span the entire business domain. This strategy could work for a small system, as shown in Figure 3-5 . Figure 3-5. Monolithic bounded context When conflicting models arise, we can follow the domain experts’ mental models and decompose the systems into bounded contexts, as shown in Figure 3-6

12 Views 1 min

Business Domain

Published May 5th, 2025 by Oleksandr Sydorenko

Imagine you are producing a product or a service. Marketnovus allowed you to out‐ source all of your marketing-related chores. Marketnovus’s experts would come up with a marketing strategy for your product. Its copywriters and graphic designers would produce tons of creative material, such as banners and landing pages, that would be used to run adve

1 min

Step 5: Commands

Published May 5th, 2025 by Oleksandr Sydorenko

Whereas a domain event describes something that has already happened, a command describes what triggered the event or flow of events. Commands describe the system’s operations and, contrary to domain events, are formulated in the imperative. For example: • Publish campaign • Roll back transaction • Submit order Commands are written on light blue sti

12 Views 1 min

Open-Host Service

Published May 5th, 2025 by Oleksandr Sydorenko

This pattern addresses cases in which the power is skewed toward the consumers. The supplier is interested in protecting its consumers and providing the best service possible. To protect the consumers from changes in its implementation model, the upstream supplier decouples the implementation model from the public interface. This decou‐ pling allows

11 Views 1 min

Domain Model to Event-Sourced Domain Model

Published May 5th, 2025 by Oleksandr Sydorenko

Once you have a domain model with properly designed aggregate boundaries, you can transition it to the event-sourced model. Instead of modifying the aggregate’s data directly, model the domain events needed to represent the aggregate’s lifecycle. The most challenging aspect of refactoring a domain model into an event-sourced domain model is the hist

12 Views 1 min

Discovering Domain Knowledge

Published May 5th, 2025 by Oleksandr Sydorenko

It’s developers’ (mis)understanding, not domain experts’ knowledge, that gets released in production. —Alberto Brandolini In the previous chapter, we started exploring business domains. You learned how to identify a company’s business domains, or areas of activity, and analyze its strategy to compete in them; that is, its business subdomains’ bounda

11 Views 1 min

Bounded Contexts Versus Subdomains

Published May 5th, 2025 by Oleksandr Sydorenko

In Chapter 2 , we saw that a business domain consists of multiple subdomains. So far in this chapter, we explored the notion of decomposing a business domain into a set of fine-grained problem domains or bounded contexts. At first, the two methods of decomposing business domains might seem redundant. However, that’s not the case. Let’s examine why w

12 Views 1 min

Event-Sourced Domain Model

Published May 5th, 2025 by Oleksandr Sydorenko

The original domain model maintains a state representation of its aggregates and emits select domain events. The event-sourced domain model uses domain events exclusively for modeling the aggregates’ lifecycles. All changes to an aggregate’s state have to be expressed as domain events. Each operation on an event-sourced aggregate follows this script

12 Views 1 min

Compressing Microservices’ Public Interfaces

Published May 5th, 2025 by Oleksandr Sydorenko

In addition to finding service boundaries, domain-driven design can help make serv‐ ices deeper. This section demonstrates how the open-host service and anticorruption layer patterns can simplify the microservices’ public interfaces.

12 Views 1 min

Shared Kernel

Published May 5th, 2025 by Oleksandr Sydorenko

Despite bounded contexts being model boundaries, there still can be cases when the same model of a subdomain, or a part of it, will be implemented in multiple bounded contexts. It’s crucial to stress that the shared model is designed according to the needs of all of the bounded contexts. Moreover, the shared model has to be consistent across all of

11 Views 2 min

Refactoring the Event-Driven Integration

Published May 5th, 2025 by Oleksandr Sydorenko

As you can see, blindly pouring events on a system makes it neither decoupled nor resilient. You may assume that this is an unrealistic example, but unfortunately, this example is based on a true story. Let’s see how the events can be adjusted to improve the design dramatically. Exposing all the domain events constituting the CRM’s data model couple

12 Views 1 min

Supporting to Generic

Published May 5th, 2025 by Oleksandr Sydorenko

BuyIT’s marketing department implements a system for managing the vendors it works with and their contracts. There is nothing special or complex about the system—it’s just some CRUD user interfaces for entering data. In other words, it is a typical supporting subdomain. However, a few years after BuyIT began implementing the in-house solution, an op

12 Views 1 min

Data Lake

Published May 5th, 2025 by Oleksandr Sydorenko

As a data warehouse, the data lake architecture is based on the same notion of ingest‐ ing the operational systems’ data and transforming it into an analytical model. How‐ ever, there is a conceptual difference between the two approaches. A data lake–based system ingests the operational systems’ data. However, instead of being transformed right away

12 Views 1 min

Strategic Design Concerns

Published May 5th, 2025 by Oleksandr Sydorenko

A change in a subdomain’s type directly affects its bounded context and, conse‐ quently, corresponding strategic design decisions. As you learned in Chapter 4 , differ‐ ent bounded context integration patterns accommodate the different subdomain types. The core subdomains have to protect their models by using anticorruption lay‐ ers and have to prot

10 Views 1 min

Data as a Product

Published May 5th, 2025 by Oleksandr Sydorenko

The classic data management architectures make it difficult to discover, understand, and fetch quality analytical data. This is especially acute in the case of data lakes. The data as a product principle calls for treating the analytical data as a first-class citi‐ zen. Instead of the analytical systems having to get the operational data from dubiou

10 Views 1 min

What Is a Model?

Published May 5th, 2025 by Oleksandr Sydorenko

A model is a simplified representation of a thing or phenomenon that intentionally emphasi‐ zes certain aspects while ignoring others. Abstraction with a specific use in mind. —Rebecca Wirfs-Brock A model is not a copy of the real world but a human construct that helps us make sense of real-world systems. A canonical example of a model is a map. Any

12 Views 1 min

Problem

Published May 5th, 2025 by Oleksandr Sydorenko

To provide a software solution, we first have to understand the problem: what is the business domain that we are working in, what are the business goals, and what is the strategy for achieving them. We used the ubiquitous language to gain a deep understanding of the business domain and its logic that we have to implement in software. You learned to

14 Views 1 min

When to Use Ports & Adapters

Published May 5th, 2025 by Oleksandr Sydorenko

The decoupling of the business logic from all technological concerns makes the ports & adapters architecture a perfect fit for business logic implemented with the domain model pattern.

12 Views 1 min

Event-Driven Architecture

Published May 5th, 2025 by Oleksandr Sydorenko

As microservices, event-driven architecture (EDA) is ubiquitous in modern dis‐ tributed systems. Many advise using event-driven communication as the default inte‐ gration mechanism when designing loosely coupled, scalable, fault-tolerant distributed systems. Event-driven architecture is often linked to domain-driven design. After all, EDA is based o

14 Views 1 min

Transaction Script

Published May 5th, 2025 by Oleksandr Sydorenko

Organizes business logic by procedures where each procedure handles a single request from the presentation. —Martin Fowler 1 A system’s public interface can be seen as a collection of business transactions that consumers can execute, as shown in Figure 5-1 . These transactions can retrieve infor‐ mation managed by the system, modify it, or both. The

14 Views 1 min

Event Store

Published May 5th, 2025 by Oleksandr Sydorenko

The event store should not allow modifying or deleting the events 2 since it’s append- only storage. To support implementation of the event sourcing pattern, at a minimum the event store has to support the following functionality: fetch all events belonging to a specific business entity and append the events. For example: interface IEventStore { IEn

14 Views 1 min

Five Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

Before we delve into the bounded contexts and how they were designed, as well- behaved DDD practitioners we have to start by defining Marketnovus’s business domain.

1 min

Temporal Coupling

Published May 5th, 2025 by Oleksandr Sydorenko

The AdsOptimization and Reporting bounded contexts are temporally coupled: they depend on a strict order of execution. The AdsOptimization component has to finish its processing before the Reporting module is triggered. If the order is reversed, inconsistent data will be produced in the Reporting system. To enforce the required execution order, the

12 Views 1 min

Watch the Dynamics

Published May 5th, 2025 by Oleksandr Sydorenko

As the workshop progresses, it’s important to track the energy of the group. If the dynamics are slowing down, see whether you can reignite the process by asking ques‐ tions or whether it’s time to advance to the next stage of the workshop. Remember that EventStorming is a group activity, so ensure that it is handled as such. Make sure everyone has

10 Views 1 min

Advanced Domain-Driven Design

Published May 5th, 2025 by Oleksandr Sydorenko

• Evans, E. (2003). Domain-Driven Design: Tackling Complexity in the Heart of Soft‐ ware . Boston: Addison-Wesley. Eric Evans’s original book that introduced the domain-driven design methodol‐ ogy. Although it doesn’t reflect newer aspects of DDD such as domain events and event sourcing, it’s still essential reading for becoming a DDD black belt. •

11 Views 1 min

The EventStorming Process

Published May 5th, 2025 by Oleksandr Sydorenko

An EventStorming workshop is usually conducted in 10 steps. During each step, the model is enriched with additional information and concepts.

12 Views 1 min

Ports & Adapters

Published May 5th, 2025 by Oleksandr Sydorenko

The ports & adapters architecture addresses the shortcomings of the layered architec‐ ture and is a better fit for implementation of more complex business logic. Interest‐ ingly, both patterns are quite similar. Let’s “refactor” the layered architecture into ports & adapters.

1 min

Discussion

Published May 5th, 2025 by Oleksandr Sydorenko

Those were the five bounded contexts I wanted to tell you about: marketing, CRM, event crunchers, bonuses, and marketing hub. Of course, such a wide business domain as Marketnovus entailed many more bounded contexts, but I wanted to share the bounded contexts we learned from the most. Now that we’ve walked through the five bounded contexts, let’s lo

1 min

Frequently Asked Questions

Published May 5th, 2025 by Oleksandr Sydorenko

When engineers are introduced to the event sourcing pattern, they often ask several common questions, so I find it obligatory to address them in this chapter.

1 min

Step 6: Policies

Published May 5th, 2025 by Oleksandr Sydorenko

Almost always, some commands are added to the model but have no specific actor associated with them. During this step, you look for automation policies that might execute those commands. An automation policy is a scenario in which an event triggers the execution of a com‐ mand. In other words, a command is automatically executed when a specific doma

1 min

Reversed Testing Pyramid

Published May 5th, 2025 by Oleksandr Sydorenko

The reversed testing pyramid attributes the most attention to end-to-end tests: verify‐ ing the application’s workflow from beginning to end. Such an approach best fits codebases implementing the transaction script pattern: the business logic is simple and the number of layers is minimal, making it more effective to verify the end-to- end flow of th

12 Views 1 min

Business Logic Implementation Patterns

Published May 5th, 2025 by Oleksandr Sydorenko

In Chapters 5 – 7 , where we discussed business logic in detail, you learned four differ‐ ent ways to model business logic: the transaction script, active record, domain model, and event-sourced domain model patterns. Both the transaction script and active record patterns are better suited for subdo‐ mains with simple business logic: supporting subd

1 min

When to Use Layered Architecture

Published May 5th, 2025 by Oleksandr Sydorenko

The dependency between the business logic and the data access layers makes this architectural pattern a good fit for a system with its business logic implemented using the transaction script or active record pattern. However, the pattern makes it challenging to implement a domain model. In a domain model, the business entities (aggregates and value

12 Views 1 min

Architectural and Integration Patterns

Published May 5th, 2025 by Oleksandr Sydorenko

• Dehghani, Z. (Expected to be published in 2022). Data Mesh: Delivering Data- Driven Value at Scale . Boston: O’Reilly. Zhamak Dehghani is the author of the data mesh pattern that we discussed in Chapter 16 . In this book, Dehghani explains the principles behind the data man‐ agement architecture, as well as how to implement the data mesh architect

1 min

Dimension Table

Published May 5th, 2025 by Oleksandr Sydorenko

Another essential building block of an analytical model is a dimension. If a fact repre‐ sents a business process or action (a verb), a dimension describes the fact (an adjective). The dimensions are designed to describe the facts’ attributes and are referenced as a foreign key from a fact table to a dimension table. The attributes modeled as dimen‐

13 Views 1 min

Consistency

Published May 5th, 2025 by Oleksandr Sydorenko

The ubiquitous language must be precise and consistent. It should eliminate the need for assumptions and should make the business domain’s logic explicit. Since ambiguity hinders communication, each term of the ubiquitous language should have one and only one meaning. Let’s look at a few examples of unclear termi‐ nology and how it can be improved.

12 Views 1 min

Model of the Business Domain

Published May 5th, 2025 by Oleksandr Sydorenko

Now let’s look at the ubiquitous language from a different perspective: modeling.

1 min

Architectural Patterns

Published May 5th, 2025 by Oleksandr Sydorenko

The tactical patterns discussed up to this point in the book defined the different ways to model and implement business logic. In this chapter, we will explore tactical design decisions in a broader context: the different ways to orchestrate the interactions and dependencies between a system’s components.

11 Views 1 min

Context Map

Published May 5th, 2025 by Oleksandr Sydorenko

After analyzing the integration patterns between a system’s bounded contexts, we can plot them on a context map, as shown in Figure 4-8 . Figure 4-8. Context map The context map is a visual representation of the system’s bounded contexts and the integrations between them. This visual notation gives valuable strategic insight on multiple levels: High

13 Views 1 min

Business Problems

Published May 5th, 2025 by Oleksandr Sydorenko

The software systems we are building are solutions to business problems. In this con‐ text, the word problem doesn’t resemble a mathematical problem or a riddle that you can solve and be done with. In the context of business domains, “problem” has a broader meaning. A business problem can be challenges associated with optimizing workflows and proces

15 Views 1 min

Model Differences

Published May 5th, 2025 by Oleksandr Sydorenko

Differences in the bounded contexts’ models can also be a reason to go with a sepa‐ rate ways collaboration. The models may be so different that a conformist relation‐ ship is impossible, and implementing an anticorruption layer would be more expensive than duplicating the functionality. In such a case, it is again more cost- effective for the teams

11 Views 1 min

Build an Ecosystem

Published May 5th, 2025 by Oleksandr Sydorenko

The final step to creating a data mesh system is to appoint a federated governance body to enable interoperability and ecosystem thinking in the domain of the analyti‐ cal data. Typically, that would be a group consisting of the bounded contexts’ data and product owners and representatives of the data infrastructure platform team, as shown in Figure

10 Views 1 min

Communication Patterns

Published May 5th, 2025 by Oleksandr Sydorenko

Chapters 5 – 8 presented tactical design patterns that define the different ways to implement a system’s components: how to model the business logic and how to orga‐ nize the internals of a bounded context architecturally. In this chapter, we will step beyond the boundaries of a single component and discuss the patterns for organizing the flow of co

16 Views 1 min

Partnership to Customer–Supplier

Published May 5th, 2025 by Oleksandr Sydorenko

The partnership pattern assumes there is strong communication and collaboration among teams. As time goes by, that might cease to be the case; for example, when work on one of the bounded contexts is moved to a distant development center. Such a change will negatively affect the teams’ communication, and it may make sense to move away from the partn

1 min

What Is EventStorming?

Published May 5th, 2025 by Oleksandr Sydorenko

EventStorming is a low-tech activity for a group of people to brainstorm and rapidly model a business process. In a sense, EventStorming is a tactical tool for sharing busi‐ ness domain knowledge. An EventStorming session has a scope: the business process that the group is interes‐ ted in exploring. The participants are exploring the process as a se

10 Views 1 min

Semantic Domains

Published May 5th, 2025 by Oleksandr Sydorenko

It can be said that domain-driven design’s bounded contexts are based on the lexico‐ graphical notion of semantic domains . A semantic domain is defined as an area of meaning and the words used to talk about it. For example, the words monitor, port, and processor have different meanings in the software and hardware engineering semantic domains. A ra

13 Views 1 min

Physical Boundaries

Published May 5th, 2025 by Oleksandr Sydorenko

Bounded contexts serve not only as model boundaries but also as physical boundaries of the systems implementing them. Each bounded context should be implemented as an individual service/project, meaning it is implemented, evolved, and versioned independently of other bounded contexts. Clear physical boundaries between bounded contexts allow us to im

12 Views 1 min

Data Warehouse

Published May 5th, 2025 by Oleksandr Sydorenko

The data warehouse (DWH) architecture is relatively straightforward. Extract data from all of the enterprise’s operational systems, transform the source data into an analytical model, and load the resultant data into a data analysis–oriented database. This database is the data warehouse. This data management architecture is based primarily on the ex

11 Views 2 min

Advantages

Published May 5th, 2025 by Oleksandr Sydorenko

Compared to the more traditional model, in which the aggregates’ current states are persisted in a database, the event-sourced domain model requires more effort to model the aggregates. However, this approach brings significant advantages that make the pattern worth considering in many scenarios: Time traveling Just as the domain events can be used

10 Views 1 min

Microservices as Deep Services

Published May 5th, 2025 by Oleksandr Sydorenko

A module in a software system, or any system, for that matter, is defined by its func‐ tion and logic. A function is what the module is supposed to do—its business func‐ tionality. The logic is the module’s business logic—how the module implements its business functionality. In his book, The Philosophy of Software Design, John Ousterhout discusses t

13 Views 1 min

Generic to Supporting

Published May 5th, 2025 by Oleksandr Sydorenko

Finally, for the same reason as a core subdomain, a generic subdomain can turn into a supporting one. Going back to the example of BuyIT’s document management sys‐ tem, assume the company has decided that the complexity of integrating the open source solution doesn’t justify the benefits and has resorted back to the in-house sys‐ tem. As a result, t

12 Views 1 min

Source of Truth

Published May 5th, 2025 by Oleksandr Sydorenko

For the event sourcing pattern to work, all changes to an object’s state should be rep‐ resented and persisted as events. These events become the system’s source of truth (hence the name of the pattern). This process is shown in Figure 7-1 . Figure 7-1. Event-sourced aggregate The database that stores the system’s events is the only strongly consist

13 Views 1 min

Colophon

Published May 5th, 2025 by Oleksandr Sydorenko

The animal on the cover of Learning Domain-Driven Design is a mona monkey (Cer‐ copithecus mona ), which can be found in the tropical forests of West Africa and the Caribbean islands, where they were introduced during the slave trade. They leap from trees in the mid- to top canopy, using their long tails for balance. Mona monkeys have brownish fur t

1 min

Heuristic

Published May 5th, 2025 by Oleksandr Sydorenko

A heuristic is not a hard rule that is guaranteed and mathematically proven to be cor‐ rect in 100% of cases. Rather, it’s a rule of thumb: not guaranteed to be perfect, yet sufficient for one’s immediate goals. In other words, using heuristics is an effective problem-solving approach that ignores the noise inherent in many cues, focusing instead on

11 Views 1 min

Strategic Modernization

Published May 5th, 2025 by Oleksandr Sydorenko

As we discussed in Chapter 10 , it can be risky to prematurely decompose the system into the smallest bounded contexts possible. We will discuss bounded contexts and microservices in more detail in the next chapter. For now, look for where the most value can be gained by turning the logical boundaries into physical boundaries. The process of extract

1 min

Distributed Big Ball of Mud

Published May 5th, 2025 by Oleksandr Sydorenko

Consider the system shown in Figure 15-5 . The CRM bounded context is implemented as an event-sourced domain model. When the CRM system had to be integrated with the Marketing bounded context, the teams decided to leverage the event-sourced data model’s flexibility and let the con‐ sumer—in this case, Marketing—subscribe to the CRM’s domain events a

1 min

Knowledge Discovery

Published May 5th, 2025 by Oleksandr Sydorenko

To design an effective software solution, we have to grasp at least the basic knowledge of the business domain. As we discussed in Chapter 1 , this knowledge belongs to domain experts: it’s their job to specialize in and comprehend all the intricacies of the business domain. By no means should we, nor can we, become domain experts. That said, it’s c

11 Views 1 min

Remote EventStorming

Published May 5th, 2025 by Oleksandr Sydorenko

EventStorming was invented as a low-tech activity in which people interact and learn together in the same room. The creator of the workshop, Alberto Brandolini, has often objected to conducting EventStorming remotely because it’s impossible to achieve the same levels of participation, and hence, collaboration and knowledge sharing, when the group is

10 Views 1 min

Domain Model

Published May 5th, 2025 by Oleksandr Sydorenko

The domain model pattern is intended to cope with cases of complex business logic. Here, instead of CRUD interfaces, we deal with complicated state transitions, busi‐ ness rules, and invariants: rules that have to be protected at all times. Let’s assume we are implementing a help desk system. Consider the following excerpt from the requirements that

12 Views 1 min

Data Mesh

Published May 5th, 2025 by Oleksandr Sydorenko

So far in this book, we have discussed models used to build operational systems. Operational systems implement real-time transactions that manipulate the system’s data and orchestrate its day-to-day interactions with its environment. These models are the online transactional processing (OLTP) data. Another type of data that deserves attention and pr

11 Views 1 min

When to Use CQRS

Published May 5th, 2025 by Oleksandr Sydorenko

The CQRS pattern can be useful for applications that need to work with the same data in multiple models, potentially stored in different kinds of databases. From an operational perspective, the pattern supports domain-driven design’s core value of working with the most effective models for the task at hand, and continuously improving the model of th

12 Views 1 min

Ownership Boundaries

Published May 5th, 2025 by Oleksandr Sydorenko

Studies show that good fences do indeed make good neighbors. In software projects, we can leverage model boundaries—bounded contexts—for the peaceful coexistence of teams. The division of work between teams is another strategic decision that can be made using the bounded context pattern. A bounded context should be implemented, evolved, and maintain

12 Views 1 min

Science

Published May 5th, 2025 by Oleksandr Sydorenko

As historian Yuval Noah Harari puts it, “Scientists generally agree that no theory is 100 percent correct. Thus, the real test of knowledge is not the truth, but utility.” In other words, no scientific theory is correct in all cases. Different theories are useful in different contexts. This notion can be demonstrated by the different models of gravi

10 Views 1 min

Tools

Published May 5th, 2025 by Oleksandr Sydorenko

There are tools and technologies that can alleviate the processes of capturing and managing a ubiquitous language. For example, a wiki can be used as a glossary to capture and document the ubiquitous language. Such a glossary alleviates the onboarding process of new team members, as it serves as a go-to place for information about the business domai

12 Views 1 min

Growth

Published May 5th, 2025 by Oleksandr Sydorenko

Growth is a sign of a healthy system. When new functionality is continuously added, it’s a sign that the system is successful: it brings value to its users and is expanded to further address users’ needs and keep up with competing products. But growth has a dark side. As a software project grows, its codebase can grow into a big ball of mud: A big b

10 Views 1 min

Analytical Models

Published May 5th, 2025 by Oleksandr Sydorenko

The table structure depicted in Figure 16-5 is called the star schema. It is based on the many-to-one relationships between the facts and their dimensions: each dimension record is used by many facts; a fact’s foreign key points to a single dimension record. Figure 16-5. The many-to-one relationship between facts and their dimensions Another predomi

12 Views 1 min

Language of the Business

Published May 5th, 2025 by Oleksandr Sydorenko

It’s crucial to emphasize that the ubiquitous language is the language of the business. As such, it should consist of business domain–related terms only. No technical jar‐ gon! Teaching business domain experts about singletons and abstract factories is not your goal. The ubiquitous language aims to frame the domain experts’ understanding and mental

10 Views 1 min

Event Sourcing

Published May 5th, 2025 by Oleksandr Sydorenko

Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowchart; it’ll be obvious. —Fred Brooks 1 Let’s use Fred Brooks’s reasoning to define the event sourcing pattern and understand how it differs from traditional modeling and persisting of data. Examine Table 7-1 a

12 Views 5 min

Modeling the Dimension of Time

Published May 5th, 2025 by Oleksandr Sydorenko

In the previous chapter, you learned about the domain model pattern: its building blocks, purpose, and application context. The event-sourced domain model pattern is based on the same premise as the domain model pattern. Again, the business logic is complex and belongs to a core subdomain. Moreover, it uses the same tactical pat‐ terns as the domain

14 Views 1 min

Evolving Design Decisions

Published May 5th, 2025 by Oleksandr Sydorenko

In the modern, fast-paced world we inhabit, companies cannot afford to be lethargic. To keep up with the competition, they have to continually change, evolve, and even reinvent themselves over time. We cannot ignore this fact when designing systems, especially if we intend to design software that’s well adapted to the requirements of its business do

1 min

Outbox

Published May 5th, 2025 by Oleksandr Sydorenko

The outbox pattern ( Figure 9-11 ) ensures reliable publishing of domain events using the following algorithm: • Both the updated aggregate’s state and the new domain events are committed in the same atomic transaction. • A message relay fetches newly committed domain events from the database. • The relay publishes the domain events to the message b

12 Views 1 min

EventStorming

Published May 5th, 2025 by Oleksandr Sydorenko

In this chapter, we will take a break from discussing software design patterns and techniques. Instead, we will focus on a low-tech modeling process called EventStorm‐ ing . This process brings together the core aspects of domain-driven design that we covered in the preceding chapters. You will learn the EventStorming process, how to facilitate an E

11 Views 1 min

Closing Words

Published May 5th, 2025 by Oleksandr Sydorenko

To complete our exploration of domain-driven design I want to get back to the quote we started with: There is no sense in talking about the solution before we agree on the problem, and no sense talking about the implementation steps before we agree on the solution. —Efrat Goldratt-Ashlag This quote neatly summarizes our DDD journey.

11 Views 1 min

Ubiquitous Language Refined

Published May 5th, 2025 by Oleksandr Sydorenko

Bounded contexts allow us to complete the definition of a ubiquitous language. A ubiquitous language is not “ubiquitous” in the sense that it should be used and applied “ubiquitously” throughout the organization. A ubiquitous language is not universal. Instead, a ubiquitous language is ubiquitous only in the boundaries of its bounded context. The la

11 Views 1 min

Generic to Core

Published May 5th, 2025 by Oleksandr Sydorenko

Since its inception, BuyIT has been using an off-the-shelf solution to manage its inventory. However, its business intelligence reports are continuously showing inade‐ quate predictions of its customers’ demands. Consequently, BuyIT fails to replenish its stock of the most popular products and is wasting warehouse real estate on the unpopular produc

11 Views 1 min

Disadvantages

Published May 5th, 2025 by Oleksandr Sydorenko

So far it may seem that the event-sourced domain model is the ultimate pattern for implementing business logic and thus should be used as often as possible. Of course, that would contradict the principle of letting the business domain’s needs drive the design decisions. So, let’s discuss some of the challenges presented by the pattern: Learning curv

11 Views 1 min

Step 10: Bounded Contexts

Published May 5th, 2025 by Oleksandr Sydorenko

The last step of an EventStorming session is to look for aggregates that are related to each other, either because they represent closely related functionality or because they’re coupled through policies. The groups of aggregates form natural candidates for bounded contexts’ boundaries, as shown in Figure 12-11 . Figure 12-11. A possible decompositi

14 Views 1 min

Testing Services with Restate SDK: A Comprehensive Guide

Published May 5th, 2025 by Oleksandr Sydorenko

Testing your Java and Kotlin services with the Restate SDK is straightforward and efficient. The SDK provides a comprehensive testing module that simplifies integration and service validation. Getting Started with SDK Testing To begin testing your services, you'll need to add the SDK testing module to your project. Include the following dependency i

1 min

Event-Driven Design Heuristics

Published May 5th, 2025 by Oleksandr Sydorenko

Matching types of events to the tasks at hand makes the resultant design orders of magnitude less coupled, more flexible, and fault tolerant. Let’s formulate the design heuristics behind the applied changes. Assume the worst As Andrew Grove put it, only the paranoid survive. 3 Use this as a guiding principle when designing event-driven systems: • Th

10 Views 1 min

Analysis

Published May 5th, 2025 by Oleksandr Sydorenko

Your business intelligence department asks you to provide a more analysis-friendly representation of the leads data. For their current research, they want to get the num‐ ber of follow-up calls scheduled for different leads. Later they will filter the converted and closed leads data and use the model to optimize the sales process. Let’s project the

12 Views 1 min

Bounded Contexts in Real Life

Published May 5th, 2025 by Oleksandr Sydorenko

In one of my domain driven-design classes, a participant once noted: “You said that DDD is about aligning software design with business domains. But where are the bounded contexts in real life? There are no bounded contexts in business domains.” Indeed, bounded contexts are not as evident as business domains and subdomains, but they are there, as do

15 Views 1 min

Decompose Data Around Domains

Published May 5th, 2025 by Oleksandr Sydorenko

Both the data warehouse and data lake approaches aim to unify all of the enterprise’s data into one big model. The resultant analytical model is ineffective for all the same reasons as an enterprise-wide operational model is. Furthermore, gathering data from all systems into one location blurs the ownership boundaries of the various data elements. I

10 Views 1 min

Method as a Service: Perfect Microservices?

Published May 5th, 2025 by Oleksandr Sydorenko

Saying that a microservice is a micro-public interface is deceptively simple. It may sound as though limiting service interfaces to a single method would result in perfect microservices. Let’s see what will happen if we apply this naïve decomposition in practice. Consider the backlog management service in Figure 14-3 . Its public interface consists

11 Views 1 min

Generating Past Transitions

Published May 5th, 2025 by Oleksandr Sydorenko

This approach entails generating an approximate stream of events for each aggregate so that the stream of events can be projected into the same state representation as in the original implementation. Consider the example you saw in Chapter 7 , as repre‐ sented in Table 11-1 . Table 11-1. A state-based representation of the aggregate’s data lead- in

1 min

Domain-Driven Design in the Real World

Published May 5th, 2025 by Oleksandr Sydorenko

We have covered domain-driven design tools for analyzing business domains, sharing knowledge, and making strategic and tactical design decisions. Just imagine how fun it will be to apply this knowledge in practice. Let’s consider a scenario in which you are working on a greenfield project. All of your coworkers have a strong grasp of domain-driven d

13 Views 1 min

Step 8: External Systems

Published May 5th, 2025 by Oleksandr Sydorenko

This step is about augmenting the model with external systems. An external system is defined as any system that is not a part of the domain being explored. It can execute commands (input) or can be notified about events (output). The external systems are represented by pink sticky notes. In Figure 12-9 , the CRM (external system) triggers execution

10 Views 1 min

Transaction Script to Active Record

Published May 5th, 2025 by Oleksandr Sydorenko

At their core, both the transaction script and active record patterns are based on the same principle: the business logic is implemented as a procedural script. The differ‐ ence between them is how the data structures are modeled: the active record pattern introduces the data structures to encapsulate the complexity of mapping them to the storage me

12 Views 1 min

Step 1: Unstructured Exploration

Published May 5th, 2025 by Oleksandr Sydorenko

EventStorming starts with a brainstorm of the domain events related to the business domain being explored. A domain event is something interesting that has happened in the business. It’s important to formulate domain events in the past tense (see Figure 12-2 )—they are describing things that have already happened. 1 Of course, that’s not a hard rule

10 Views 1 min

Modeling Migration Events

Published May 5th, 2025 by Oleksandr Sydorenko

The alternative approach is to acknowledge the lack of knowledge about past events and explicitly model it as an event. Instead of recovering the events that may have led to the current state, define a migration event and use it to initialize the event streams of existing aggregate instances: { "lead-id" : 12 , "event-id" : 0 , "event-type" : "migra

14 Views 1 min

Applying Domain-Driven Design in Practice

Published May 5th, 2025 by Oleksandr Sydorenko

In Parts I and II , we discussed domain-driven design tools for making strategic and tactical design decisions. In this part of the book, we move from theory to practice. You will learn to apply domain-driven design in real-life projects. • Chapter 10 merges what we discussed about strategic and tactical design into simple rules of thumb that stream

13 Views 1 min

Effective Modeling

Published May 5th, 2025 by Oleksandr Sydorenko

All models have a purpose, and an effective model contains only the details needed to fulfill its purpose. For example, you won’t see subway stops on a world map. On the other hand, you cannot use a subway map to estimate distances. Each map contains just the information it is supposed to provide. This point is worth reiterating: a useful model is n

14 Views 1 min

Testing Pyramid

Published May 5th, 2025 by Oleksandr Sydorenko

The classic testing pyramid emphasizes unit tests, fewer integration tests, and even fewer end-to-end tests. Both variants of the domain model patterns are best addressed with the testing pyramid. Aggregates and value objects make perfect units for effectively testing the business logic.

13 Views 1 min

Facilitation Tips

Published May 5th, 2025 by Oleksandr Sydorenko

When facilitating an EventStorming session with a group of people who have never done EventStorming before, I prefer to start with a quick overview of the process. I explain what we are about to do, the business process we are about to explore, and the modeling elements we will use in the workshop. As we go through the elements— domain events, comma

12 Views 1 min

Analytical Data Management Platforms

Published May 5th, 2025 by Oleksandr Sydorenko

Let’s shift the discussion from analytical modeling to data management architectures that support generating and serving analytical data. In this section, we will discuss two common analytical data architectures: data warehouse and data lake. You will learn the basic working principles of each architecture, how they differ from each other, and the c

10 Views 1 min

Microservices as Deep Modules

Published May 5th, 2025 by Oleksandr Sydorenko

Apart from different terminology, the notion of deep modules differs from the micro‐ services pattern in that the modules can denote both logical and physical boundaries, while microservices are strictly physical. Otherwise, both concepts and their underly‐ ing design principles are the same. The services implementing a single business method, shown

12 Views 1 min

Design Goal

Published May 5th, 2025 by Oleksandr Sydorenko

Following the simplistic decomposition heuristic of having each service expose only a single method proved to be suboptimal for many reasons. First, it’s simply not possi‐ ble. Since the services have to work together, we were forced to expand their public interfaces with integration-related public methods. Second, we won the battle but lost the war

12 Views 1 min

Integrating Aggregates

Published May 5th, 2025 by Oleksandr Sydorenko

In Chapter 6 , we discussed that one of the ways aggregates communicate with the rest of the system is by publishing domain events. External components can subscribe to these domain events and execute their logic. But how are domain events published to a message bus? Before we get to the solution, let’s examine a few common mistakes in the event pub

11 Views 1 min

Core to Generic

Published May 5th, 2025 by Oleksandr Sydorenko

Imagine that an online retail company called BuyIT has been implementing its own order delivery solution. It developed an innovative algorithm to optimize its couriers’ delivery routes and thus is able to charge lower delivery fees than its competitors. One day, another company—DeliverIT—disrupts the delivery industry. It claims it has solved the “t

11 Views 1 min

Communication Issues

Published May 5th, 2025 by Oleksandr Sydorenko

A common reason for avoiding collaboration is communication difficulties driven by the organization’s size or internal politics. When teams have a hard time collaborating and agreeing, it may be more cost-effective to go their separate ways and duplicate functionality in multiple bounded contexts.

12 Views 1 min

History

Published May 5th, 2025 by Oleksandr Sydorenko

As with both the transaction script and active record patterns, the domain model pat‐ tern was introduced initially in Martin Fowler’s book Patterns of Enterprise Applica‐ tion Architecture . Fowler concluded his discussion of the pattern by saying, “Eric Evans is currently writing a book on building Domain Models.” The referenced book is Evans’s se

11 Views 1 min

Modernization Strategy

Published May 5th, 2025 by Oleksandr Sydorenko

The “big rewrite” endeavors, in which the engineers are trying to rewrite the system from scratch, this time designing and implementing the whole system correctly, are rarely successful. Even more rarely does management support such architectural makeovers. A safer approach to improving the design of existing systems is to think big but start small.

11 Views 1 min

Events

Published May 5th, 2025 by Oleksandr Sydorenko

In an EDA system, the exchange of events is the key communication mechanism for integrating the components and making them a system. Let’s take a look at events in more detail and see how they differ from messages.

1 min

Active Record

Published May 5th, 2025 by Oleksandr Sydorenko

An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. —Martin Fowler 2 Like the transaction script pattern, active record supports cases where the business logic is simple. Here, however, the business logic may operate on more complex data structures. For example, instead of fla

1 min

Generic Subdomains

Published May 5th, 2025 by Oleksandr Sydorenko

The nature of the duplicated subdomain can also be a reason for teams to go their separate ways. When the subdomain in question is generic, and if the generic solution is easy to integrate, it may be more cost-effective to integrate it locally in each boun‐ ded context. An example is a logging framework; it would make little sense for one of the bou

11 Views 1 min

Deleting Data

Published May 5th, 2025 by Oleksandr Sydorenko

The event store is an append-only database, but what if I do need to delete data physi‐ cally; for example, to comply with GDPR? 3 This need can be addressed with the forgettable payload pattern: all sensitive information is included in the events in encrypted form. The encryption key is stored in an external key–value store: the key storage, where

11 Views 1 min

Organizational Changes

Published May 5th, 2025 by Oleksandr Sydorenko

Another type of change that can affect a system’s design is a change in the organiza‐ tion itself. Chapter 4 looked at different patterns of integrating bounded contexts: partnership, shared kernel, conformist, anticorruption layer, open-host service, and separate ways. Changes in the organization’s structure can affect teams’ communica‐ tion and co

10 Views 1 min

Model Translation

Published May 5th, 2025 by Oleksandr Sydorenko

A bounded context is the boundary of a model—a ubiquitous language. As you learned in Chapter 3 , there are different patterns for designing communication across different bounded contexts. Suppose the teams implementing two bounded contexts are communicating effectively and willing to collaborate. In this case, the bounded contexts can be integrate

12 Views 1 min

Model Boundaries

Published May 5th, 2025 by Oleksandr Sydorenko

As we discussed in the previous chapter, a model is not a copy of the real world but a construct that helps us make sense of a complex system. The problem it is supposed to solve is an inherent part of a model—its purpose. A model cannot exist without a boundary; it will expand to become a copy of the real world. That makes defining a model’s bounda

12 Views 1 min

What Is a Bounded Context?

Published May 5th, 2025 by Oleksandr Sydorenko

The solution in domain-driven design is trivial: divide the ubiquitous language into multiple smaller languages, then assign each one to the explicit context in which it can be applied: its bounded context. In the preceding example, we can identify two bounded contexts: marketing and sales. The term lead exists in both bounded contexts, as shown in

15 Views 1 min

Solution

Published May 5th, 2025 by Oleksandr Sydorenko

You learned to leverage this knowledge to design solutions optimized for each type of subdomain. We discussed four business logic implementation patterns—transaction script , active record , domain model , and event sourced domain model—and the scenar‐ ios in which each pattern shines. You also saw three architectural patterns that pro‐ vide the req

12 Views 1 min

Customer–Supplier to Separate Ways

Published May 5th, 2025 by Oleksandr Sydorenko

Unfortunately, it’s not uncommon for teams to have severe communication problems. The issues might be caused by geographical distance or organizational politics. Such teams may experience more and more integration issues over time. At some point, it may become more cost-effective to duplicate the functionality instead of continu‐ ously chasing one a

1 min

Further Reading

Published May 5th, 2025 by Oleksandr Sydorenko

I hope this book got you interested in domain-driven design. If you want to keep learning, here are some books that I wholeheartedly recommend.

13 Views 1 min

Who Should Participate in EventStorming?

Published May 5th, 2025 by Oleksandr Sydorenko

Just keep in mind that the goal of the workshop is to learn as much as possible in the shortest time possible. We invite key people to the workshop, and we don’t want to waste their valua‐ ble time. —Alberto Brandolini, creator of the EventStorming workshop Ideally, a diverse group of people should participate in the workshop. Indeed, anyone related

1 min

Anticorruption Layer

Published May 5th, 2025 by Oleksandr Sydorenko

As in the conformist pattern, the balance of power in this relationship is still skewed toward the upstream service. However, in this case, the downstream bounded context is not willing to conform. Instead, it can translate the upstream bounded context’s model into a model tailored to its own needs via an anticorruption layer, as shown in Figure 4-5

1 min

Enable Autonomy

Published May 5th, 2025 by Oleksandr Sydorenko

The product teams should be able to both create their own data products and con‐ sume data products served by other bounded contexts. Just as in the case of bounded contexts, the data products should be interoperable. It would be wasteful, inefficient, and hard to integrate if each team builds their own solution for serving analytical data. To preve

1 min

Fact Table

Published May 5th, 2025 by Oleksandr Sydorenko

Facts represent business activities that have already happened. Facts are similar to the notion of domain events in the sense that both describe things that happened in the past. However, contrary to domain events, there is no stylistic requirement to name facts as verbs in the past tense. Still, facts represent activities of business processes. For

12 Views 1 min

What Do You Need for EventStorming?

Published May 5th, 2025 by Oleksandr Sydorenko

EventStorming is considered a low-tech workshop because it is done using a pen and paper—a lot of paper, actually. Let’s see what you need in order to facilitate an Event‐ Storming session: Modeling space First, you need a large modeling space. A whole wall covered with butcher paper makes the best modeling space, as shown in Figure 12-1 . A large w

11 Views 1 min

Step 4: Pivotal Events

Published May 5th, 2025 by Oleksandr Sydorenko

Once you have a timeline of events augmented with pain points, look for significant business events indicating a change in context or phase. These are called pivotal events and are marked with a vertical bar dividing the events before and after the piv‐ otal event. For example, “shopping cart initialized,” “order initialized,” “order shipped,” “orde

11 Views 1 min

Tactical Design Decision Tree

Published May 5th, 2025 by Oleksandr Sydorenko

The business logic patterns, architectural patterns, and testing strategy heuristics can be unified and summarized with a tactical design decision tree, as depicted in Figure 10-7 . Figure 10-7. Tactical design decision tree As you can see, identifying subdomains types and following the decision tree gives you a solid starting point for making the e

12 Views 1 min

Understand the Business Domain

Published May 5th, 2025 by Oleksandr Sydorenko

First, identify the company’s business domain: • What is the organization’s business domain(s)? • Who are its customers? • What service, or value, does the organization provide to customers? • What companies or products is the organization competing with? Answering these questions will give you a bird’s-eye view of the company’s high-level goals. Ne

10 Views 1 min

Communication

Published May 5th, 2025 by Oleksandr Sydorenko

It’s safe to say that almost all software projects require the collaboration of stakehold‐ ers in different roles: domain experts, product owners, engineers, UI and UX design‐ ers, project managers, testers, analysts, and others. As in any collaborative effort, the outcome depends on how well all those parties can work together. For example, do all

15 Views 1 min

When to Use EventStorming

Published May 5th, 2025 by Oleksandr Sydorenko

The workshop can be facilitated for many reasons: Build a ubiquitous language As the group cooperates in building the model of the business process, they instinctively synchronize the terminology and start using the same language. Model the business process An EventStorming session is an effective way to build a model of the business process. Since

11 Views 1 min

Functional Coupling

Published May 5th, 2025 by Oleksandr Sydorenko

The Marketing and AdsOptimization bounded contexts both subscribed to the CRM’s domain events and ended up implementing the same projection of the cus‐ tomers’ data. In other words, the business logic that transforms incoming domain events into a state-based representation was duplicated in both bounded contexts, and it had the same reasons for chan

12 Views 1 min

Be Pragmatic

Published May 5th, 2025 by Oleksandr Sydorenko

Although business data is important and the code we design and build should protect its integrity, there are cases in which a pragmatic approach is more desirable. Especially at high levels of scale, there are cases when data consistency guarantees can be relaxed. Check whether corrupting the state of one record out of 1 million is really a showstop

11 Views 1 min

Implementation Coupling

Published May 5th, 2025 by Oleksandr Sydorenko

This type of coupling is more subtle. The Marketing and AdsOptimization bounded contexts are subscribed to all the domain events generated by the CRM’s event- sourced model. Consequently, a change in the CRM’s implementation, such as adding a new domain event or changing the schema of an existing one, has to be reflected in both subscribing bounded

12 Views 1 min

Variation

Published May 5th, 2025 by Oleksandr Sydorenko

It’s common to see the layered architecture pattern extended with an additional layer: the service layer. Service layer Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation. —Patterns of Enterprise Application Architecture 4 The service

10 Views 2 min

Process Manager

Published May 5th, 2025 by Oleksandr Sydorenko

The saga pattern manages simple, linear flow. Strictly speaking, a saga matches events to the corresponding commands. In the examples we used to demonstrate saga implementations, we actually implemented simple matching of events to commands: • CampaignActivated event to PublishingService.SubmitAdvertisement command • PublishingConfirmed event to Cam

11 Views 1 min

Types of Events

Published May 5th, 2025 by Oleksandr Sydorenko

Events can be categorized into one of three types: 2 event notification, event-carried state transfer, or domain events. Event notification An event notification is a message regarding a change in the business domain that other components will react to. Examples include PaycheckGenerated and Cam‐ paignPublished, among others. The event notification

10 Views 4 min

Supporting to Core

Published May 5th, 2025 by Oleksandr Sydorenko

A supporting subdomain can also turn into a core subdomain—for example, if a company finds a way to optimize the supporting logic in such a way that it either reduces costs or generates additional profits. The typical symptom of such a transformation is the increasing complexity of the supporting subdomain’s business logic. Supporting subdomains, by

12 Views 1 min

Layered Architecture

Published May 5th, 2025 by Oleksandr Sydorenko

Layered architecture is one of the most common architectural patterns. It organizes the codebase into horizontal layers, with each layer addressing one of the following technical concerns: interaction with the consumers, implementing business logic, and persisting the data. You can see this represented in Figure 8-1 . Figure 8-1. Layered architectur

12 Views 1 min

Why Can’t I Just…?

Published May 5th, 2025 by Oleksandr Sydorenko

Why can’t I just write logs to a text file and use it as an audit log? Writing data both to an operational database and to a logfile is an error-prone operation. In its essence, it’s a transaction against two storage mechanisms: the database and the file. If the first one fails, the second one has to be rolled back. For example, if a database transa

11 Views 1 min

Partnership

Published May 5th, 2025 by Oleksandr Sydorenko

In the partnership model, the integration between bounded contexts is coordinated in an ad hoc manner. One team can notify a second team about a change in the API, and the second team will cooperate and adapt—no drama or conflicts (see Figure 4-1 ). Figure 4-1. The partnership model The coordination of integration here is two-way. No one team dictat

1 min

Relationships to Other Methodologies and Patterns

Published May 5th, 2025 by Oleksandr Sydorenko

So far in this book you’ve learned how to use domain-driven design to design soft‐ ware solutions according to an organization’s business strategy and needs. We saw how to apply DDD tools and practices to make sense of the business domain, design the boundaries of the system’s components, and implement the business logic. Domain-driven design covers

12 Views 1 min

Aggregates

Published May 5th, 2025 by Oleksandr Sydorenko

When we discussed the domain model pattern in Chapter 6 , we used the following guiding principle for designing aggregates’ boundaries: The rule of thumb is to keep the aggregates as small as possible and include only objects that are required to be in a strongly consistent state by the business domain. As the system’s business requirements grow, it

10 Views 1 min

Explore the Current Design

Published May 5th, 2025 by Oleksandr Sydorenko

Once you are familiar with the problem domain, you can continue to investigate the solution and its design decisions. First, start with the high-level components. These are not necessarily bounded contexts in the DDD sense, but rather boundaries used to decompose the business domain into subsystems. The characteristic property to look for is the com

17 Views 1 min

Scenarios

Published May 5th, 2025 by Oleksandr Sydorenko

Let’s say we are working on an advertising campaign management system. Consider the following statements: • An advertising campaign can display different creative materials. • A campaign can be published only if at least one of its placements is active. • Sales commissions are accounted for after transactions are approved. All of these statements ar

11 Views 1 min

Step 9: Aggregates

Published May 5th, 2025 by Oleksandr Sydorenko

Once all the events and commands are represented, the participants can start think‐ ing about organizing related concepts in aggregates. An aggregate receives commands and produces events. Aggregates are represented as large yellow sticky notes, with commands on the left and events on the right, as depicted in Figure 12-10 . Figure 12-10. Commands a

11 Views 1 min

Core to Supporting

Published May 5th, 2025 by Oleksandr Sydorenko

A core subdomain can, over time, become a supporting subdomain. This can happen when the subdomain’s complexity isn’t justified. In other words, it’s not profitable. In such cases, the organization may decide to cut the extraneous complexity, leaving the minimum logic needed to support implementation of other subdomains.

10 Views 1 min

Designing Event-Driven Integration

Published May 5th, 2025 by Oleksandr Sydorenko

As we discussed in Chapter 3 , software design is predominantly about boundaries. Boundaries define what belongs inside, what remains outside, and most importantly, what goes across the boundaries—essentially, how the components are integrated with one another. The events in an EDA-based system are first-class design elements, affecting both how the

12 Views 1 min

Cooperation

Published May 5th, 2025 by Oleksandr Sydorenko

Cooperation patterns relate to bounded contexts implemented by teams with well- established communication. In the simplest case, these are bounded contexts implemented by a single team. This also applies to teams with dependent goals, where one team’s success depends on the success of the other, and vice versa. Again, the main criterion here is the

11 Views 1 min

Selling Domain-Driven Design

Published May 5th, 2025 by Oleksandr Sydorenko

When I present on this topic at technology conferences, there is one question that I’m asked almost every time: “That all sounds great, but how do I ‘sell’ domain-driven design to my team and management?” That’s an extremely important question. Selling is hard, and personally, I hate selling. That said, if you think about it, design‐ ing software is

13 Views 1 min

Maintenance

Published May 5th, 2025 by Oleksandr Sydorenko

Ideally, a context map should be introduced into a project right from the get-go, and be updated to reflect additions of new bounded contexts and modifications to the existing one. Since the context map potentially contains information originating from the work of multiple teams, it’s best to define the maintenance of the context map as a shared eff

10 Views 1 min

Modeling the Business Domain

Published May 5th, 2025 by Oleksandr Sydorenko

When cultivating a ubiquitous language, we are effectively building a model of the business domain. The model is supposed to capture the domain experts’ mental mod‐ els—their thought processes about how the business works to implement its function. The model has to reflect the involved business entities and their behavior, cause and effect relations

11 Views 1 min

Microservices

Published May 5th, 2025 by Oleksandr Sydorenko

In the mid-2010s, microservices took the software engineering industry by storm. The intent was to address modern systems’ need to change quickly, scale, and fit the distributed nature of cloud computing naturally. Many companies made the strategic decision to decompose their monolithic codebases in favor of the flexibility provided by the microserv

12 Views 1 min

Testing Diamond

Published May 5th, 2025 by Oleksandr Sydorenko

The testing diamond focuses the most on integration tests. When the active record pattern is used, the system’s business logic is, by definition, spread across both the service and business logic layers. Therefore, to focus on integrating the two layers, the testing pyramid is the more effective choice.

12 Views 1 min

Limitations

Published May 5th, 2025 by Oleksandr Sydorenko

It’s important to note that charting a context map can be a challenging task. When a system’s bounded contexts encompass multiple subdomains, there can be multiple integration patterns at play. For example, in Figure 4-9 , you can see two bounded contexts with two integration patterns: partnership and anticorruption layer. Figure 4-9. Complicated co

12 Views 1 min

Design Heuristics

Published May 5th, 2025 by Oleksandr Sydorenko

“It depends” is the correct answer to almost any question in software engineering, but not really practical. In this chapter, we will explore what “it” depends on. In Part I of the book, you learned domain-driven design tools for analyzing business domains and making strategic design decisions. In Part II , we explored tactical design patterns: the

11 Views 1 min

Communication Between Layers

Published May 5th, 2025 by Oleksandr Sydorenko

The layers are integrated in a top-down communication model: each layer can hold a dependency only on the layer directly beneath it, as shown in Figure 8-5 . This enfor‐ ces decoupling of implementation concerns and reduces the knowledge shared between the layers. In Figure 8-5 , the presentation layer references only the business logic layer. It ha

12 Views 1 min

Active Record to Domain Model

Published May 5th, 2025 by Oleksandr Sydorenko

If the business logic that manipulates active records becomes complex and you notice more and more cases of inconsistencies and duplications, refactor the implementa‐ tion to the domain model pattern. Start by identifying value objects. What data structures can be modeled as immutable objects? Look for the related business logic, and make it a part

11 Views 1 min

Step 7: Read Models

Published May 5th, 2025 by Oleksandr Sydorenko

A read model is the view of data within the domain that the actor uses to make a decision to execute a command. This can be one of the system’s screens, a report, a notification, and so on. The read models are represented by green sticky notes (see the “Shopping cart” note in Figure 12-8 ) with a short description of the source of information needed

12 Views 1 min

Managing Complexity

Published May 5th, 2025 by Oleksandr Sydorenko

As noted in this chapter’s introduction, the aggregate and value object patterns were introduced as a means for tackling complexity in the implementation of business logic. Let’s see the reasoning behind this. In his book The Choice , business management guru Eliyahu M. Goldratt outlines a succinct yet powerful definition of system complexity. Accor

11 Views 1 min

Changes in Domains

Published May 5th, 2025 by Oleksandr Sydorenko

In Chapter 2 , you’ve learned the three types of business subdomains and how they are different from one another: Core Activities the company is performing differently from its competitors to gain a competitive advantage Supporting Things the company is doing differently from its competitors, but that do not provide a competitive edge Generic Things

10 Views 1 min

Separate Ways

Published May 5th, 2025 by Oleksandr Sydorenko

The last collaboration option is not to collaborate at all. This pattern can arise for dif‐ ferent reasons, in cases where the teams are unwilling or unable to collaborate. We’ll look at a few of them here.

10 Views 1 min

Optional: Layers Versus Tiers

Published May 5th, 2025 by Oleksandr Sydorenko

The layers architecture is often confused with the N-Tier architecture, and vice versa. Despite the similarities between the two patterns, layers and tiers are conceptually different: a layer is a logical boundary, whereas a tier is a physical boundary. All layers in the layered architecture are bound by the same lifecycle: they are implemented, evo

10 Views 1 min

Projecting Read Models

Published May 5th, 2025 by Oleksandr Sydorenko

For the read models to work, the system has to project changes from the command execution model to all its read models. This concept is illustrated in Figure 8-12 . Figure 8-12. CQRS architecture The projection of read models is similar to the notion of a materialized view in rela‐ tional databases: whenever source tables are updated, the changes ha

13 Views 1 min

Business Logic Versus Architectural Patterns

Published May 5th, 2025 by Oleksandr Sydorenko

Business logic is the most important part of software; however, it is not the only part of a software system. To implement functional and nonfunctional requirements, the codebase has to fulfill more responsibilities. It has to interact with users to gather input and provide output, and it has to use different storage mechanisms to persist state and

13 Views 1 min

Exercises

Published May 5th, 2025 by Oleksandr Sydorenko

1. Who should be able to contribute to the definition of a ubiquitous language? a. Domain experts b. Software engineers c. End users d. All of the project’s stakeholders 2. Where should a ubiquitous language be used? a. In-person conversations b. Documentation c. Code d. All of the above 3. Please review the description of the fictional WolfDesk com

1 min

Terminology

Published May 5th, 2025 by Oleksandr Sydorenko

Essentially, both the presentation layer and data access layer represent integration with external components: databases, external services, and user interface frame‐ works. These technical implementation details do not reflect the system’s business logic; so, let’s unify all such infrastructural concerns into a single “infrastructure layer,” as sho

1 min

Presentation Layer

Published May 5th, 2025 by Oleksandr Sydorenko

The presentation layer, shown in Figure 8-2 , implements the program’s user interface for interactions with its consumers. In the pattern’s original form, this layer denotes a graphical interface, such as a web interface or a desktop application. In modern systems, however, the presentation layer has a broader scope: that is, all means for triggerin

13 Views 1 min

Dependency Inversion Principle

Published May 5th, 2025 by Oleksandr Sydorenko

The dependency inversion principle (DIP) states that high-level modules, which implement the business logic, should not depend on low-level modules. However, that’s precisely what happens in the traditional layered architecture. The business logic layer depends on the infrastructure layer. To conform with the DIP, let’s reverse the relationship, as

11 Views 1 min

When to Use Transaction Script

Published May 5th, 2025 by Oleksandr Sydorenko

The transaction script pattern is well adapted to the most straightforward problem domains in which the business logic resembles simple procedural operations. For example, in extract-transform-load (ETL) operations, each operation extracts data from a source, applies transformation logic to convert it into another form, and loads the result into the

11 Views 1 min

Combining Data Mesh and Domain-Driven Design

Published May 5th, 2025 by Oleksandr Sydorenko

These are the four principles that the data mesh architecture is based on. The empha‐ sis on defining boundaries, and encapsulating the implementation details behind well-defined output ports, makes it evident that the data mesh architecture is based on the same reasoning as domain-driven design. Furthermore, some of the domain- driven design patter

12 Views 1 min

Structure

Published May 5th, 2025 by Oleksandr Sydorenko

An event is a data record that can be serialized and transmitted using the messaging platform of choice. A typical event schema includes the event’s metadata and its pay‐ load—the information communicated by the event: { "type" : "delivery-confirmed" , "event-id" : "14101928-4d79-4da6-9486-dbc4837bc612", "correlation-id" : "08011958-6066-4815-8dbe-d

12 Views 1 min

Command-Query Responsibility Segregation

Published May 5th, 2025 by Oleksandr Sydorenko

The command-query responsibility segregation (CQRS) pattern is based on the same organizational principles for business logic and infrastructural concerns as ports & adapters. It differs, however, in the way the system’s data is managed. This pattern enables representation of the system’s data in multiple persistent models. Let’s see why we migh

10 Views 1 min

When to Use Active Record

Published May 5th, 2025 by Oleksandr Sydorenko

Because an active record is essentially a transaction script that optimizes access to databases, this pattern can only support relatively simple business logic, such as CRUD operations, which, at most, validate the user’s input. Accordingly, as in the case of the transaction script pattern, the active record pattern lends itself to supporting subdom

11 Views 1 min

Implementation

Published May 5th, 2025 by Oleksandr Sydorenko

Each procedure is implemented as a simple, straightforward procedural script. It can use a thin abstraction layer for integrating with storage mechanisms, but it is also free to access the databases directly. The only requirement procedures have to fulfill is transactional behavior. Each opera‐ tion should either succeed or fail but can never result

11 Views 1 min

Challenges of Data Warehouse and Data Lake Architectures

Published May 5th, 2025 by Oleksandr Sydorenko

Both data warehouse and data lake architectures are based on the assumption that the more data that is ingested for analytics, the more insight the organization will gain. Both approaches, however, tend to break under the weight of “big” data. The trans‐ formation of operational to analytical models converges to thousands of unmaintain‐ able, ad hoc

10 Views 1 min

What Is a Ubiquitous Language?

Published May 5th, 2025 by Oleksandr Sydorenko

Using a ubiquitous language is the cornerstone practice of domain-driven design. The idea is simple and straightforward: if parties need to communicate efficiently, instead of relying on translations, they have to speak the same language. Although this notion is borderline common sense, as Voltaire said, “common sense is not so common.” The traditio

17 Views 1 min

Cultivate a Ubiquitous Language

Published May 5th, 2025 by Oleksandr Sydorenko

A prerequisite to the successful modernization of a design is the domain knowledge and effective model of the business domain. As I have mentioned several times throughout this book, domain-driven design’s ubiquitous language is essential for achieving knowledge and building an effective solution model. Don’t forget domain-driven design’s shortcut f

11 Views 3 min

Undercover Domain-Driven Design

Published May 5th, 2025 by Oleksandr Sydorenko

Make domain-driven design a part of your professional toolbox, not an organiza‐ tional strategy. DDD’s patterns and practices are engineering techniques, and since software engineering is your job, use them! Let’s see how to incorporate DDD into your day-to-day job without making much ado about it. Ubiquitous language The use of a ubiquitous languag

11 Views 2 min

Scope

Published May 5th, 2025 by Oleksandr Sydorenko

The patterns we’ve discussed—layered architecture, ports & adapters architecture, and CQRS—should not be treated as systemwide organizational principles. These are not necessarily high-level architecture patterns for a whole bounded context either. Consider a bounded context encompassing multiple subdomains, as shown in Figure 8-17 . The subdoma

11 Views 1 min

Customer–Supplier

Published May 5th, 2025 by Oleksandr Sydorenko

The second group of collaboration patterns we’ll examine is the customer–supplier patterns. As shown in Figure 4-3 , one of the bounded contexts—the supplier—pro‐ vides a service for its customers. The service provider is “upstream” and the customer or consumer is “downstream.” Figure 4-3. Customer–supplier relationship Unlike in the cooperation cas

1 min

It’s Not That Easy!

Published May 5th, 2025 by Oleksandr Sydorenko

When I introduce the transaction script pattern in my domain-driven design classes, my students often raise their eyebrows, and some even ask, “Is it worth our time? Aren’t we here for the more advanced patterns and techniques?” The thing is, the transaction script pattern is a foundation for the more advanced business logic implementation patterns

13 Views 3 min
Load More

info@smartphonekey.com

  • Home
  • How It Works
  • Features
  • Residents and Tenants
  • Property Managers
  • Airbnb Hosts
  • Products
  • Blog
  • Guide for Usage and Installation
  • Our Team
  • Contact Us
  • Privacy Policy
  • Terms of Service
  • Facebook
  • Instagram
  • LinkedIn
© 2025, Smartphonekey.com Powered by Shopify
Expand