Overview
I'm trying to learn about domain-driven design, and I'm about 80% of the way through Eric Evan's book on the subject (and about the same on the Pluralsight course). I've been attempting to apply what I've learnt in redesigning an old LabVIEW/TestStand project but I'm concerned about whether it's okay to have what I consider as the entities in it performing I/O logic, such as CAN/Modbus communication. The approach I'm taking now isn't very far from what I've done previously, and it's worked well for me so far so I'm fairly confident in it. However, I'd like to see if there's still room for improvement by viewing the development process from a DDD-perspective.
Beyond that, I'm hoping to just get validation on the approach I've taken in general. For that reason, this post will be a little long-winded - sorry in advance.
Background
This project is centered around performing automated tests of a certain brand of mechatronic (part of the transmission system of vehicles). I kicked off the project by collaborating with a colleague of mine who has less experience with object-oriented software development but a ton of expertise in automotive hardware testing. In this sense, he played the role of the domain expert. Using a whiteboard I modelled the test equipment and wrote down definitions of some of the terminology he used (these became part of the ubiquitous language):
As I started developing the project, I formalised this into a UML class diagram. The diagram below is the latest revision, slightly different from the first version due to an evolving understanding of the domain:
At the stage I'm at now, I have created most of the overall application architecture and implemented most of the logic. I've done the bulk of the code, leaving placeholders for my hardware-expert colleague to fill in with the actual hardware logic. We exchange back and forth using git, with my workstation being ideally suited for writing the bulk of the code and his for testing it against real hardware equipment (power supplies, motor drives, etc.). So far so good.
Typically, my approach to designing these applications is to create a LabVIEW "utility" library that models the test-rig and all the resources on it, and TestStand sequence files that make use of this library, performing a precedural sequence of steps like "Turn on power supply", "Set motor to 1000 RPM", "Measure pressures and check against limits", etc.
Looking at this from a DDD-perspective, it seems like the LabVIEW library constitutes the domain layer, while the TestStand sequence files constitutes the application layer, utilising and organising the classes in the library representing the domain to perform an actual test sequence that has value to our business. Furthermore, the VB test rig seems to serve as an aggregate root consisting of entities such as a power supply, a flow meter array, and so on.
Crux Of Problem
Here's where I'm a little unsure: Eric explains that entity classes should certainly contain behaviour appropriate to whatever it is they represent (to do otherwise would lead to an anemic domain model). Still, all the entity classes in his book (like Customer
or Account
) tend to have relatively "simple" behaviour - a Customer
class does not need to perform I/O, for example.
Is it appropriate for me to still think of power supply and flow meter array as entities (when they're clear parts of the domain and ubiquitous language) despite the fact that I implement ZPL Power Supply
with serial communication, and DAQ Flow Meter Array
with data acquisition logic?
Additionally: have I suitably applied DDD principles, or is there room for improvement? Is DDD even appropriate to a project like this?