Domain Driven Design
Domain Driven Design
Domain Driven Design advocates for organizing your code around how your business and its workflows are organized.
Wikipedia Page: https://en.wikipedia.org/wiki/Domain-driven_design
It's difficult to map domain driven design to a specific code implementation because it's a concept, not a software framework. However, important parts of the concept include:
An object with a unique identifier. Its attributes may change but the unique identifier lets us continue to acknowledge it as the same entity.
In Ruby on Rails, this could be an ActiveRecord model
create_table :pizzas do |t| t.uuid :uuid t.string :size t.expiration_date :datetime end class Pizza << ActiveRecord::Base end
In this case, the size and expiration_date may change but the uuid tells us it is the same object.
An object without a unique identifier whose attributes determine its value.
In Ruby on Rails, this could be a Money object
value_object_one = Money.new("USD", 10.10) # Currency, Magnitude value_object_two = Money.new("USD", 10.10) # Currency, Magnitude value_object_one == value_object_two # would return true
In this case, the combination of currency and magnitude determines what the object represents. Any two instances of the money class with the same attributes are equal.
An abstraction that guarantees the consistency of changes to a collection of entities.
In Ruby on Rails, this could be a custom class that exacts as an interface for making changes to multiple ActiveRecord models which need to be updated together.
class Order def place(opts) ActiveRecord::Base.transaction do if opts[:pizza] Pizza.create!(opts[:pizza]) end if opts[:soda] Soda.create!(opts[:soda]) end end end end
A service handles the use of aggregates. It's an interface into the domain logic of your codebase.
In Ruby on Rials, this could look like the following:
class OrdersController def create ProcessPayment.call(params) PlaceOrder.call(params) SendConfirmation.call(params) end end class PlaceOrder def self.call(opts) order = Order.new(opts) order.place end end
These are simple examples that cannot illustrate the full reasons why you would want to apply domain driven design to your codebase. In order to learn more, please see the following resources:
- Domain-Driven Design by Eric Evans
- Domain-Driven Design Distilled by Vaughn Vernon
- Implementing Domain-Driven Design by Vaughn Vernon
- RailsConf 2014 - Domain Driven Design and Hexagonal Architecture with Rails (https://www.youtube.com/watch?v=_rbF97T4480)