单一职责原则(设计模式)

目录

问题:

定义:

解决:

[方式 1:使用策略模式](#方式 1:使用策略模式)

示例:用户管理

[方式 2:使用装饰者模式](#方式 2:使用装饰者模式)

示例:用户操作

[方式 3:使用责任链模式](#方式 3:使用责任链模式)

示例:用户操作链

总结

推荐


问题:

今天刷面经的时候,发现不理解单一职责原则,特此记录。

定义:

单一职责原则:一个模块或类只完成一个功能。

那可以想一想,引起类变化的原因有哪些呢?

总结下来,只有2种

  • 添加
  • 修改

如果我们可以,将"添加"和"修改"分开,那么这个类也就完成了单一职责原则

建议先了解一下 委托者模式,因为下面几个设计模式核心都是委托者模式。

解决:

在 Java 开发中,如果你想 将"引起一个类的变更的原因"进行拆分 ,通常需要遵循单一职责原则 ,让修改 (Modify)和添加(Add)两个操作独立,不相互影响。

可以用 策略模式、装饰者模式、责任链模式、组合模式 等方式来实现。下面是几种常见的方式:


方式 1:使用策略模式

如果修改和添加是两种不同的操作,可以用策略模式拆分,让它们各自处理自己的逻辑。

示例:用户管理

java 复制代码
// 定义通用策略接口
public interface UserOperationStrategy {
    void execute(User user);
}

// 修改策略
public class ModifyUserStrategy implements UserOperationStrategy {
    @Override
    public void execute(User user) {
        System.out.println("修改用户信息: " + user.getName());
    }
}

// 添加策略
public class AddUserStrategy implements UserOperationStrategy {
    @Override
    public void execute(User user) {
        System.out.println("添加新用户: " + user.getName());
    }
}

// 上下文类,动态选择操作
public class UserService {
    private UserOperationStrategy strategy;

    public void setStrategy(UserOperationStrategy strategy) {
        this.strategy = strategy;
    }

    public void executeOperation(User user) {
        strategy.execute(user);
    }
}

// 使用策略
public class Main {
    public static void main(String[] args) {
        User user = new User("Tom");

        UserService userService = new UserService();

        // 进行添加操作
        userService.setStrategy(new AddUserStrategy());
        userService.executeOperation(user);

        // 进行修改操作
        userService.setStrategy(new ModifyUserStrategy());
        userService.executeOperation(user);
    }
}

优点

  • 让"修改"和"添加"逻辑完全解耦,互不影响。
  • 方便扩展,比如再加一个"删除用户"策略。

方式 2:使用装饰者模式

如果修改和添加可以叠加 ,可以使用装饰者模式,在原功能基础上动态增加额外行为,而不改变原类的代码。

示例:用户操作

java 复制代码
// 定义基础接口
public interface UserOperation {
    void execute();
}

// 基础实现(原始功能)
public class BaseUserOperation implements UserOperation {
    @Override
    public void execute() {
        System.out.println("基础用户操作");
    }
}

// 装饰器基类
public abstract class UserOperationDecorator implements UserOperation {
    protected UserOperation decoratedOperation;

    public UserOperationDecorator(UserOperation decoratedOperation) {
        this.decoratedOperation = decoratedOperation;
    }

    @Override
    public void execute() {
        decoratedOperation.execute();
    }
}

// 添加用户功能
public class AddUserDecorator extends UserOperationDecorator {
    public AddUserDecorator(UserOperation decoratedOperation) {
        super(decoratedOperation);
    }

    @Override
    public void execute() {
        super.execute();
        System.out.println("添加用户");
    }
}

// 修改用户功能
public class ModifyUserDecorator extends UserOperationDecorator {
    public ModifyUserDecorator(UserOperation decoratedOperation) {
        super(decoratedOperation);
    }

    @Override
    public void execute() {
        super.execute();
        System.out.println("修改用户");
    }
}

// 使用装饰器
public class Main {
    public static void main(String[] args) {
        UserOperation operation = new BaseUserOperation();
        
        // 先添加,再修改
        UserOperation addThenModify = new ModifyUserDecorator(new AddUserDecorator(operation));
        addThenModify.execute();
    }
}

输出

复制代码
基础用户操作
添加用户
修改用户

优点

  • 动态组合行为,比如 先添加再修改 或者 只修改不添加
  • 方便扩展,不用修改原类。

方式 3:使用责任链模式

如果修改和添加是流程中的不同步骤,可以用责任链模式,让不同操作按顺序执行,方便扩展。

示例:用户操作链

javascript 复制代码
// 责任链接口
public interface UserHandler {
    void handle(User user);
}

// 责任链基类
public abstract class AbstractUserHandler implements UserHandler {
    protected UserHandler nextHandler;

    public void setNextHandler(UserHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handle(User user) {
        if (nextHandler != null) {
            nextHandler.handle(user);
        }
    }
}

// 添加用户处理器
public class AddUserHandler extends AbstractUserHandler {
    @Override
    public void handle(User user) {
        System.out.println("添加用户: " + user.getName());
        super.handle(user);
    }
}

// 修改用户处理器
public class ModifyUserHandler extends AbstractUserHandler {
    @Override
    public void handle(User user) {
        System.out.println("修改用户信息: " + user.getName());
        super.handle(user);
    }
}

// 流程控制
public class Main {
    public static void main(String[] args) {
        User user = new User("Tom");

        // 责任链
        AddUserHandler addHandler = new AddUserHandler();
        ModifyUserHandler modifyHandler = new ModifyUserHandler();

        addHandler.setNextHandler(modifyHandler);

        // 先添加,再修改
        addHandler.handle(user);
    }
}

输出

复制代码
添加用户: Tom
修改用户信息: Tom

总结

方案 适用场景 主要特点
策略模式 修改和添加是两种独立操作 通过不同策略切换操作,逻辑清晰,便于扩展
装饰者模式 需要叠加功能 ,比如先添加再修改 允许动态组合多个操作,避免修改原类
责任链模式 操作有固定顺序 ,比如先添加再修改 让多个处理器按顺序执行,扩展性强

推荐

  • 如果"修改"和"添加"是 两种完全独立的操作,用 策略模式。
  • 如果"修改"和"添加"可能会 动态组合,用 装饰者模式。
  • 如果"修改"和"添加"是 必须按固定顺序执行,用 责任链模式。
相关推荐
sun༒8 分钟前
递归经典例题
java·算法
小年糕是糕手8 分钟前
【C语言】函数栈帧的创建和销毁
java·c语言·开发语言·数据结构·c++·链表
努力努力再努力wz23 分钟前
【Linux进阶系列】:信号(下)
java·linux·运维·服务器·开发语言·数据结构·c++
m0_748233641 小时前
C++与Python:内存管理与指针的对比
java·c++·python
紫荆鱼1 小时前
设计模式-备忘录模式(Memento)
c++·后端·设计模式·备忘录模式
软件2051 小时前
【JDK、JRE、JVM】
java·开发语言·jvm
m0_748255411 小时前
TailwindCSS vs UnoCSS 性能深度对决:究竟快多少?
java
薛家明1 小时前
easy-query暴打efcore(包括其他所有orm),隐式Group看我如何在子查询做到极致的性能天花板
java·orm·efcore·easy-query·entityframeworkcore·dotnetcore
wudl55662 小时前
JDK 21 API增强详解
java·开发语言·windows
学习编程的Kitty2 小时前
JavaEE初阶——多线程(3)线程安全
java·开发语言·jvm