Created by Stan on 07-04-2023
Domain-Driven Design is a thrilling ride filled with magical concepts and endless possibilities. We'll use a simple online bookstore domain as an example. By embracing DDD as your trusty guidebook and incorporating patterns like the Repository Pattern, you can explore complex software with confidence, creating flexible, scalable, and maintainable software systems that accurately represent the relevant business logic.
For our purposes, we'll build a simple bookstore. We will design the models as shown in the YML diagram below. The Author, Book, and Price classes are represented with their attributes and methods. The relationships between these classes are shown with associations: An Author is associated with zero or more Books, while each Book is associated with exactly one Author and one Price.
We will create an Author entity, a Book entity, and a Price value object.
# author.rb class Author attr_reader :id, :name def initialize(id, name) @id = id @name = name end end # book.rb class Book attr_reader :id, :title, :author, :price def initialize(id, title, author, price) @id = id @title = title @author = author @price = price end end # price.rb class Price attr_reader :amount, :currency def initialize(amount, currency) @amount = amount @currency = currency end def ==(other) other.is_a?(Price) && amount == other.amount && currency == other.currency end end
Now, let's implement the Repository Pattern to handle storage and retrieval of Book entities. We'll create an interface for the BookRepository
and an implementation of the repository interface.
#book_repository.rb module BookRepository def all; end def find_by_id(id); end def add(book); end def remove(book); end end # book_repository_impl.rb require_relative 'book_repository' class BookRepositoryImpl include BookRepository def initialize @books = [] end def all @books end def find_by_id(id) @books.find { |book| book.id == id } end def add(book) @books << book end def remove(book) @books.delete(book) end end
With the BookRepositoryImpl
, we can now store and retrieve Book
entities:
# client.rb require_relative 'author' require_relative 'price' require_relative 'book' require_relative 'book_repository_impl' # Creating some sample data author = Author.new(1, 'J.K. Rowling') price = Price.new(10.99, 'USD') book = Book.new(1, 'Harry Potter and the Philosopher\'s Stone', author, price) # Using the InMemoryBookRepository repository = BookRepositoryImpl.new repository.add(book) puts repository.all.inspect # => [#<Book:0x00005607c9a9e990 @id=1, @title="Harry Potter and the Philosopher's Stone", @author=#<Author:0x00005607c9a9e9b8 @id=1, @name="J.K. Rowling">, @price=#<Price:0x00005607c9a9e9e0 @amount=10.99, @currency="USD">>] found_book = repository.find_by_id(1) puts found_book.inspect # => #<Book:0x00005607c9a9e990 @id=1, @title="Harry Potter and the Philosopher's Stone", @author=#<Author:0x00005607c9a9e9b8 repository.remove(book) puts repository.all.inspect # => []
In a real-world application, you might implement additional repositories, such as a DatabaseBookRepository
, to interact with a database or another storage system. This separation of concerns allows you to swap out different implementations of the repository without affecting the rest of your application.
The Repository Pattern provides a clean and maintainable way to manage the storage and retrieval of domain entities. It abstracts the data storage mechanism from the domain logic, making it easier to adapt to changes in storage requirements and promoting a modular and well-structured codebase.
By embracing DDD as your trusty guidebook and incorporating patterns like the Repository Pattern, you can explore complex software kingdoms with confidence, creating flexible, scalable, and maintainable software systems that accurately represent the diverse realms and their inhabitants. As you embark on your DDD journey, remember to collaborate closely with domain experts, forge a shared understanding of the realms, and utilize the mighty building blocks of DDD to conquer the challenges ahead.
Architecture
Posted on 08 Apr, 2023Architecture
Posted on 08 Apr, 2023Architecture
Posted on 10 Apr, 2023