Mastering the Chain of Responsibility: From SOLID Principles to Spring Integration
This article explains the seven SOLID design principles, introduces the Chain of Responsibility pattern, demonstrates its application to a video‑review workflow with step‑by‑step Java code, and shows how to evolve the implementation from a basic chain to a Spring‑managed, fully open‑closed solution.
SOLID Principles (brief)
The Open‑Closed, Single Responsibility, Liskov Substitution, Dependency Inversion, Interface Segregation, Composite/Aggregate Reuse and Least Knowledge principles guide the design of extensible, maintainable code.
Chain of Responsibility (CoR) Pattern
CoR is a behavioral pattern that decouples a request sender from multiple potential handlers by linking handlers in a linear chain. A request traverses the chain until a handler processes it, allowing handlers to be added or removed without changing the sender.
Business Scenario: Video Review & Publication
A video passes through upload, transcoding, review and publishing stages. The review stage requires different processing logic depending on the upload source (e.g., "Fox Friend", "News", "Special Author"). The original code used a long series of nested if‑else statements, violating the Open‑Closed principle and making extensions error‑prone.
Step 1 – Basic CoR Implementation
public interface Handler {
void handle(Object videoInfo);
void setNext(Handler handler);
}
public class Handler1 implements Handler {
private Handler next;
@Override
public void handle(Object videoInfo) {
System.out.println("handler1处理");
if (next != null) next.handle(videoInfo);
}
@Override
public void setNext(Handler handler) { this.next = handler; }
}
public class Handler2 implements Handler { /* similar */ }
public class Handler3 implements Handler { /* similar */ }
public class Client {
public static void main(String[] args) {
Handler h1 = new Handler1();
Handler h2 = new Handler2();
Handler h3 = new Handler3();
h1.setNext(h2);
h2.setNext(h3);
h1.handle("videoInfo");
}
}This version works but each handler still holds a reference to the next handler, which breaches the Single Responsibility principle and forces the client to manage the chain.
Step 2 – Introducing a Chain Manager
public class HandlerChain {
private List<Handler> list = new ArrayList<>();
public void add(Handler handler) { list.add(handler); }
public void handle(Object videoInfo) { list.forEach(h -> h.handle(videoInfo)); }
}The client now only adds handlers to HandlerChain and invokes handle. The chain manager removes the need for each handler to store a next reference, reducing coupling. However, adding a new handler still requires modifying the manager.
Step 3 – Full Open‑Closed Solution with Spring
By declaring each handler as a Spring @Component and injecting the list of all Handler beans into the chain manager, the system becomes truly open‑closed: new handlers are discovered automatically without source changes.
@Component
public class Handler1 implements Handler {
@Override
public void handle(Object videoInfo) {
if (videoInfo.toString().contains("handler1")) {
System.out.println("handler1处理");
}
}
}
@Component
public class Handler2 implements Handler {
@Override
public void handle(Object videoInfo) {
System.out.println("handler2处理");
}
}
@Component
public class Handler3 implements Handler {
@Override
public void handle(Object videoInfo) {
System.out.println("handler3处理");
}
}
@Component
public class HandlerChain {
@Autowired
private List<Handler> list;
public void handle(Object videoInfo) { list.forEach(h -> h.handle(videoInfo)); }
}
@Component
public class Client {
@Autowired
private HandlerChain handlerChain;
public void handle(Object videoInfo) { handlerChain.handle(videoInfo); }
}Adding a new processing step now only requires creating a new Handler implementation and annotating it with @Component. The Spring IoC container wires it into the chain automatically, satisfying Open‑Closed, Single Responsibility and Dependency Inversion principles.
Key Takeaways
Replace large if‑else blocks with a CoR to decouple request routing from processing logic.
Extract chain orchestration into a dedicated manager to avoid each handler holding a reference to the next one.
Leverage Spring’s IoC container to achieve true open‑closed behavior: new handlers are added without modifying existing code.
The resulting architecture is easier to maintain, extend, and less prone to bugs introduced by manual chain manipulation.
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.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
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.
