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

目录

问题:

定义:

解决:

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

总结

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

推荐

  • 如果"修改"和"添加"是 两种完全独立的操作,用 策略模式。
  • 如果"修改"和"添加"可能会 动态组合,用 装饰者模式。
  • 如果"修改"和"添加"是 必须按固定顺序执行,用 责任链模式。
相关推荐
mghio6 小时前
Dubbo 中的集群容错
java·微服务·dubbo
千千寰宇8 小时前
[设计模式/Java/多线程] 设计模式之单例模式【9】
设计模式·操作系统-进程/线程/并发
咖啡教室11 小时前
java日常开发笔记和开发问题记录
java
咖啡教室11 小时前
java练习项目记录笔记
java
鱼樱前端12 小时前
maven的基础安装和使用--mac/window版本
java·后端
RainbowSea12 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq
RainbowSea13 小时前
5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
java·消息队列·rabbitmq
李少兄14 小时前
Unirest:优雅的Java HTTP客户端库
java·开发语言·http
此木|西贝14 小时前
【设计模式】原型模式
java·设计模式·原型模式