1 前置知识
前言:
一定要阅读这个有关多态的知识点 ,要不然不方便阅读下面的知识
1.1 接口
1.1.1 定义
接口是一种抽象类型,它定义了一组方法签名,但不包含方法的实现。接口用于指定类必须实现的行为,使得不同的类可以通过实现相同的接口来具有统一的对外交互方式
方法签名:方法签名是对方法的一种抽象描述,包含方法名称、参数列表和返回类型
int add(int a, int b) {
return a + b;
}
上面那个就是方法签名: int add(int a, int b)
1.1.2
- 抽象类:含有至少一个纯虚函数的类被称作抽象类。抽象类不能实例化对象,它的主要作用是为派生类提供统一的接口规范。
- 纯虚函数:这是一种特殊的虚函数,在声明时赋值为 0。纯虚函数没有函数体,派生类必须对其进行实现。
#include <iostream>// 定义一个抽象类,包含一组方法签名
class Shape {
public:// 纯虚函数,计算面积的方法签名virtual double calculateArea() = 0;// 纯虚函数,获取周长的方法签名virtual double getPerimeter() = 0;// 虚析构函数,确保正确释放派生类对象virtual ~Shape() {}
};// 实现 Shape 接口的 Circle 类
class Circle : public Shape {
private:double radius;
public:Circle(double r) : radius(r) {}// 实现 calculateArea 方法double calculateArea() override {return 3.14 * radius * radius;}// 实现 getPerimeter 方法double getPerimeter() override {return 2 * 3.14 * radius;}
};// 实现 Shape 接口的 Rectangle 类
class Rectangle : public Shape {
private:double length;double width;
public:Rectangle(double l, double w) : length(l), width(w) {}// 实现 calculateArea 方法double calculateArea() override {return length * width;}// 实现 getPerimeter 方法double getPerimeter() override {return 2 * (length + width);}
};int main() {// 使用基类指针指向派生类对象Shape* circle = new Circle(5.0);Shape* rectangle = new Rectangle(4.0, 6.0);// 调用派生类的方法std::cout << "Circle area: " << circle->calculateArea() << std::endl;std::cout << "Circle perimeter: " << circle->getPerimeter() << std::endl;std::cout << "Rectangle area: " << rectangle->calculateArea() << std::endl;std::cout << "Rectangle perimeter: " << rectangle->getPerimeter() << std::endl;// 释放内存delete circle;delete rectangle;return 0;
}
基类的析构函数应该声明为虚析构函数。
1.2 耦合度
- 定义:在一个复杂的软件系统中,通常由多个模块组成,这些模块可能是函数、类、子系统等。模块之间会存在各种联系,比如一个模块可能会调用另一个模块的功能、使用另一个模块的数据等。耦合度就是对这种联系紧密程度的度量。
耦合度越低越好 - 降低耦合度的方法
- 模块化设计:将系统分解为多个功能独立的模块,每个模块只负责一个特定的功能,减少模块之间的依赖关系。
- 使用接口和抽象类:通过定义接口和抽象类,模块之间可以通过接口进行通信,而不是直接依赖具体的实现类,从而降低耦合度。
- 依赖注入:将一个模块所依赖的其他模块通过参数传递的方式注入到该模块中,而不是在模块内部直接创建依赖对象,这样可以使模块之间的依赖关系更加灵活和可配置。
- 数据封装:将数据封装在模块内部,只提供必要的接口供其他模块访问,避免外部模块直接访问内部数据,从而降低模块之间的耦合度。
2 设计模式
定义:设计模式(Design Pattern)是指在软件开发过程中,针对反复出现的问题所总结归纳出的通用解决方案。它就像是建筑师手中的蓝图,为开发者提供了一套经过实践验证的、行之有效的设计思路和方法,帮助开发者更高效地构建出可维护、可扩展、可复用的软件系统。
一句话总结:软件开发中的套路
设计原则
- 单一职责原则(Single Responsibility Principle,SRP)
定义:一个类应该只有一个引起它变化的原因。也就是说,一个类应该只负责一项职责,而不应该承担过多的职责。 - 开闭原则
定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。即当需求发生变化时,应该通过扩展现有代码来实现新的功能,而不是修改已有的代码。 - 里氏替换原则(Liskov Substitution Principle,LSP)
定义:所有引用基类的地方必须能透明地使用其子类的对象。也就是说,子类对象可以替换父类对象,而程序的行为不会发生改变。 - 依赖倒置原则(Dependency Inversion Principle,DIP)
定义:高层模块不应该依赖低层模块,二者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。简单来说,就是要依赖接口或抽象类,而不是具体的实现类。
- 接口隔离原则(Interface Segregation Principle,ISP)
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。也就是说,要将一个大的接口拆分成多个小的、具体的接口,每个接口只包含客户端需要的方法。 - 迪米特法则(Law of Demeter,LoD),也称为最少知识原则
定义:一个对象应该对其他对象有最少的了解。也就是说,一个类应该尽量减少与其他类的直接交互,如果两个类之间确实需要通信,应该通过一个中间类来进行。 - 组合优于继承
组合定义:是指一个类包含另一个类的对象作为其成员变量,通过调用该对象的方法来实现功能。例如,在一个汽车系统中,Car 类可以包含一个 Engine 类的对象,通过调用 Engine 对象的方法来实现汽车的启动、停止等功能。
这些概念太抽象 建议直接进入实现系列
3 实战
3.1 行为型设计模式