oop

  • An enum case removed, and the stored values that remained

    A status removed from an enum, and eleven thousand rows still holding its value. Removing an enum case is a schema change disguised as a code change, and…

  • The command bus we removed

    A command bus introduced in 2021, and 88 commands with one handler each. A stack trace with four frames of dispatch before the work.

  • Equality on a type where identity was ambiguous

    A value object where two instances with the same fields might or might not be the same thing, and five years of nobody deciding. The ambiguity is in…

  • The exception I stopped catching

    A catch block added in 2021 for an error that has not occurred since, swallowing a different one. A catch of Throwable is a decision that every possible…

  • The value object library, five years on

    32 value objects in 2021, 41 now, and a retrospective on which of them earned their place. No symptom — a deliberate look.

  • A value object with no invariant, deleted

    Eight single-property wrappers over a string, none of which validated anything. A value object with no invariant is a type alias that PHP does not have, and the…

  • A readonly class that survived a requirements change

    A value object made readonly in 2022, and the requirement in 2026 that would have broken a mutable one. The property that mattered was not thread safety or…

  • A trait deleted after its second use appeared

    A trait extracted in 2023 for one class, on the grounds that a second would arrive, and the second one arriving and not fitting. A trait extracted in…

  • private(set) doing the work a hook was written for

    Three hooks reverted, and in every case asymmetric visibility was the whole answer. A get hook that returns a backing property unchanged is asymmetric visibility with extra syntax…

  • A year of property hooks, and the three I would not write again

    218 methods became properties in December 2024, and a year of living with a syntax that hides work.