Fundamentals 13 min read

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.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Mastering the Chain of Responsibility: Refactor Video Processing with SOLID Principles

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.

Chain of Responsibilitydesign-patternsJavaSpringrefactoringVideo processingSOLID
Sohu Tech Products
Written by

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.

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.