The Heart of the Matter: Domain Models in models.py
[home]
The Developer's Diary
The Heart of the Matter: Defining our Domain with models.py
From composing our app to keeping its secrets, we now define the very concepts it works with.
We've set the stage with main.py
as our assembler and config.py
as our secret keeper. Now, we get to the core of our SpLD assessment application: the Domain Model. This is where we define the fundamental concepts and data structures that our application is all about. The home for these definitions is app/core/models.py
.
More Than Just Data: Defining a Language
At first glance, the classes in models.py
might look like simple containers for data. But their role is much deeper. They form the vocabulary of our application—a clear, explicit, and shared language that developers can use to reason about the system. This is a core idea from a software design approach called Domain-Driven Design (DDD).
Novice Coder (NC): "So... these are just classes with variables? Why not just pass dictionaries around? They're so much more flexible if I need to add a new field."
Experienced Coder (IC): "That 'flexibility' is a trap that leads to runtime KeyError
exceptions and code that's impossible to reason about. Here, we're defining our Domain Model. Using Python's dataclasses
gives us type hints, auto-generated __init__
and __repr__
, and a clear, explicit contract. These aren't just data bags; they are Entities (if they have a unique identity) or Value Objects (if they're defined by their attributes, like a `Color`). This creates a Ubiquitous Language—a core concept from Domain-Driven Design (DDD)—so when we say `Client`, we mean this specific object, not some arbitrary dictionary."
By defining a Client
class, we create a contract. Any part of our code that works with a `Client` knows exactly what to expect: it will have a name, a date of birth, and so on. This eliminates guesswork and prevents a whole class of bugs that arise from inconsistent data structures.
Our Hypothetical models.py
For our SpLD app, we can start by modeling the key entity: the client being assessed. We'll use Python's built-in dataclasses
module to make this clean and efficient.
# app/core/models.py
from dataclasses import dataclass
from datetime import date
from typing import Optional, List
@dataclass
class Client:
"""
Represents a client undergoing an SpLD assessment.
This is an ENTITY, as it has a unique identity (client_id).
"""
client_id: int
first_name: str
last_name: str
date_of_birth: date
# Optional field for notes from the psychologist
notes: Optional[str] = None
@dataclass
class Assessment:
"""
Represents a single assessment session for a client.
This is also an ENTITY.
"""
assessment_id: int
client_id: int
assessment_date: date
report_summary: Optional[str] = None
hypotheses: List[str] = None # Key hypotheses driven from history
Breaking it down:
from dataclasses import dataclass
: The@dataclass
decorator is a powerful tool. It automatically generates methods like__init__
,__repr__
, and__eq__
for us based on the class attributes we define. This saves a lot of boilerplate code.- Type Hinting: We use type hints (e.g.,
first_name: str
,assessment_date: date
). This makes our code self-documenting and allows static analysis tools to catch potential bugs before we even run the code. - Entities: Both
Client
andAssessment
are Entities because they have a unique identifier (client_id
andassessment_id
, respectively). Two `Client` objects could have the same name and birthdate, but their `client_id` makes them unique individuals in our system. Optional
andList
: We use types from thetyping
module to be explicit about our data.Optional[str]
means the `notes` field can be either a string or `None`.List[str]
clearly indicates that `hypotheses` is a list of strings.
By defining these models, we've created the central vocabulary for our application. When a developer sees a `Client` object, they know precisely what it is and what it contains. This clarity is the essence of clean architecture and will be invaluable as we build out our services and UI components.
Comments
Post a Comment