Domain-Driven Design
Bounded Contexts
The solution boundary you draw once the problem has a name — where a word is allowed to mean one thing.
A subdomain is a name for a problem. A bounded context is the place you are allowed to model that problem. Inside the line, a word means one thing, and the model has to stay consistent. Across the line, the same word is allowed to mean something else, and you translate.
Here is an example. The catalog and the canvas both say Creative. They do not mean the same object.
Creative means two things
The catalog side has a slot and its published versions. It exists so a campaign can point at something the exchange will play.
public sealed class CatalogCreative
{
public CatalogCreativeId Id { get; private set; }
public MediaType MediaType { get; private set; }
public int? SlotLengthSeconds { get; private set; }
public bool Archived { get; private set; }
}
public sealed class CatalogCreativeVersion
{
public CatalogCreativeVersionId Id { get; private set; }
public CatalogCreativeId CreativeId { get; private set; }
public VersionStatus Status { get; private set; }
public Dimensions Dimensions { get; private set; }
}
The canvas creative is an editable design: width, height, and how it is delivered. Its editor data lives beside it.
public sealed class CanvasCreative
{
public CanvasCreativeId Id { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public DeliveryType DeliveryType { get; private set; }
}
Publishing compiles the editor data, then creates a catalog creative and a catalog version with new ids. Name and slot length cross to the catalog creative. Width and height cross to the published version. The editable canvas remains a different object with a different history.
The duplication is deliberate. Sharing one Creative class would let editor state, catalog lifecycle, and version approval change the same model for unrelated reasons.
A post-campaign report has the same pattern with Campaign. The buying model has budget, dates, and an exchange id. The report only needs a campaign id, a name, and a sort order. Sharing the id is fine. Sharing the class is not.
Fowler’s point is that the model inside the line has to be unified. Conversation can paper over a noun meaning two things. Code cannot. You draw the line, and you are explicit about what sits on each side.
The model draws the line
The two Creative id types, folders, and publish handler make this boundary visible. They do not create it. The boundary exists because each model has a different job, language, and rate of change. The handler translates between them when a design becomes something the catalog can serve.
This matters when the code is rearranged. Putting both types in one assembly would not merge their models. Putting one type in a microservice would not prove it had a bounded context. Projects and services are deployment choices. A bounded context is an ownership and understanding boundary.
Subdomains and contexts need not match
Verraes and Wirfs-Brock put the distinction plainly: subdomains live in the problem; bounded contexts are design choices in the solution. One subdomain can need several models. One context can also contain several closely related parts of a model.
MiniVerine’s Domain contains Envelope, Messaging, and Sagas in one context. Each owns different rules, but they share one account of a message moving through the bus. Messaging does not create a second Envelope meaning “the AMQP frame”. RabbitMQ will have to translate its frame into the core model.
Creating Domains found divisions in the problem. Drawing a bounded context decides where each model may stay internally consistent.
Do not unify because it looks tidy
The instinct, once you see two Creatives, is to merge them. Unifying would be a design choice, not a law. Verraes and Wirfs-Brock argue from rate of change: keep together the concepts that change at the same pace.
The canvas changes with widgets, preview, and compile. The catalog changes with approval and the exchange. Forcing one Creative would couple those clocks. Copying a name and duration across a translator is more honest than pretending the canvas is a version of the slot.
A bounded context is where the words are allowed to settle. Ubiquitous Language is those words, used in speech and in code.