Rethinking Java Design Patterns: From OOP to FP
Nicolas Duminil, published at DZone with permission from the author. It takes five Gang-of-Four patterns and rewrites each one in functional Java, arguing against the usual functional-programming answer to “how do I combine this with my object-oriented code” — which he characterizes, via Feynman’s turtles, as “just do functional all the way down.” The article’s position is that a systematic mapping is more useful than a conversion.
The two worked examples that carry the argument:
- Factory. The object-oriented version is a
ProductFactory.newProduct(...)switching on aProductTypeenum to pick a constructor. The functional version moves the factory onto the enum constant as a constructor reference —ELECTRONIC(ElectronicProduct::new)— so the enum holds a function field, and adding a product forces adding its factory. The switch statement disappears. - Visitor. The functional version seals the hierarchy (
sealed interface Product permits ...) and makes an operation a plainFunction<Product, R>built on aswitchthat deconstructs records. Because the type is sealed, the compiler proves the switch exhaustive: nodefaultbranch, no double dispatch, noacceptmethod.
Builder, Decorator and Strategy get the same treatment, and the article closes with the project structure.
T3 — a practitioner article on a syndication site, no review, no measurement. Its value is the worked transformation, which is checkable by reading it; nothing in it is a claim about outcomes.
Why it sits in this spoke
It is the corpus’s only source that is about program design rather than about a language, and it is
the one that connects the others: what it demonstrates is that a pattern is a function of the language’s
feature set (design-patterns). The features doing the work — lambdas, constructor references, sealed
types, records, pattern matching in switch — arrived in Java over roughly a decade, and each one
retired a piece of ceremony that a pattern existed to organize.
Read against clojure, the article is describing a destination that language started at, since functions have always been values there. Read against c, it does not apply at all. That range is the point: the patterns you need are the ones your language will not give you.
Related
design-patterns · programming-language · clojure · synthesis