【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;
}
相关推荐
WaaTong2 小时前
《重学Java设计模式》之 原型模式
java·设计模式·原型模式
霁月风2 小时前
设计模式——观察者模式
c++·观察者模式·设计模式
暗黑起源喵5 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
wrx繁星点点12 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
金池尽干14 小时前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨14 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
捕鲸叉1 天前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点1 天前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰1 天前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus1 天前
java设计模式之策略模式
java·设计模式·策略模式