【C++设计模式】八大设计原则
·
系列文章目录
文章目录
- 系列文章目录
- 前言
- C++ 八大设计原则
- 1. 单一职责原则 (Single Responsibility Principle, SRP)
- 2. 开放封闭原则 (Open/Closed Principle, OCP)
- 3. 里氏替换原则 (Liskov Substitution Principle, LSP)
- 4. 接口隔离原则 (Interface Segregation Principle, ISP)
- 5. 依赖倒置原则 (Dependency Inversion Principle, DIP)
- 6. 迪米特法则 (Law of Demeter, LoD)
- 7. 合成复用原则 (Composite Reuse Principle, CRP)
- 8. 最少知识原则 (Principle of Least Knowledge, PLK)
前言
在软件开发中,设计原则是指导我们编写高质量代码的重要准则。
为了写出符合高内聚、低耦合原则的代码,我们需要遵循一些公认的设计原则。
以下是C++中常见的八大设计原则的简单介绍,以及符合和违背这些原则的代码示例。
C++ 八大设计原则
1. 单一职责原则 (Single Responsibility Principle, SRP)
原则:一个类应该只有一个引起它变化的原因。
即一个类只负责一个职责。可以提高类的可读性和可维护性,降低类的复杂度,但可能导致类的数量增加,进而增加系统设计的复杂性。
- 违背原则的代码示例:
class Order {
public:
void addItem(const std::string& item) {
// 添加商品
}
void log(const std::string& message) { //错误:实现了不该由该类实现的功能
// 记录日志
}
};
- 符合原则的代码示例:
class Logger {
public:
void log(const std::string& message) {
// 记录日志
}
};
class Order {
void addItem(const std::string& item) {
// 添加商品
}
};
2. 开放封闭原则 (Open/Closed Principle, OCP)
原则:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
可以提高系统的可扩展性,减少修改代码引入错误的风险,但需要仔细设计抽象层次,可能增加系统的复杂度。
- 违背原则的代码示例:
class Shape {
public:
enum Type { Circle, Rectangle } type;
double radius, width, height; //错误:类外可修改类内成员变量
double area() const {
switch (type) { //错误:失去扩展性,想修改必须修改类本体
case Circle:
return 3.14 * radius * radius;
case Rectangle:
return width * height;
}
return 0;
}
};
- 符合原则的代码示例:
class Shape {
public:
virtual double area() const = 0;
};
class Circle : public Shape {
public:
double area() const override {
return 3.14 * radius * radius;
}
private:
double radius;
};
class Rectangle : public Shape {
public:
double area() const override {
return width * height;
}
private:
double width, height;
};
3. 里氏替换原则 (Liskov Substitution Principle, LSP)
原则:子类对象应该能够替换掉基类对象而不影响程序的正确性。
- 违背原则的代码示例:
class Bird {
public:
virtual void fly() {
// 飞行
}
};
class Ostrich : public Bird { //鸵鸟不能飞行
public:
void fly() override {
throw std::logic_error("Ostrich can't fly");
}
};
- 符合原则的代码示例:
class Bird {
public:
virtual void fly() {
// 飞行
}
};
class Sparrow : public Bird { //麻雀可以飞行
public:
void fly() override {
// 麻雀飞行
}
};
4. 接口隔离原则 (Interface Segregation Principle, ISP)
原则:不应该强迫客户端依赖它们不需要的接口,接口应小而完备。
即类间的依赖关系应该建立在最小的接口上。可以减少代码的冗余,提高系统的灵活性和可维护性,但可能导致接口数量增加,进而增加系统设计的复杂性。
- 违背原则的代码示例:
class IMachine {
public:
virtual void print() = 0;
virtual void scan() = 0;
};
class Printer : public IMachine {
public:
void print() override {
// 打印
}
void scan() override {
// 错误:不需要实现
}
};
- 符合原则的代码示例:
class IPrinter {
public:
virtual void print() = 0;
};
class IScanner {
public:
virtual void scan() = 0;
};
class Printer : public IPrinter {
public:
void print() override {
// 打印
}
};
class Scanner : public IScanner {
public:
void scan() override {
// 扫描
}
};
5. 依赖倒置原则 (Dependency Inversion Principle, DIP)
原则:高层模块不应该依赖低层模块。
二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
- 违背原则的代码示例:
class WiredKeyboard {
public:
void type() {
// 有线键盘打字
}
};
class Computer {
public:
void input() {
keyboard_.type();
}
private:
WiredKeyboard keyboard_;
};
- 符合原则的代码示例:
class IKeyboard {
public:
virtual void type() = 0;
};
class WiredKeyboard : public IKeyboard {
public:
void type() override {
// 有线键盘打字
}
};
class Computer {
public:
Computer(IKeyboard* keyboard) : keyboard_(keyboard) {}
void input() {
keyboard_->type();
}
private:
IKeyboard* keyboard_;
};
6. 迪米特法则 (Law of Demeter, LoD)
原则:一个对象应该对其他对象有最少的了解。
- 违背原则的代码示例:
class Engine {
public:
void start() {
// 启动引擎
}
};
class Car {
public:
Engine& getEngine() {
return engine;
}
private:
Engine engine;
};
class Driver {
public:
void startCar(Car& car) {
car.getEngine().start();
}
};
- 符合原则的代码示例:
class Engine {
public:
void start() {
// 启动引擎
}
};
class Car {
public:
void start() {
engine.start();
}
private:
Engine engine;
};
7. 合成复用原则 (Composite Reuse Principle, CRP)
原则:尽量使用对象组合,而不是继承来达到复用的目的。
继承耦合度高,一定程度上破坏了封装性。
- 违背原则的代码示例:
class Engine {
public:
void start() {
// 启动引擎
}
};
class Car : public Engine {
public:
void start() {
Engine::start();
}
};
- 符合原则的代码示例:
class Engine {
public:
void start() {
// 启动引擎
}
};
class Car {
public:
Car(Engine* engine) : engine_(engine) {}
void start() {
engine_->start();
}
private:
Engine* engine_;
};
8. 最少知识原则 (Principle of Least Knowledge, PLK)
原则:一个软件实体应当尽可能少地与其他实体发生相互作用。
- 违背原则的代码示例:
class Wheel {
public:
void rotate() {
// 轮子旋转
}
};
class Car {
public:
Wheel& getWheel() {
return wheel;
}
private:
Wheel wheel;
};
class Driver {
public:
void drive(Car& car) {
car.getWheel().rotate();
}
};
- 符合原则的代码示例:
class Wheel {
public:
void rotate() {
// 轮子旋转
}
};
class Car {
public:
void move() {
wheel.rotate();
}
private:
Wheel wheel;
};
更多推荐
所有评论(0)