Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a practical way to model lookup tables in Domain Driven Design (DDD)?

I'm just learning DDD (Eric Evans book is open in front of me) and I've come across a problem that I can't find an answer for. What do you do in DDD when you're just trying to get a simple list of lookup records?

Ex.

EmployeeID: 123
EmployeeName: John Doe
State: Alaska (drop-down)
County: Wasilla (drop-down -- will be filtered based on state).

For example, let's say that you have an Employee domain object, an IEmployeeRepository interface and an EmployeeRepository class. This will be used by a UI to show a list of employees and individual details. In the UI, you want to use a drop-down for the State and County where the employee lives. The Available counties will be filtered based on which state was chosen.

Unfortunately, the database tables and the UI look very different. In tblEmployees, it contains State Code=AK and County Code=02130, not the State and County Names.

The old way (before I began this DDD quest) would be pretty straightforward, just create 2 queries and use a DataReader to populate the drop-downs. Underneath the display in the drop-downs is the value, which gets automatically used in form posts.

With DDD, though, I'm not sure how you're supposed to do this. I first started by creating State and County objects as well repositories and interfaces for the repositories. However, writing 4 classes + 2 interfaces and the plumbing in the hbm.xml files + Employee Business objects seems like overkill for just 2 queries for 2 drop-downs. There has to be a better way, doesn't there? I'm not changing the records in the State or County tables any time soon and even if I did, it wouldn't be through this application. So I don't really want to create business objects for State and County if I don't have to.

The simplest solution that I see is to just create a helper class with methods that return dictionaries, such as GetStatesAll(), GetState() and GetCounties() and GetCounty(), but that just feels wrong from a DDD perspective.

Please help. How can I use DDD without overengineering just a couple of simple lookups?

Final Solution I think that I finally found my answer through experience, which was to put the GetStates() method into its own Data Access class, though not a repository class. Since I was only doing read-only access, I threw it into a struct DTO. Since the database was small, I threw them altogether into a single class, like Todd below described.

My conclusions:

  1. Lookup tables are NEVER value objects, because lookup tables ALWAYS have an identity. If they didn't have an identity, you'd have duplicates, which wouldn't make much sense.
  2. Read-only lookup table can have a repository, but probably don't need one. The goal of a repository is to reduce complexity by forcing access only through the aggregate. Going through the aggregate provides you with a way to ensure that business rules can be enforced, such as not adding tires if you don't have a car.
  3. If you allow CRUD maintenance on the lookup table, then it makes sense for the lookup table to have its own repository.
  4. The fact that I ended up storing the codes as structs doesn't make them "value types". Fowler says in POEAA that a struct is a value type. That's true, structs are immutable, which is why Fowler says that they are "value types", however I was using them differently. I was using structs as a lightweight way to pass around DTOs that I didn't ever plan on changing after their initial creation. In truth, the structs that I used did, indeed, have identities, but since they were read-only they worked as structs.
  5. One pattern that I've been using that I don't see much elsewhere is to make primary key fields be immutable. They're set by the constructor, but they're read-only (not private accessors) and cannot be changed once the object is created.
like image 751
John Avatar asked Apr 30 '09 18:04

John


People also ask

What is domain model in DDD?

A DDD domain model is composed from aggregates, an aggregate can have just one entity or more, and can include value objects as well. Note that the Buyer aggregate could have additional child entities, depending on your domain, as it does in the ordering microservice in the eShopOnContainers reference application.

Which approach we can use for domain driven design?

Domain-Driven Design is a concept introduced by a programmer Eric Evans in 2004 in his book Domain-Driven Design: Tackling Complexity in Heart of Software. It is an approach for architecting software design by looking at software in top-down approach.

What is DDD pattern?

DDD patterns help you understand the complexity in the domain. For the domain model for each Bounded Context, you identify and define the entities, value objects, and aggregates that model your domain. You build and refine a domain model that is contained within a boundary that defines your context.

What is DDD architecture?

Domain-driven design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts. Its premise is: - Place the project's primary focus on the core domain and domain logic. - Base complex designs on a model.


2 Answers

You may want to look into the concept of Command Query Separation. I wouldn't worry about typed repositories for lookup values, but I'd still probably use DTO type classes over datasets etc...

You may want to spend some time reading Greg Young's blogs starting from this one to the present. He doesn't talk about filling lookup data specifically but he often talks about not handling the reading/reporting functionality of your application through typed methods on a repository.

like image 131
Daniel Auger Avatar answered Sep 20 '22 17:09

Daniel Auger


Using DDD I have something similar with the following:

interface IAddressService {   IList<Country> GetCountries ();   IList<State> GetStatesByCountry (string country);   IList<City> GetCitiesByState (string state);   // snip } 

Country, State and City are value objects which come from a lookup table in the database.

like image 38
Todd Smith Avatar answered Sep 16 '22 17:09

Todd Smith