Fundamentals 26 min read

A 20,000‑Word Deep Dive into 9 Overused Design Patterns in Real‑World Code

This article reviews nine widely used design patterns—Singleton, Builder, Factory, Strategy, Template Method, Chain of Responsibility, Proxy, Adapter, and Observer—explaining their concepts, common implementations in open‑source projects such as Spring, Dubbo, MyBatis, and providing concrete code examples and visual diagrams to help readers understand and apply them when reading source code.

Shepherd Advanced Notes
Shepherd Advanced Notes
Shepherd Advanced Notes
A 20,000‑Word Deep Dive into 9 Overused Design Patterns in Real‑World Code

Singleton Pattern

The Singleton pattern ensures a class has only one instance per process. Two main implementations dominate open‑source projects: a static constant (eager initialization) used in Spring’s AnnotationBeanNameGenerator, and double‑checked locking (lazy initialization) illustrated with a volatile INSTANCE field and synchronized block. The article explains the purpose of the outer null check (reduce synchronization), the inner null check (prevent duplicate creation), and the volatile keyword (avoid reordering that could expose a partially constructed object).

It also shows Dubbo’s SPI mechanism using double‑checked locking to guarantee a singleton instance.

Builder Pattern

The Builder pattern separates complex object construction from its representation, allowing step‑by‑step creation. An example creates a PersonDTO via PersonDTO.builder(). The pattern is used in Spring’s BeanDefinitionBuilder, Guava’s CacheBuilder, and JDK’s StringBuilder. A reference link to a tutorial is provided.

Factory Pattern

Factory patterns abstract object creation. Three variants are covered:

Simple Factory – a static method creates objects based on a type string (e.g., SimpleAnimalFactory for Cat and Dog).

Factory Method – introduces an interface ( AnimalFactory) and concrete factories ( CatFactory, DogFactory) to obey the Open‑Closed Principle.

Abstract Factory – extends the idea to families of products, adding a Food product to the animal example.

Real‑world usages include MyBatis’s SqlSessionFactory, Spring’s BeanFactory, and the BeanDefinitionBuilder mentioned earlier.

Strategy Pattern

Strategy encapsulates interchangeable algorithms. The article contrasts a naïve if‑else notification implementation with a strategy interface MessageNotifier and concrete strategies for SMS and app notifications. It demonstrates Spring MVC’s use of HandlerMethodArgumentResolver and HandlerMethodReturnValueHandler, Dubbo’s SPI, and Spring Boot’s property source loading as strategy applications.

Template Method Pattern

Template Method defines a fixed algorithm skeleton in a superclass while allowing subclasses to override specific steps. A travel‑planning example illustrates abstract methods for planning, packing, traveling, playing, and returning. Real‑world examples include HashMap ’s afterNodeInsertion hook (overridden by LinkedHashMap), Spring’s AbstractApplicationContext.refresh() with onRefresh, and MyBatis’s BaseExecutor and doQuery abstract methods.

Chain of Responsibility Pattern

Responsibility chains pass a request along linked handlers until one handles it. The article provides a generic ApprovalHandler abstract class, concrete handlers for group leader, director, and HR approvals, and a Spring component assembling the chain. It also shows the pattern in Spring MVC’s HandlerInterceptor, Sentinel’s slot chain, and other frameworks.

Proxy Pattern

Proxy adds behavior without modifying the original class. An example wraps PersonServiceImpl with PersonServiceProxy to log parameters. The article notes MyBatis’s CachingExecutor as a proxy that adds second‑level caching while delegating to a SimpleExecutor, and mentions Spring AOP as a dynamic proxy variant.

Adapter Pattern

Adapter converts one interface to another. A real‑world analogy (USB‑C to Micro‑USB charger) is followed by code: USBTypeC, MicroUSB, and two adapter implementations (composition and inheritance). The pattern is used in MyBatis’s logging abstraction, where LogFactory returns a concrete logger (e.g., Slf4jLoggerImpl) matching the project’s logging framework.

Observer Pattern

Observer decouples one‑to‑many relationships. The article explains the concept with a fire‑alert analogy, then shows Spring’s event system: ApplicationListener implementations are registered in ApplicationEventMulticaster, which dispatches events to listeners.

Conclusion

The article summarizes the nine patterns, emphasizes their frequent appearance in source code and everyday development, and encourages readers to apply them judiciously based on concrete scenarios.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Chain of ResponsibilityDesign PatternsproxyTemplate MethodSingletonAdapterStrategyFactoryObserverBuilder
Shepherd Advanced Notes
Written by

Shepherd Advanced Notes

Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.