Reading Data Classes
DTO, POJO, record, struct — understanding data-only classes across languages
Data class vocabulary
- DTO — Data Transfer Object; carries data between layers; no business logic
- POJO — Plain Old Java Object; simple class with fields + getters/setters
- Record (Java/Kotlin) — immutable; auto-generates constructor, equals, hashCode, toString
- Struct (Go/C) — composite type with named fields; struct tags control serialization
- frozen=True (@dataclass) — immutable Python dataclass; raises error on field assignment
Question 0 of 5
A Python codebase uses: @dataclass
class UserDTO:
id: int
name: str
email: str
What does "DTO" stand for and what is its purpose?
Data Transfer Object — carries data between layers, no business logic. Data class vocabulary:
- DTO (Data Transfer Object) — simple data container; used to pass data between API layer, service layer, database layer; no methods beyond accessors
- POJO (Plain Old Java Object) — Java equivalent; a simple class with fields, getters, setters, no framework dependencies
- Record — immutable data class in Java 16+ and Kotlin; generates equals(), hashCode(), toString() automatically
- Struct — in Go and C; a composite data type with named fields; no methods (Go structs can have methods)
What is the difference between a "mutable" and "immutable" data class?
Mutable = fields can change after creation; immutable = state fixed at construction. Immutability vocabulary:
- Immutable — cannot be modified after construction; thread-safe by default; safer to pass around
- frozen=True in Python @dataclass — makes fields read-only (raises FrozenInstanceError on assignment)
- record in Java — immutable by default;
record Point(int x, int y) {}generates a final class - val vs var in Kotlin —
val= immutable field;var= mutable field - const / readonly — language-specific immutability keywords
A Go codebase defines: type CreateOrderRequest struct {
UserID int `json:"user_id"`
Items []string `json:"items"`
Total float64 `json:"total"`
}
What do the backtick annotations (struct tags) do?
Struct tags provide serialization metadata — json:"user_id" controls the JSON key name. Go struct tag vocabulary:
json:"user_id"— JSON key for encoding/decoding; camelCase vs snake_case mappingjson:"field,omitempty"— omit the field from JSON output if it is the zero valuejson:"-"— never include this field in JSON outputdb:"user_id"— used by database libraries (sqlx, GORM) to map struct fields to column namesvalidate:"required,email"— used by validation libraries (go-playground/validator)
In a Java codebase, you see: public record Point(double x, double y) {}. How does a record differ from a regular class?
Immutable data class with auto-generated constructor, equals, hashCode, toString. Java record vocabulary:
- Components — the fields declared in the record header:
(double x, double y) - Auto-generated: canonical constructor, getters (x(), y()), equals(), hashCode(), toString()
- Immutable — fields are final; no setters
- Compact constructor — can add validation without repeating assignments:
record Point(double x, double y) { Point { if (x < 0) throw new IllegalArgumentException(); } }
A code review comment says: "This class has business logic — it should not be a DTO." What does this mean?
DTOs are pure data containers; business logic belongs in service/domain layers. Layered architecture vocabulary:
- DTO — carries data; no logic beyond simple data access; crosses layer boundaries
- Domain model / entity — has business rules, invariants, state transitions; belongs in the domain layer
- Service — orchestrates business logic; uses domain models and repositories
class OrderDTO { calculateDiscount() { ... } } — calculateDiscount is business logic. It should live in an Order domain object or OrderService, not in a DTO used just to carry API request/response data. Code review phrase: "Move calculateDiscount() to the Order domain class. The DTO should only carry the field values to and from the API."