您的位置:首页 > 新闻 > 会展 > 服务器搭建网站域名配置_即速应用微信小程序官网_百度河南代理商_网络营销方案有哪些

服务器搭建网站域名配置_即速应用微信小程序官网_百度河南代理商_网络营销方案有哪些

2025/1/7 14:05:26 来源:https://blog.csdn.net/ke_wu/article/details/144730135  浏览:    关键词:服务器搭建网站域名配置_即速应用微信小程序官网_百度河南代理商_网络营销方案有哪些
服务器搭建网站域名配置_即速应用微信小程序官网_百度河南代理商_网络营销方案有哪些

常用设计原则目录

    • 单一职责原则
    • 开闭原则
    • 里氏替换原则
    • 接口隔离原则
    • 依赖倒置原则
    • 迪米特法则

单一职责原则

  • 单一职责原则(Single Responsibility Principle, SRP)
  • 定义:
    一个类应该只有一个引起它变化的原因。即一个类应该只负责一项职责。
  • 解释:
    这意味着一个类应该专注于一个功能或一个业务逻辑。如果一个类承担了多个不同的职责,那么对其中一个职责的修改可能会影响到其他职责,导致难以维护和测试。例如,一个类既负责用户数据的存储又负责用户数据的验证,当存储逻辑需要修改时,可能会影响到验证逻辑,反之亦然。
    例如,在一个电商系统中, OrderService 类应该只负责订单的处理,如创建订单、修改订单、取消订单等操作,而不应该同时负责处理用户的支付和商品的库存管理。
#include <iostream>
#include <string>// 用户验证类,只负责用户验证功能
class UserValidator {
public:bool validate(const std::string& username, const std::string& password) {// 简单的验证逻辑,这里仅作示例if (username == "admin" && password == "123456") {return true;}return false;}
};// 用户存储类,只负责用户存储功能
class UserStorage {
public:void save(const std::string& username, const std::string& password) {// 简单的存储逻辑,这里仅作示例std::cout << "Saving user: " << username << " with password: " << password << std::endl;}
};int main() {UserValidator validator;UserStorage storage;std::string username = "admin";std::string password = "123456";if (validator.validate(username, password)) {storage.save(username, password);} else {std::cout << "Invalid user" << std::endl;}return 0;
}

注释:

  • UserValidator 类只负责用户验证,通过 validate 方法验证用户名和密码。
  • UserStorage 类只负责用户存储,通过 save 方法存储用户信息。这样,每个类只负责一项职责,符合单一职责原则。

开闭原则

  • 开闭原则(Open/Closed Principle, OCP)
  • 定义:
    软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
  • 解释:
    当需要对系统添加新功能时,应该通过扩展现有代码(例如通过继承、实现接口等方式)而不是修改现有代码来实现。这样可以确保现有代码的稳定性,避免因修改旧代码而引入新的错误。
    例如,在一个图形绘制系统中,有一个 Shape 基类,其派生类有 Circle、Rectangle 等。如果要添加新的形状 Triangle,应该创建一个新的 Triangle 类继承自 Shape,而不是修改 Shape 类的代码。这样,Shape 类及其已有的派生类的代码保持不变,实现了对修改关闭,对扩展开放。
#include <iostream>
#include <memory>
#include <vector>// 基类 Shape,定义一个绘制形状的抽象接口
class Shape {
public:virtual void draw() = 0;virtual ~Shape() = default;
};// 具体的圆形类,实现 Shape 接口
class Circle : public Shape {
public:void draw() override {std::cout << "Drawing a circle" << std::endl;}
};// 具体的矩形类,实现 Shape 接口
class Rectangle : public Shape {
public:void draw() override {std::cout << "Drawing a rectangle" << std::endl;}
};// 图形绘制器类,负责绘制各种形状
class ShapeDrawer {
public:void drawShapes(const std::vector<std::shared_ptr<Shape>>& shapes) {for (const auto& shape : shapes) {shape->draw();}}
};int main() {std::vector<std::shared_ptr<Shape>> shapes;shapes.push_back(std::make_shared<Circle>());shapes.push_back(std::make_shared<Rectangle>());ShapeDrawer drawer;drawer.drawShapes(shapes);// 新增一个三角形类,扩展功能而不修改现有代码class Triangle : public Shape {public:void draw() override {std::cout << "Drawing a triangle" << std::endl;}};shapes.push_back(std::make_shared<Triangle>());drawer.drawShapes(shapes);return 0;
}

注释:

  • Shape 是一个抽象基类,定义了 draw 接口,CircleRectangle 是其具体实现。
  • ShapeDrawer 类的 drawShapes 方法可以绘制各种形状,通过使用 Shape
    的指针,它可以绘制不同的形状而不关心具体的形状类型。
  • 新增 Triangle 类时,无需修改 ShapeDrawer 类的代码,符合开闭原则。

里氏替换原则

  • 里氏替换原则(Liskov Substitution Principle, LSP)
  • 定义:
    子类型必须能够替换掉它们的父类型,而程序的行为不会发生变化。
  • 解释:
    这意味着派生类应该可以在任何使用基类的地方被使用,并且不会破坏程序的正确性。派生类在重写基类的方法时,不能改变基类方法的前置条件和后置条件,不能改变基类方法的输入输出约定。
    例如,如果 Bird 是一个基类,PenguinBird 的一个派生类,那么在使用 Bird 的地方,使用 Penguin 替换时,不应该出现错误。如果 Bird 类有一个fly 方法,而 Penguin 不能飞,那么在 Penguin 类中不应该简单地重写 fly 方法为抛出异常或不做任何事情,而应该重新考虑类的继承关系或方法的设计,因为这违反了里氏替换原则。
#include <iostream>// 基类 Bird,定义一个飞行接口
class Bird {
public:virtual void fly() = 0;virtual ~Bird() = default;
};// 能正常飞行的鸟
class Sparrow : public Bird {
public:void fly() override {std::cout << "Sparrow is flying" << std::endl;}
};// 不会飞行的鸟,重新设计接口以符合 LSP
class Penguin {
public:void swim() {std::cout << "Penguin is swimming" << std::endl;}
};// 鸟的操作类,使用 Bird 基类
class BirdOperation {
public:void makeBirdFly(Bird* bird) {bird->fly();}
};int main() {Sparrow sparrow;BirdOperation operation;operation.makeBirdFly(&sparrow);// 企鹅类不继承自 Bird,避免违反 LSPPenguin penguin;// 不会调用企鹅的 fly 方法,因为企鹅不应该有 fly 接口// 如果企鹅继承自 Bird 并抛出异常或不做任何事情,就违反了 LSPreturn 0;
}

注释:

  • Bird 是基类,定义了 fly 接口,SparrowBird 的子类,实现了正常飞行。
  • Penguin 类不继承自 Bird,因为它不能飞行。如果让 Penguin 继承 Bird 并实现 fly
    接口(如抛出异常),就会违反里氏替换原则,这里通过重新设计类结构避免了这个问题。
  • BirdOperation 类使用 Bird 基类,调用 fly 方法。

接口隔离原则

  • 接口隔离原则(Interface Segregation Principle, ISP)
  • 定义:
    客户端不应该依赖它不需要的接口。
  • 解释:
    应该将大而全的接口拆分成多个小的、更具体的接口,使客户端只依赖于它们真正需要的接口,避免强迫客户端实现它们不使用的方法。
    例如,有一个 Worker 接口,包含 workeatsleep 方法。对于一个 RobotWorker 类,它不需要 eatsleep 方法,所以可以将 Worker 接口拆分成 Workable(包含 work)、Eatable(包含 eat)和 Sleepable(包含 sleep)接口,这样 RobotWorker 只需要实现 Workable 接口,而不用实现 Eatable Sleepable 接口。
#include <iostream>// 可工作的接口
class Workable {
public:virtual void work() = 0;virtual ~Workable() = default;
};// 可吃的接口
class Eatable {
public:virtual void eat() = 0;virtual ~Eatable() = default;
};// 可睡的接口
class Sleepable {
public:virtual void sleep() = 0;virtual ~Sleepable() = default;
};// 人类,实现了 Workable, Eatable, Sleepable 接口
class Human : public Workable, public Eatable, public Sleepable {
public:void work() override {std::cout << "Human is working" << std::endl;}void eat() override {std::cout << "Human is eating" << std::endl;}void sleep() override {std::cout << "Human is sleeping" << std::endl;}
};// 机器人,只实现 Workable 接口
class Robot : public Workable {
public:void work() override {std::cout << "Robot is working" << std::endl;}
};int main() {Human human;human.work();human.eat();human.sleep();Robot robot;robot.work();// 机器人不需要 eat 和 sleep 功能,避免实现不必要的接口return 0;
}

注释:

  • Workable、Eatable 和 Sleepable 是不同的接口,将不同的行为分离。
  • Human 实现了三个接口,因为人类可以工作、吃和睡。
  • Robot 只实现 Workable 接口,因为机器人不需要吃和睡,符合接口隔离原则。

依赖倒置原则

  • 依赖倒置原则(Dependency Inversion Principle, DIP)
  • 定义:
    高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
  • 解释:
    这意味着在软件设计中,应该依赖于抽象接口或抽象类,而不是具体的实现类。通过依赖抽象,可以降低模块之间的耦合度,提高代码的可维护性和可扩展性。
    例如,在一个汽车制造系统中,Car 类(高层模块)不应该直接依赖于具体的 Engine 实现类,而是依赖于一个抽象的 IEngine 接口。不同的 Engine 实现(如 GasolineEngine、ElectricEngine)可以实现 IEngine 接口,Car 类可以使用不同的 IEngine 实现,这样当需要更换引擎时,只需要替换 IEngine 的具体实现,而不需要修改 Car 类。
#include <iostream>// 抽象引擎接口
class IEngine {
public:virtual void start() = 0;virtual ~IEngine() = default;
};// 汽油引擎实现
class GasolineEngine : public IEngine {
public:void start() override {std::cout << "Gasoline engine starts" << std::endl;}
};// 电动引擎实现
class ElectricEngine : public IEngine {
public:void start() override {std::cout << "Electric engine starts" << std::endl;}
};// 汽车类,依赖于抽象引擎接口
class Car {
private:IEngine* engine;
public:Car(IEngine* e) : engine(e) {}void start() {engine->start();}
};int main() {// 使用汽油引擎IEngine* gasolineEngine = new GasolineEngine();Car car1(gasolineEngine);car1.start();// 使用电动引擎IEngine* electricEngine = new ElectricEngine();Car car2(electricEngine);car2.start();delete gasolineEngine;delete electricEngine;return 0;
}

注释:

  • IEngine 是抽象引擎接口,GasolineEngineElectricEngine 是具体实现。
  • Car 类依赖于 IEngine 接口,而不是具体的引擎实现。这样可以通过传递不同的引擎实现类给 Car 类,实现了依赖倒置原则。

迪米特法则

  • 迪米特法则(Law of Demeter, LoD),也称为最少知识原则(Least Knowledge Principle)
  • 定义:
    一个对象应该对其他对象有最少的了解,只与直接朋友通信,避免耦合度过高。
  • 解释:
    一个对象的 “朋友” 包括:当前对象本身、作为参数传递进来的对象、当前对象的成员变量、如果成员变量是一个集合,那么集合中的元素、当前对象创建的对象。该原则要求对象之间的通信应该尽可能地少,避免一个对象对另一个对象内部的细节有过多的了解。
    例如,在一个公司系统中,Employee 类不应该直接调用 Department 类的 Manager 类的方法,而是通过 Department 类提供的接口来间接调用,这样 Employee 类只需要和 Department 类通信,而不用深入到 Department类内部的 Manager 类。
#include <iostream>
#include <vector>class Employee {
private:std::string name;
public:Employee(const std::string& n) : name(n) {}std::string getName() const {return name;}
};class Department {
private:std::vector<Employee> employees;
public:void addEmployee(const Employee& e) {employees.push_back(e);}std::vector<Employee> getEmployees() const {return employees;}
};class Company {
private:std::vector<Department> departments;
public:void addDepartment(const Department& d) {departments.push_back(d);}void printEmployees() {for (const auto& department : departments) {// 通过 Department 提供的接口获取员工信息,而不是直接访问 Department 内部的 Employee 集合for (const auto& employee : department.getEmployees()) {std::cout << employee.getName() << std::endl;}}}
};int main() {Company company;Department department;department.addEmployee(Employee("Alice"));department.addEmployee(Employee("Bob"));company.addDepartment(department);company.printEmployees();return 0;
}

注释:

  • Employee 类表示员工,包含员工的基本信息。
  • Department 类管理员工,包含添加和获取员工的方法。
  • Company 类管理部门,通过 DepartmentgetEmployees 接口获取员工信息,而不是直接操作
    Department 类中的 employees 集合,符合迪米特法则。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com