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

目录

问题:

定义:

解决:

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

总结

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

推荐

  • 如果"修改"和"添加"是 两种完全独立的操作,用 策略模式。
  • 如果"修改"和"添加"可能会 动态组合,用 装饰者模式。
  • 如果"修改"和"添加"是 必须按固定顺序执行,用 责任链模式。
相关推荐
reddingtons5 小时前
【游戏宣发】PS “生成式扩展”流,30秒无损适配全渠道KV
游戏·设计模式·新媒体运营·prompt·aigc·教育电商·游戏美术
李慕婉学姐5 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆7 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin7 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20057 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉7 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国8 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882488 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈8 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_998 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc