Mastering the Chain of Responsibility: Refactor Video Processing with SOLID Principles
This article demonstrates how to apply the Chain of Responsibility design pattern together with SOLID principles to refactor a video upload, transcoding, review and publishing workflow, providing clear Java examples, UML diagrams, and Spring integration for a maintainable, extensible solution.
Introduction
This article explains how to apply the Chain of Responsibility design pattern together with SOLID principles to refactor a video‑upload, transcoding, review and publishing workflow.
SOLID Principles
Open/Closed Principle (OCP) : extend behavior by adding new classes instead of modifying existing code.
Single Responsibility Principle (SRP) : each class or method should have only one reason to change.
Liskov Substitution Principle (LSP) : objects of a superclass must be replaceable with objects of a subclass.
Dependency Inversion Principle (DIP) : high‑level modules should depend on abstractions, not concrete implementations.
Interface Segregation Principle (ISP) : keep interfaces small and focused.
Composite/Aggregate Reuse Principle (CARP) : prefer composition/aggregation over inheritance.
Least Knowledge Principle / Law of Demeter (LKP/LOD) : limit knowledge of other objects.
Chain of Responsibility Pattern
The pattern decouples request senders from multiple handlers by linking handlers in a chain. A request travels the chain until a handler processes it.
In the video‑processing scenario the request passes through stages such as upload, transcoding, review and publishing.
Initial Naïve Implementation
Business logic was written as a series of nested if‑else statements, violating the Open/Closed Principle and making the code hard to extend.
if (videoInfo.getUploadFrom().equals("狐友") || videoInfo.getUploadFrom().equals("新闻")) {
// ...
} else {
// ...
}
if (videoInfo.getUploadFrom().equals("特邀作者上传") || videoInfo.getUploadFrom().equals("抓取来源")) {
// ...
} else {
// ...
}
// many more if‑else branches ...Basic Refactor Using Chain of Responsibility
Define a Handler interface with handle(Object videoInfo) and setNext(Handler). Implement three concrete handlers and a client that manually links them.
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 {
private Handler next;
@Override
public void handle(Object videoInfo) {
System.out.println("handler2处理");
if (next != null) {
next.handle(videoInfo);
}
}
@Override
public void setNext(Handler handler) {
this.next = handler;
}
} public class Handler3 implements Handler {
private Handler next;
@Override
public void handle(Object videoInfo) {
System.out.println("handler3处理");
if (next != null) {
next.handle(videoInfo);
}
}
@Override
public void setNext(Handler handler) {
this.next = handler;
}
} public class Client {
public static void main(String[] args) {
Handler handler1 = new Handler1();
Handler handler2 = new Handler2();
Handler handler3 = new Handler3();
handler1.setNext(handler2);
handler2.setNext(handler3);
handler1.handle("videoInfo");
}
}Advanced Refactor – HandlerChain
Introduce a HandlerChain that stores handlers in a list and iterates over them, removing the need for each handler to keep a reference to the next one.
public class HandlerChain {
private List<Handler> list = new ArrayList<>();
public void add(Handler handler) {
this.list.add(handler);
}
public void handle(Object videoInfo) {
list.forEach(handler -> handler.handle(videoInfo));
}
}Spring Integration
Mark handlers and the chain with @Component and inject the list of Handler beans using @Autowired. This achieves full compliance with the Open/Closed Principle because new handlers are discovered automatically.
@Component
public class Handler1 implements Handler {
@Override
public void handle(Object videoInfo) {
if (videoInfo.toString().contains("handler1")) {
System.out.println("handler1处理");
}
}
} @Component
public class HandlerChain {
@Autowired
private List<Handler> list;
public void handle(Object videoInfo) {
list.forEach(handler -> handler.handle(videoInfo));
}
} @Component
public class Client {
@Autowired
private HandlerChain handlerChain;
public void handle(Object videoInfo) {
handlerChain.handle(videoInfo);
}
}Conclusion
By applying the Chain of Responsibility pattern and adhering to SOLID principles, the video‑review and publishing workflow becomes modular, extensible, and easier to maintain, reducing the risk of bugs when new processing steps are added.
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.
