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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Shepherd Advanced Notes
Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
