

How to Produce a Rich Domain Model with Active Record
source link: https://kevinsmith.io/how-to-produce-a-rich-domain-model-with-active-record/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to Produce a Rich Domain Model with Active Record
You can't. It's not possible.
I know that sounds like an outrageous claim given the popularity of the Active Record pattern, but it's true.
Active Record provides complete access to a database row's fields through an object's public properties (or "attributes" of an "Active Record model", as they're called in both Ruby on Rails' and Laravel's ORMs). Any part of the codebase can access those attributes to read or change any of the data in the database row, making it easy to start working with a real database in your code.
The trouble starts when the complexity of the business inevitably reveals itself and you need to restrict the inherent permissiveness of Active Record to ensure that information is only retrieved or modified according to the rules of the business. In other words, you need a rich domain model: a layer of the codebase where the expressiveness of the business is encoded into a community of collaborating objects, each properly bounded and equipped with the information and behavior they need to model the relevant interactions and responsibilities of the business.
Need to make a property private so that only the object has access to it, a fundamental principle of software design called information hiding? It's not possible.
Need to require multiple pieces of information for an update and validate them before accepting the changes, like making sure you have both longitude and latitude before updating geo-coordinates? Sorry, you can't enforce that.
The best you can do is apply business rules in domain services that wrap the Active Record model, but you can't actually enforce the rules anywhere.1This is the critical, inescapable problem with using Active Record in the domain. Nothing is stopping the rest of the codebase (or worse, third-party packages) from bypassing your constraints to manipulate the data directly. And make no mistake, that will happen. The inevitable outcome is data corruption, inscrutable bugs, and feature development slowing to a crawl as you try to regain stability in your system.
By its very nature, Active Record's impact on a domain cannot be contained and thus will largely determine the resulting system architecture, despite whatever plans its developers may have at the outset. Given enough time under real-world dynamics, it will lead to a big ball of mud that becomes increasingly expensive to maintain.
Now you could try to contain Active Record to the edge of your application, only using it as a conduit between your database and domain objects that properly enforce the necessary constraints. This would keep it out of your domain and go a long way toward avoiding architectural distortion.
But in practice, this tends to be a fool's errand. The most popular Active Record implementations are clearly not meant to be confined to such a petty task. The documentation for Rails and Laravel both assume you'll be using it in the heart of your system and passing these Active Record models around to use everywhere. All the third-party packages assume the same. So do the creators of these frameworks, as do their developer communities. You'd be swimming against a mighty current, and nothing would prevent the "batteries included" features of these ecosystems from bypassing your domain entirely.
To put it plainly: Active Record fundamentally cannot allow the enforcement of constraints on its objects, leaving you with no option but to apply all your business rules in services and therefore "completely miss the point of what object-oriented design is all about" and "incur all of the costs of a [rich] domain model, without yielding any of the benefits".
Behold, the anemic domain model.
- This includes clever tooling in some Active Record implementations that will allow you to accept value objects to update multiple attributes. Nothing enforces that as the only way to update those attributes.↩
Recommend
-
19
-
8
Table of Contents Overview Provide the most minimal configuration required to allow a Linux node to join a Windows domain. Module Description This module is intended for the lazy Linux admin who wants their...
-
10
Domain Events over Active Record CallbacksHi, weʼre arkency 👋 Recently Marcin wrote an article about
-
5
CNBC Disruptor 50Blockbuster IPO day produces big gains for Uber, Delta Air Lines and tech VCsPublished Wed, Jun 30 20217:24 PM EDTUpdated Wed,...
-
8
supply and demand — Nintendo’s “OLED model” Switch estimated to cost just $10 more to produce Top-end model costs $50 more to buy; standard Switch price hasn't dropped in 4+ years....
-
6
RHEL 8 System to Active Directory (AD) domainQuestion: How do I join a CentOS 8 / RHEL 8 system to Windows Active Directory domain?. In this guide, we’ll discuss how to use realmd system to join a CentOS 8 /...
-
9
<?xml encoding="utf-8" ??>When you are setting up a new Active Directory forest and are trying to add a client to a domain, the following error may come up:
-
8
Produce, record and stream studio quality video contentDamn this is sick! I've been using Restream for a while and keep on telling them they need to implement scenes like in OBS! Seems Zudd...
-
4
US Seizes Z-Library Login Domain, But Secret URLs for Each User Remain Active ...
-
2
Active domain connection for this domain not found Something unexpected happened while accessing this website. It looks like it doesn't have an active
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK