Static memberseasy0-2 years

A teammate asks why the codebase prefers `Money.of(500, EUR)` over `new Money(500, EUR)` everywhere, calling it "just a style preference." Is it?

No — a static factory can do several things a constructor structurally cannot, and "style" undersells all of them. A constructor must return a new instance of exactly the class it's declared on, every time, with no exceptions; a factory method is an ordinary method, so it can return a cached instance instead of allocating (Money.ZERO), it can return a different concrete subtype depending on the arguments while the caller only sees the interface (the way List.of() picks a different implementation class for zero, one, two or many elements), and it can refuse to produce anything at all by returning Optional.empty() rather than being forced to either construct something or throw. A constructor can do none of those three things by its nature — it always allocates, always returns exactly its own type, and can only refuse by throwing.

The lesson behind it →
More on Static members