Interview Prep Zoneby CuriouserLabs

Question 4 of 5 · senior level

Which GoF patterns live inside the JDK and Spring — and when do patterns become anti-patterns?

🎤 Say this first

The platform is a pattern museum: Builder (StringBuilder, HttpRequest.newBuilder), Factory Method (List.of, Executors.new*), Strategy (Comparator), Observer (listeners, PropertyChangeListener), Decorator (BufferedInputStream wrapping streams), Adapter (Arrays.asList), Template Method (AbstractList), Proxy (dynamic proxies — Spring AOP's heart), Singleton (enum idiom, Spring's scope), Chain of Responsibility (servlet filters). Patterns rot into anti-patterns when applied speculatively: the value is a shared vocabulary and proven force-resolutions — not class-count.

The full picture

PatternIn the wildThe force it resolves
BuilderHttpRequest.newBuilder()…build()Many optional params, immutability at the end
StrategyComparator, RejectedExecutionHandlerBehavior varies independently of host
Decoratornew GZIPInputStream(new BufferedInputStream(in))Stackable capabilities without subclass explosion
ProxyJDK dynamic proxy / CGLIB — @TransactionalCross-cutting interception behind the same interface
ObserverApplicationEvents, Flow APIDecoupled notification, N listeners
Template MethodAbstractStringBuilder, JdbcTemplate*Fixed algorithm, variable steps (*JdbcTemplate is really Strategy-via-lambda)

Anti-pattern signals a lead should call out: pattern-first design (interfaces + factories before a second implementation exists), Singleton-as-global-state (hidden coupling, test pain — DI containers made it obsolete), deep inheritance where Strategy/Decorator composition would do, and 'pattern name as documentation' where a lambda suffices. Post-Java 8, many GoF patterns compress dramatically: Strategy is a Function, Command is a Runnable, Observer is a listener lambda — the forces remain, the ceremony shouldn't.

🔄 Likely follow-up questions

  • Why is the enum singleton the recommended form — what attacks does it survive? (serialization, reflection)
  • Show how a GoF pattern collapses into a lambda and what's lost/gained.
  • Which pattern does Spring's BeanPostProcessor mechanism embody?