0

I'm kind of stuck at modeling this problem in the right way applying Domain Driven Design way. I want to model travelling group in a traveling agency.

We have concepts like passenger, group, and group member in one bounded context. This passenger is a large AR that holds all sorts of information, like name, job, address, bank account, religion, ANYTHING. But not all of them are necessary for all kinds of travels and their invariants differ based on the type of the trip. For example in travel type A, we don't need passengers' phone numbers. In travel type B we do. So when a person goes to create a group to go on travel type B, I will have an invariant on passenger AR to have a valid data for phone.

So basically there are two challenges here: How can I break this huge AR and how should I handle enforcing these conditional invariants? Is it OK if I enforce invariants on passenger AR inside handlers - application service- while creating group AR? (Besides, the passenger AR and the group AR are in the same bounded context but they have the potential to be separated in the future).

Gru97
  • 471
  • 5
  • 8

2 Answers2

0

I would say the constraint here should be not on passenger, but on the group. At the end you may create passengers for different type of travels with or without phone numbers. The actual constraint should be enforced like a passenger without a phone should not be added to that particular group as a group member. Regarding the implementation side:

public void addPassengerToGroup(PassengerInformation passenger) {
    //original code omitted
    this.assertArgumentTrue(passenger.isPhoneInformationProvided(), "Passenger doesn't have contact information.");

    this.groupMembers().add(passenger); 
}

Somethink like this may solve your problem problem for constraint checks.

There is also some addition explanation for a similar situation: https://softwareengineering.stackexchange.com/questions/319602/how-to-treat-validation-of-references-between-aggregates

cool
  • 1,746
  • 1
  • 14
  • 15
0

This passenger is a large AR that holds all sorts of information, like name, job, address, bank account, religion, ANYTHING.

Well, to be honest, that sounds wrong as an aggregate. Consider why would you have this aggregate in the first place? What sort of business logic does this aggregate that involves the religion and bank account? or name? or address?

So, in short, this doesn't look like a Passenger aggregate. It looks more like a Customer record on a CRM without following DDD.

The first thing I would suggest is to consider your bounded contexts. I don't know your domain nor the specifics of your application, but most likely, you need bank account information for Finance reasons. So you'll have a Finance Bounded Context with Customers, their bank accounts, the invoices that you sent to them, and so on. You might also have a Bounded Context like Traveling or similar. Here, you might have a Passenger. A passenger could have a CustomerId and a TripId, plus other information, like ContactInformation and so on. You can also have Groups, with a list of Members and each Member could have a PassengerId and other information needed for the group management.

Obviously this is just an example from the limited information I have, but it seems to me, as I said, that a Customer becomes a Passenger when she signs up for a Trip. If the same Customer signs up for another trip, you'll create a new Passenger. There is no reason to reuse the same Passenger aggregate for multiple trips, because, as you said, even if it's the same person going to multiple Trips, the requirements for each are different, so trying to model a single Passenger that will fit all present and future types of Trips is creating an artificial coupling in my opinion.

Also, as I said previously, consider what information do you need on each aggregate. Even if across the whole application you know a lot of things from a single "person", it doesn't mean that you have to store them in a single place. That is the main point of DDD, in my opinion, finding where each piece of information belongs to and put it together with the business logic that needs it.

Francesc Castells
  • 2,692
  • 21
  • 25