当前位置: 首页 > news >正文

设计模式的几个准则

设计模式的几个准则

C++ 设计模式遵循一些重要的设计准则,这些准则有助于创建可维护、可扩展和灵活的代码。以下是主要的设计准则及示例:

1. 开闭原则 (Open-Closed Principle)

准则:对扩展开放,对修改关闭

#include <iostream>
#include <vector>
#include <memory>// 违反开闭原则的写法
class Shape {
public:enum Type { CIRCLE, SQUARE };Type type;void draw() {if (type == CIRCLE) {drawCircle();} else if (type == SQUARE) {drawSquare();}// 添加新形状需要修改此类}
private:void drawCircle() { std::cout << "Drawing Circle\n"; }void drawSquare() { std::cout << "Drawing Square\n"; }
};// 遵循开闭原则的写法
class ShapeBase {
public:virtual ~ShapeBase() = default;virtual void draw() = 0;
};class Circle : public ShapeBase {
public:void draw() override { std::cout << "Drawing Circle\n"; }
};class Square : public ShapeBase {
public:void draw() override { std::cout << "Drawing Square\n"; }
};// 可以轻松扩展新形状而不修改现有代码
class Triangle : public ShapeBase {
public:void draw() override { std::cout << "Drawing Triangle\n"; }
};class Drawing {
private:std::vector<std::shared_ptr<ShapeBase>> shapes;
public:void addShape(std::shared_ptr<ShapeBase> shape) {shapes.push_back(shape);}void drawAll() {for (auto& shape : shapes) {shape->draw();}}
};

2. 依赖倒置原则 (Dependency Inversion Principle)

准则:依赖抽象而不是具体实现

#include <iostream>
#include <memory>// 违反依赖倒置原则
class MySQLDatabase {
public:void connect() { std::cout << "MySQL connected\n"; }void query() { std::cout << "MySQL query executed\n"; }
};class Application {
private:MySQLDatabase db;  // 直接依赖具体实现
public:void run() {db.connect();db.query();}
};// 遵循依赖倒置原则
class Database {
public:virtual ~Database() = default;virtual void connect() = 0;virtual void query() = 0;
};class MySQLDB : public Database {
public:void connect() override { std::cout << "MySQL connected\n"; }void query() override { std::cout << "MySQL query executed\n"; }
};class PostgreSQLDB : public Database {
public:void connect() override { std::cout << "PostgreSQL connected\n"; }void query() override { std::cout << "PostgreSQL query executed\n"; }
};class App {
private:std::shared_ptr<Database> database;
public:App(std::shared_ptr<Database> db) : database(db) {}  // 依赖抽象void run() {database->connect();database->query();}
};

3. 单一职责原则 (Single Responsibility Principle)

准则:一个类只负责一个功能领域

#include <iostream>
#include <string>// 违反单一职责原则
class Employee {
private:std::string name;double salary;
public:Employee(const std::string& n, double s) : name(n), salary(s) {}// 太多职责:数据存储、计算、报告void saveToDatabase() {std::cout << "Saving " << name << " to database\n";}double calculatePay() {return salary * 0.8;  // 扣除税款}void generateReport() {std::cout << "Report for " << name << "\n";}
};// 遵循单一职责原则
class EmployeeData {
private:std::string name;double salary;
public:EmployeeData(const std::string& n, double s) : name(n), salary(s) {}std::string getName() const { return name; }double getSalary() const { return salary; }
};class PayCalculator {
public:double calculatePay(const EmployeeData& emp) {return emp.getSalary() * 0.8;}
};class EmployeeRepository {
public:void save(const EmployeeData& emp) {std::cout << "Saving " << emp.getName() << " to database\n";}
};class ReportGenerator {
public:void generateReport(const EmployeeData& emp) {std::cout << "Report for " << emp.getName() << "\n";}
};

4. 接口隔离原则 (Interface Segregation Principle)

准则:客户端不应该依赖它不需要的接口

#include <iostream>// 违反接口隔离原则
class IWorker {
public:virtual ~IWorker() = default;virtual void work() = 0;virtual void eat() = 0;virtual void code() = 0;
};class HumanWorker : public IWorker {
public:void work() override { std::cout << "Human working\n"; }void eat() override { std::cout << "Human eating\n"; }void code() override { std::cout << "Human coding\n"; }
};class RobotWorker : public IWorker {
public:void work() override { std::cout << "Robot working\n"; }void eat() override { throw std::runtime_error("Robots don't eat!");  // 被迫实现不需要的方法}void code() override { std::cout << "Robot coding\n"; }
};// 遵循接口隔离原则
class IWorkable {
public:virtual ~IWorkable() = default;virtual void work() = 0;
};class ICodeable {
public:virtual ~ICodeable() = default;virtual void code() = 0;
};class IEatable {
public:virtual ~IEatable() = default;virtual void eat() = 0;
};class Human : public IWorkable, public IEatable, public ICodeable {
public:void work() override { std::cout << "Human working\n"; }void eat() override { std::cout << "Human eating\n"; }void code() override { std::cout << "Human coding\n"; }
};class Robot : public IWorkable, public ICodeable {
public:void work() override { std::cout << "Robot working\n"; }void code() override { std::cout << "Robot coding\n"; }// 不需要实现eat方法
};

5. 里氏替换原则 (Liskov Substitution Principle)

准则:子类必须能够替换父类

#include <iostream>
#include <memory>// 违反里氏替换原则
class Rectangle {
protected:int width, height;
public:virtual void setWidth(int w) { width = w; }virtual void setHeight(int h) { height = h; }int getWidth() const { return width; }int getHeight() const { return height; }int getArea() const { return width * height; }
};class Square : public Rectangle {
public:void setWidth(int w) override {width = w;height = w;  // 改变了父类的行为}void setHeight(int h) override {height = h;width = h;   // 改变了父类的行为}
};// 使用示例(会出问题)
void processRectangle(Rectangle& rect) {rect.setWidth(5);rect.setHeight(4);// 期望面积是20,但如果是Square,面积会是16std::cout << "Area: " << rect.getArea() << std::endl;
}// 遵循里氏替换原则
class Shape {
public:virtual ~Shape() = default;virtual int getArea() const = 0;
};class GoodRectangle : public Shape {
private:int width, height;
public:GoodRectangle(int w, int h) : width(w), height(h) {}void setWidth(int w) { width = w; }void setHeight(int h) { height = h; }int getArea() const override { return width * height; }
};class GoodSquare : public Shape {
private:int side;
public:GoodSquare(int s) : side(s) {}void setSide(int s) { side = s; }int getArea() const override { return side * side; }
};

6. 合成复用原则 (Composite Reuse Principle)

准则:优先使用组合而不是继承

#include <iostream>
#include <memory>// 使用继承(不推荐)
class Engine {
public:void start() { std::cout << "Engine started\n"; }
};class Car : public Engine {  // Car "is-a" Engine? 不合理
public:void drive() {start();  // 可以使用Engine的方法std::cout << "Car driving\n";}
};// 使用组合(推荐)
class BetterEngine {
public:void start() { std::cout << "Engine started\n"; }
};class BetterCar {
private:std::unique_ptr<BetterEngine> engine;  // Car "has-a" Engine
public:BetterCar() : engine(std::make_unique<BetterEngine>()) {}void drive() {engine->start();std::cout << "Car driving\n";}// 可以轻松更换引擎void setEngine(std::unique_ptr<BetterEngine> newEngine) {engine = std::move(newEngine);}
};// 更复杂的组合示例
class Tire {
public:void rotate() { std::cout << "Tire rotating\n"; }
};class Door {
public:void open() { std::cout << "Door opened\n"; }
};class AdvancedCar {
private:std::unique_ptr<BetterEngine> engine;std::vector<std::unique_ptr<Tire>> tires;std::vector<std::unique_ptr<Door>> doors;
public:AdvancedCar() {engine = std::make_unique<BetterEngine>();for (int i = 0; i < 4; ++i) {tires.push_back(std::make_unique<Tire>());doors.push_back(std::make_unique<Door>());}}void operate() {engine->start();for (auto& tire : tires) {tire->rotate();}}
};

实际应用示例

#include <iostream>
#include <memory>
#include <vector>// 综合应用设计原则的示例
class Notification {
public:virtual ~Notification() = default;virtual void send(const std::string& message) = 0;
};class EmailNotification : public Notification {
public:void send(const std::string& message) override {std::cout << "Sending Email: " << message << std::endl;}
};class SMSNotification : public Notification {
public:void send(const std::string& message) override {std::cout << "Sending SMS: " << message << std::endl;}
};class NotificationService {
private:std::vector<std::shared_ptr<Notification>> notifiers;
public:void addNotifier(std::shared_ptr<Notification> notifier) {notifiers.push_back(notifier);}void notifyAll(const std::string& message) {for (auto& notifier : notifiers) {notifier->send(message);}}
};int main() {auto service = std::make_unique<NotificationService>();service->addNotifier(std::make_shared<EmailNotification>());service->addNotifier(std::make_shared<SMSNotification>());service->notifyAll("Hello Design Patterns!");return 0;
}
http://www.dtcms.com/a/398370.html

相关文章:

  • python+nodejs+springboot在线车辆租赁信息管理信息可视化系统
  • 计算机毕业设计 基于Python的音乐推荐系统 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
  • 《人机分工重塑开发:遗留系统重构的AI实践指南》
  • 从0死磕全栈第十天:nest.js集成prisma完成CRUD
  • 网站开发做什么科目网页设计与网站建设连接数据库
  • 如何看网站是html几代做的加拿大pc网站搭建
  • C#的MVVM架构中的几种数据绑定方式
  • Jmeter接口测试:jmeter组件元件介绍,利用取样器中http发送请求
  • Apache Tomcat 部署与配置
  • 网站建设详细合同范本西部数码网站管理助手破解版
  • 权限提升专项训练靶场:hacksudo: L.P.E.
  • 工作笔记----lwip的数据管理结构pbuf源码解析
  • 生产环境实战:Spring Cloud Sleuth与Zipkin分布式链路追踪实践
  • 学习React-15-useImperativeHandle
  • 响应式网站案列小学生做电子小报的网站
  • 【AskAI系列课程】:P4.将AI助手集成到Astro网站前端
  • 自注意力机制(Self-Attention)简介
  • App 代上架全流程解析 iOS 应用代上架服务、苹果应用发布步骤、ipa 文件上传与 App Store 审核经验
  • 学习日报 20250921|MQ (Kafka)面试深度复盘
  • 趣味学Solana(启航)
  • 期权末日论效应怎么来的?
  • iOS 混淆与反调试反 Hook 实战,运行时防护、注入检测与安全加固流程
  • 建设工程管理网站邹平建设网站
  • wordpress英文下主题怎么换苏州seo专家教优化网站结构
  • 《灼灼韶华》还原民国上海滩,虎鲸文娱虚拟拍摄让创作突破时空束缚
  • Redo Log 与 Crash Recovery:MySQL 事务持久化的核心技术
  • 金乡网站建设公司云南企业网站
  • 设计模式(C++)详解——职责链模式 (Chain of Responsibility)(1)
  • 酒店网站免费建设国际新闻今天最新
  • 企业产品网络安全日志9月23日-WAF应急