← Graph

Doctrine of Useful Objects Separate Fact from Fiction in OOD

talk 27 connections

Scott Bellware's wroclove.rb 2023 talk. Opens with Rogers' adoption curve and Moore's 'crossing the chasm' to frame why OO knowledge doesn't propagate from innovators/early adopters to the Rails majority — and provocatively claims 'Active Record objects are data structures built in an object-oriented language', not OO code, so most Rails developers haven't actually learned OO. Introduces the design fundamentals: afferent (inbound) vs efferent (outbound) coupling; generalization vs specialization; mapping these onto a 2x2 where the happy quadrants are afferent+general (e.g. BasicObject/Kernel) and efferent+special (controllers), and the sad ones are the inversions. Uses this to prove 'fat model, skinny controller' is one of the most fundamental mistakes in Rails design — model objects are highly afferent, so piling controller-specific business code onto them maximises blast radius; the root cause is that Rails controllers historically couldn't be tested, so TDD 'was never born' in Rails. Covers single-purpose objects and 'tell don't ask' as expressions of encapsulation, and introduces the Doctrine of Useful Objects: an object must be usable immediately after instantiation without nil-reference errors; initializers are primitive (only accept and record primitives); no IoC containers; no test doubles like mocks/stubs/spies ('toxic masculinity as a design methodology'); prefer telemetry. Walks through a SignUp class + HTTPClient example across multiple refactors: first injecting the HTTP client, then turning it into a null-coalescing attribute defaulted to a `Mimic` (Eventide's null-object generator that implements an interface inertly — invoking Liskov substitutability), then replacing the hand-rolled attribute with the `dependency` macro and defining a `Substitute` module that exposes domain telemetry (e.g. `http_client.posted?(content)`). Splits convenience from mechanical correctness by pairing a primitive initializer with a class-level `build` factory/constructor — the initializer yields a diagnostic-ready instance (mimic deps), the constructor wires real operational dependencies. Closes with Rails guidance: 'give unto Rails that which is Rails', keep business logic in `lib/`, put a `lib/model/` directory of callable objects encapsulating database operations, rename `app/models` to `app/data` and scaffold only (no callbacks, no extra code) to prevent afferent surface area from growing like Velcro. Q&A covers: how to set return values on diagnostic substitutes (specialise the substitute module, don't reach for mocks); whether this is effectively a spy (same spirit but architecturally different — designed-in telemetry vs retrofitted transparency in test files); and why class-internal dependency configuration beats external IoC/Rails configuration (a class should configure its own operational dependencies).

date
2023-03-31
type
talk
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Useful Objects concept
The talk teaches the Doctrine of Useful Objects.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Uses afferent coupling as one of the two coupling directions in the design-quadrant analysis.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Uses efferent coupling as the outbound counterpart to afference.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Introduces this classical OO metric as the grid underlying the happy/sad design quadrants.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Opens by using the chasm to explain why OO knowledge rarely reaches the Rails majority.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Frames the talk with Rogers' diffusion curve and the observation that ~70% of any population sits in the middle.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Tell Don't Ask concept
Presents tell-don't-ask as an expression of encapsulation that reduces afferent coupling.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Explains single-purpose objects as one of the design fundamentals, reframed as 'managing change'.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Justifies defaulting dependencies to inert substitutes by appealing to LSP ('is substitutable for').
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Identifies Mimic substitutes as an implementation of the null-object pattern.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Introduces diagnostic substitutes as the preferred alternative to mocks/stubs/spies in tests.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Walks through replacing a nil dependency with a null-coalescing attribute that defaults to a substitute.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Final refactor pairs a primitive initializer with a class-level `build` constructor to separate convenience from mechanical correctness.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Mimic tool
Demonstrates Eventide's Mimic library to build inert substitutes from a class's interface.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Dependency tool
Replaces the hand-written null-coalescing attribute with the `dependency` macro from Eventide's Dependency library.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Uses Eventide's Initializer macro to enforce primitive initializers that only record values.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Argues, using the distance-from-main-sequence quadrants, that fat-model-skinny-controller is a fundamental Rails design mistake.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Argues TDD was never truly adopted in Rails because controllers weren't testable, and that applying TDD would have prevented the fat-model pattern.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
about
Large parts of the talk and its Q&A focus on Rails-specific consequences and guidance.
asked_at
Doctrine of Useful Objects Separate Fact from Fiction in OOD talk
Audience question during the talk's Q&A.
asked_at
Doctrine of Useful Objects Separate Fact from Fiction in OOD talk
Audience question during the talk's Q&A.
authored
Doctrine of Useful Objects Separate Fact from Fiction in OOD talk
Bellware delivered this talk at wroclove.rb 2023.
from_talk
Doctrine of Useful Objects Separate Fact from Fiction in OOD talk
Extracted from Bellware's analysis of the design quadrants in the talk.
from_talk
Doctrine of Useful Objects Separate Fact from Fiction in OOD talk
Recommendation from the Rails-specific guidance section of the talk.
from_talk
Doctrine of Useful Objects Separate Fact from Fiction in OOD talk
Advice given near the end of the talk on Rails folder structure.
from_talk
Doctrine of Useful Objects Separate Fact from Fiction in OOD talk
Stated in the Q&A exchange about IoC containers and Rails configuration.
talk Doctrine of Useful Objects Separate Fact from Fiction in OOD
presented_at
Single-speaker talk delivered at the 2023 edition of wroclove.rb.

Provenance

Created
2026-04-17 16:17 seed
Read by
25 extractions