DDD in Action: Insights from an iOS Developer’s Perspective

Photo by Hal Gatewood on Unsplash

Domain-Driven Design (DDD) is the “art” of translating of understanding and modeling the complex business domain that a software system will operate in.

It is based on the idea that the software should be driven by the needs of the business domain, rather than the other way around.

At the heart of DDD are three key concepts: the ubiquitous language, bounded contexts, and the domain model.

Creating a Ubiquitous Language

The ubiquitous language is a shared language that is used to communicate and model the domain concepts and rules. To create a shared language that accurately reflects the business domain, it is important to consult with domain experts and gather as much information as possible. This process of creating a ubiquitous language helps to improve communication within the team, as it clearly defines the terms and concepts used in the business. The use of a consistent, shared language is also important in the codebase, as it helps to maintain consistency and avoid ambiguous naming. This can make it easier for team members to understand each other’s work and for new members to quickly get up to speed. In contrast, if each team member used their own preferred terms and naming conventions, it would be much more difficult to effectively communicate and collaborate.

As an example, consider a Food Ordering App that allows users to browse a menu of dishes, place orders, and track the status of their orders. In this context, key domain concepts might include the menu, individual dishes, orders, and order status. These concepts could be defined in collaboration with domain experts and then translated directly into structures in the code, such as classes or models. For example, there might be a Menu that represents the overall menu, a Dish that represents an individual dish, an Order that represents a customer’s order, and an OrderStatus that tracks the status of an order.

Defining Bounded Contexts

Bounded contexts are used to define and isolate different parts of the domain

To continue with our Food Ordering App we could identify, ideally together with the experts three contexts:

- Menu Management: This context would be concerned with managing and updating the list of dishes available for ordering, as well as any related metadata such as prices, descriptions, and categories.

- Order Processing: This context would handle the mechanics of placing and tracking orders, including calculating costs, handling payment, and updating the order status.

- Kitchen Management: This context could focus on managing the preparation and delivery of orders, including coordinating with the restaurant staff and tracking inventory.

We can take these context and create for example different modules to enforce some kind of separation between these contexts. Important is here to note that a Dish model might look completely different in the Menu Management context vs Kitchen Management.

In the Menu Management context, a Dish model might look like this in Swift:

struct Dish {
var id: String
var name: String
var description: String
var price: Double
var category: String
var imageUrl: String
}

In the Order Processing context, a Dish model might look like this:

struct Dish {
var id: String
var name: String
var price: Double
var quantity: Int
}

In the Kitchen Management context, a Dish model might look like

struct Dish {
var id: String
var name: String
var ingredients: [String]
var preparationInstructions: String
var estimatedPrepTime: Int
}

Building Domain Models

The domain model represents the concepts and rules of the domain in the form of entities, value objects or aggregates

One key aspect of the domain model is that it should be independent of the implementation details of the system. It should focus on modeling the core concepts and rules of the domain, rather than on the specific details of how the system will be implemented or deployed.

We should put the needs and requirements of the domain in front and ignore all the database details, API requirements or change our model to fit better with a specific third-party framework.

This allows my apps to have a robust foundation, on which I can build use cases, view models, view, API layer and more.

Lessons Learned from DDD for my iOS Development

DDD has been a really useful tool for my iOS development work. It builds on the Clean Architecture concept by helping me to better understand the “why” and “how” of the core layer, also known as the domain layer. One of the big benefits of using DDD is that it allows me to make the domain layer agnostic of things like the user interface, frameworks, and APIs. This makes my apps more testable, mockable, and able to adapt to change, which is really important for maintaining a healthy codebase. In addition to these technical benefits, I’ve found that working with DDD encourages me to think more about the business side of things and to be more in tune with the needs of the domain.

Don’t be fooled to think that this is something that makes sense only for big enterprise projects. If the project is small, the code base will be small. It’s not so much overhead, as it is a different way of thinking.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store