Modeling software with objects
A small notebook about object-oriented design: how to find the things a program is really about, draw them just enough, and write them down in Python.
01 Start from the domain
Good object models begin with the language of the problem, not with classes. Listen to how people describe their work: the nouns that keep coming back (an order, a shipment, an invoice) are candidates for objects, and the verbs hint at their responsibilities. A model that uses the same words as its users is easier to discuss, test and change.
02 UML as a sketch, not a contract
Class diagrams, sequence diagrams and state charts are most useful when they are quick. A few boxes on a whiteboard showing who owns what, and who talks to whom, will expose a confused design faster than a hundred pages of specification. Draw the part you are unsure about, argue over it, then throw the drawing away once the code says the same thing more precisely.
03 From diagram to Python
Python makes it cheap to turn a sketch into something you can run. Dataclasses cover simple value objects, small classes with clear methods cover behaviour, and protocols describe roles without forcing deep inheritance trees.
from dataclasses import dataclass, field
@dataclass
class Order:
number: str
lines: list["OrderLine"] = field(default_factory=list)
def total(self) -> float:
return sum(line.subtotal() for line in self.lines)
If the class reads like the diagram, the diagram has done its job.
04 Keeping models honest
Models drift. Prefer composition over inheritance, keep each object responsible for one idea, and let tests describe the behaviour you care about. When the code and the drawing disagree, trust the code and redraw.
More notes are being written. This page will grow into a set of short articles on domain modeling, design patterns and Python architecture.
Written by Nurlan Ergeshov, who builds AI products and still sketches boxes and arrows before writing code.