Week 017 — The DTO Constructor Problem

Building the pattern is straightforward until you hit the object with twenty fields.

Week of March 10, 2025

Progress

Deep in the DTO/Service/Repository refactor. The week was spent building the constructor for the ItemDTO class and working through how it should behave. Classes were separated into their own files with proper namespacing. The service class skeleton was created. The autoloader was set up.

By Friday, LostItemDTO had a constructor that accepts nullable fields with optional parameters, and the old inline class code had been stripped out of api-item.php.

The Hard Part

The ItemDTO constructor is a design problem. The item has a large number of fields — name, image path, owner ID, status, QR code, reward amount, lost instance ID, and more. Not all of these are available at every point in the object's lifecycle. A new item being created won't have a lost instance ID. An update might not include a new image path. A found item has fields that a safe item doesn't.

The naive approach is a long list of parameters with most of them optional, which produces a constructor that's hard to call correctly and hard to read. Named parameters were considered. Immutability was appealing — creating a new object rather than mutating an existing one — but awkward given how the code currently works.

The initial landing: default-value handling belongs in the constructor, with nulls allowed for truly optional fields. Then it was amended: actually, the service layer should handle defaults, keeping the DTO a pure data container with no business logic. The right answer shifted during the week.

Decision Made

DTOs should be pure data containers — no logic, no default-value assignment. The service layer is responsible for applying business logic and constructing DTOs with the right values. This keeps the DTO's intent clear and makes the service layer the single place where business decisions live.

The initial instinct to put defaults in the constructor was corrected mid-week. Worth noting: being wrong for a few days before arriving at the right answer is normal. The important part is writing it down so it doesn't have to be figured out again.

Next Week

Getting the autoloader working and using the new class structure through the full item save flow.