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

目录

问题:

定义:

解决:

[方式 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

总结

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

推荐

  • 如果"修改"和"添加"是 两种完全独立的操作,用 策略模式。
  • 如果"修改"和"添加"可能会 动态组合,用 装饰者模式。
  • 如果"修改"和"添加"是 必须按固定顺序执行,用 责任链模式。
相关推荐
皮影w3 小时前
Java SpringAOP入门
java·开发语言
007php0073 小时前
Redis面试题解析:Redis的数据过期策略
java·网络·redis·缓存·面试·职场和发展·php
w***48824 小时前
Spring Boot3.x集成Flowable7.x(一)Spring Boot集成与设计、部署、发起、完成简单流程
java·spring boot·后端
u***1374 小时前
详解tomcat中的jmx监控
java·tomcat
Vic101014 小时前
Java 序列化与反序列化:深入解析与实践
java·开发语言
后端小张4 小时前
【JAVA 进阶】Spring Cloud 微服务全栈实践:从认知到落地
java·开发语言·spring boot·spring·spring cloud·微服务·原理
zl9798994 小时前
RabbitMQ-发布确认高级
java·分布式·rabbitmq
灰小猿4 小时前
分布式项目集成TLog实现轻量级日志链路追踪
java·分布式·springcloud·tlog·日志链路追踪
乄bluefox4 小时前
高性能分布式 ID 生成器:基于 Redis Segment 预分配的实践
java·redis·分布式
Jiong-9524 小时前
Java求职面试:谢飞机的奇妙旅程
java·jvm·线程池·多线程·hashmap·juc·arraylist