【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;
}
相关推荐
鱼跃鹰飞8 小时前
设计模式系列:工厂模式
java·设计模式·系统架构
老蒋每日coding15 小时前
AI Agent 设计模式系列(十九)—— 评估和监控模式
人工智能·设计模式
会员果汁16 小时前
23.设计模式-解释器模式
设计模式·解释器模式
「QT(C++)开发工程师」1 天前
C++设计模式
开发语言·c++·设计模式
茶本无香1 天前
设计模式之七—装饰模式(Decorator Pattern)
java·设计模式·装饰器模式
漂洋过海的鱼儿1 天前
设计模式——EIT构型(三)
java·网络·设计模式
老蒋每日coding2 天前
AI Agent 设计模式系列(十八)—— 安全模式
人工智能·安全·设计模式
老蒋每日coding2 天前
AI Agent 设计模式系列(十六)—— 资源感知优化设计模式
人工智能·设计模式·langchain
老蒋每日coding2 天前
AI Agent 设计模式系列(十七)—— 推理设计模式
人工智能·设计模式
冷崖2 天前
桥模式-结构型
c++·设计模式