【C++设计模式】单一职责原则

2023年8月26日,周六上午


目录


概述

单一职责原则(Single Responsibility Principle,SRP),它是面向对象设计中的一个基本原则。

单一职责原则的核心思想是,一个类应该只有一个引起它变化的原因。

换句话说,一个类应该只负责一项功能或职责

这样做的好处是,当需求发生变化时,只有与该功能相关的类需要进行修改,而不会影响其他不相关的功能。


一个简单的例子

cpp 复制代码
class FileManager {
public:
  void readFile(std::string filename) {
    // 读取文件的代码逻辑
  }

  void writeFile(std::string filename) {
    // 写入文件的代码逻辑
  }

  void deleteFile(std::string filename) {
    // 删除文件的代码逻辑
  }

  void encryptFile(std::string filename) {
    // 加密文件的代码逻辑
  }

  void compressFile(std::string filename) {
    // 压缩文件的代码逻辑
  }
};

在这个示例中,FileManager类负责文件的读取、写入、删除、加密和压缩等操作。

这个类违反了单一职责原则,因为它承担了多个不同的功能,即文件操作和文件处理。

为了遵循单一职责原则,我们可以将文件操作和文件处理分离为两个独立的类:

cpp 复制代码
class FileManager {
public:
  void readFile(std::string filename) {
    // 读取文件的代码逻辑
  }

  void writeFile(std::string filename) {
    // 写入文件的代码逻辑
  }

  void deleteFile(std::string filename) {
    // 删除文件的代码逻辑
  }
};


class FileProcessor {
public:
  void encryptFile(std::string filename) {
    // 加密文件的代码逻辑
  }

  void compressFile(std::string filename) {
    // 压缩文件的代码逻辑
  }
};

现在,FileManager类负责文件的基本操作,而FileProcessor类负责对文件进行加密和压缩等处理操作。这样,每个类都只有一个单一的职责,使得代码更加清晰、可维护和可扩展。

总结来说,单一职责原则要求将不同的职责分离到不同的类中,以确保每个类只负责一项功能。这样可以提高代码的可读性、可维护性和可扩展性,减少代码之间的耦合。


用单一职责原则来设计一个简单的学生管理系统

使用单一职责原则来设计一个简单的学生管理系统,可以将功能分解为以下几个类:

  1. Student类:表示学生对象,包含学生的基本信息(如姓名、学号、年龄)以及相关操作(如获取学生信息、修改学生信息)。
  2. StudentDatabase类:负责学生信息的存储和管理,包含增加学生、删除学生、查找学生等操作。
  3. StudentUI类:负责与用户交互,显示菜单选项,接收用户输入,并调用StudentDatabase类中的方法来执行相应的操作。
cpp 复制代码
#include <iostream>
#include <vector>
#include <string>

class Student {
private:
  std::string name;
  int studentId;
  int age;

public:
  Student(std::string name, int studentId, int age)
    : name(name), studentId(studentId), age(age) {}

  std::string getName() const {
    return name;
  }

  int getStudentId() const {
    return studentId;
  }

  int getAge() const {
    return age;
  }

  void updateName(std::string newName) {
    name = newName;
  }

  void updateAge(int newAge) {
    age = newAge;
  }
};

class StudentDatabase {
private:
  std::vector<Student> students;

public:
  void addStudent(const Student& student) {
    students.push_back(student);
  }

  void removeStudent(int studentId) {
    for (auto it = students.begin(); it != students.end(); ++it) {
      if (it->getStudentId() == studentId) {
        students.erase(it);
        break;
      }
    }
  }

  Student findStudent(int studentId) const {
    for (const auto& student : students) {
      if (student.getStudentId() == studentId) {
        return student;
      }
    }
    // 如果找不到对应的学生,则返回一个空的Student对象
    return Student("", -1, -1);
  }

  std::vector<Student> getAllStudents() const {
    return students;
  }
};

class StudentUI {
private:
  StudentDatabase studentDB;

public:
  void displayMenu() {
    std::cout << "=== 学生管理系统 ===" << std::endl;
    std::cout << "1. 添加学生" << std::endl;
    std::cout << "2. 删除学生" << std::endl;
    std::cout << "3. 查找学生" << std::endl;
    std::cout << "4. 显示所有学生" << std::endl;
    std::cout << "0. 退出" << std::endl;
  }

  void addStudent() {
    std::string name;
    int studentId, age;

    std::cout << "请输入学生姓名: ";
    std::cin >> name;
    std::cout << "请输入学生学号: ";
    std::cin >> studentId;
    std::cout << "请输入学生年龄: ";
    std::cin >> age;

    Student student(name, studentId, age);
    studentDB.addStudent(student);
    std::cout << "成功添加学生!" << std::endl;
  }

  void removeStudent() {
    int studentId;

    std::cout << "请输入要删除的学生学号: ";
    std::cin >> studentId;

    studentDB.removeStudent(studentId);
    std::cout << "成功删除学生!" << std::endl;
  }

  void findStudent() {
    int studentId;

    std::cout << "请输入要查找的学生学号: ";
    std::cin >> studentId;

    Student student = studentDB.findStudent(studentId);
    if (student.getStudentId() != -1) {
      std::cout << "找到学生: " << student.getName() << std::endl;
      std::cout << "学号: " << student.getStudentId() << std::endl;
      std::cout << "年龄: " << student.getAge() << std::endl;
    } else {
      std::cout << "未找到该学生!" << std::endl;
    }
  }

  void displayAllStudents() {
    std::vector<Student> students = studentDB.getAllStudents();
    if (students.empty()) {
      std::cout << "暂无学生信息!" << std::endl;
    } else {
      std::cout << "所有学生信息:" << std::endl;
      for (const auto& student : students) {
        std::cout << "姓名: " << student.getName() << ", ";
        std::cout << "学号: " << student.getStudentId() << ", ";
        std::cout << "年龄: " << student.getAge() << std::endl;
      }
    }
  }

  void run() {
    int choice;

    do {
      displayMenu();
      std::cout << "请输入选项: ";
      std::cin >> choice;

      switch (choice) {
        case 1:
          addStudent();
          break;
        case 2:
          removeStudent();
          break;
        case 3:
          findStudent();
          break;
        case 4:
          displayAllStudents();
          break;
        case 0:
          std::cout << "退出程序!" << std::endl;
          break;
        default:
          std::cout << "无效的选项,请重新输入!" << std::endl;
      }
    } while (choice != 0);
  }
};

int main() {
  StudentUI studentUI;
  studentUI.run();

  return 0;
}
相关推荐
晨米酱35 分钟前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机6 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机7 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机7 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机7 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤7 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机1 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴1 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤1 天前
工厂模式
设计模式