DEV Community

The Struggling Dev
The Struggling Dev

Posted on

Struggling Dev's sneaky Domain Driven Design

DDD has many benefits, but it's also "a lot" to digest. You have your Ubiquitous Language, Entities, Aggregates, VOs, Application & Domain Services, ... . And this means you have to learn this stuff yourself, teach it to the rest of your team, get your team lead to buy in, ... . This might be hard, to do all at once. But there's an alternative way, a sneaky way. Start simple.

For example, you can start with Value Objects. The basics of Value Objects are:

  • they are small, and
  • they are immutable
data class MyValueObject(val value: String)
Enter fullscreen mode Exit fullscreen mode

A thing I often see is creative names to get value x by different types of IDs. Additionally, sometimes there are even objects that have multiple IDs by which we can find them. Who hasn't seen repositories or DAOs that look like this.

class SomeRepository {
  fun getCustomerByCustomerId(customerId: UUID): Customer? { /* ... */ }
  fun getCustomerByAddressId(addressId: UUID): Customer? { /* ... */ }
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

And of course, people get creative with the names.

fun getCustomerByAddressId(addressId: UUID): Customer? { /* ... */ }
fun getCustomerForAddressId(addressId: UUID): Customer? { /* ... */ }
fun getCustomerWithAddressId(addressId: UUID): Customer? { /* ... */ }
fun getCustomerBasedOnAddressId(addressId: UUID): Customer? { /* ... */ }
/* ... */
Enter fullscreen mode Exit fullscreen mode

Which leads to inconsistent naming across repositories or even duplication within a single repository. To "fix" this, we can introduce Value Objects.

data class AddressId(val value: UUID)
data class CustomerId(val value: UUID)
Enter fullscreen mode Exit fullscreen mode

For our special case where our Value Object has only one property we can also use [Inline classes].(https://kotlinlang.org/docs/inline-classes.html#members)

@JvmInline
value class AddressId(private val value: UUID)

Which allows us to simplify the names in our repository:

class SomeRepository {
  fun getCustomer(customerId: CustomerId): Customer? { /* ... */ }
  fun getCustomer(addressId: AddressId): Customer? { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

An additional benefit of this is, that you won't call myRepositoryInstance.getCustomerByAddressId() with a customer ID and wonder why you don't get the customer back, you know exists for this address ID😤.

And if you want to impress people, you can tell them that you're fixing a code smell called Primitive (Type) Obsession. Especially if your IDs are integers or strings.

There are more, simple and "sneaky" ways of starting with DDD.

So, get creative - and keep on struggling.

Struggles in this post

  • Getting it out of the door. Not wanting to add dozens of examples.
  • But hey, there's always the option of a part two and being agile means releasing stuff, learning and improving incrementally.

Top comments (0)