设计模式(四)
软件系统中,经常面临创建对象的工作,由于需求的变化,需要创建的对象的具体类型经常变化
面向接口的编程:一个对象的类型,往往需要生成抽象类,接口类;不应该生成具体的类
变量需要生成抽象基类
对象创建 模式
通过对象创建模式绕开new,来避免对象创建 new过程中所导致的紧耦合(依赖具体类),
从而支持对象创建的稳定,是接口抽象之后的第一步工作
工厂模式
虚函数:不是编译时依赖,而是延迟依赖
定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method 使得一个类的实例化延迟(目的:解耦合; 方法: 虚函数)到子类
需要一个基类或者一个接口(在C++中通常是抽象类),其中声明了一个或多个创建对象的虚函数子类将继承这个接口,并实现创建对象的虚函数。每个子类可以根据需要实例化不同的类对象的创建不是在基类中直接完成,而是在运行时由子类决定通过将对象的创建逻辑从使用逻辑中分离出来,降低了类之间的依赖关系
eg:假设我们有一个简单的图形绘制系统,我们需要能够绘制不同的图形,如圆形、矩形等
// 定义一个图形接口和两个具体的图形类
// 图形接口
class Shape {
public:virtual void draw() = 0; // 纯虚函数,用于绘制图形virtual ~Shape() {} // 虚析构函数,确保正确释放资源
};// 圆形类
class Circle : public Shape {
public:void draw() override {std::cout << "Drawing Circle" << std::endl;}
};// 矩形类
class Rectangle : public Shape {
public:void draw() override {std::cout << "Drawing Rectangle" << std::endl;}
};
定义一个工厂模式的基类:
// 图形工厂接口
class ShapeFactory {
public:virtual Shape* createShape() = 0; // 工厂方法,用于创建图形virtual ~ShapeFactory() {}
};
工厂类的接口下,定义各种图像创建具体的工厂:
// 圆形工厂
class CircleFactory : public ShapeFactory {
public:Shape* createShape() override {return new Circle();}
};// 矩形工厂
class RectangleFactory : public ShapeFactory {
public:Shape* createShape() override {return new Rectangle();}
};
使用这些工厂来创建和绘制图像:
int main() {ShapeFactory* factory = new CircleFactory();Shape* shape = factory->createShape();shape->draw();delete shape;delete factory;factory = new RectangleFactory();shape = factory->createShape();shape->draw();delete shape;delete factory;return 0;
}
- 解耦合:客户端代码不需要知道创建对象的具体类,只需要知道如何与工厂接口交互
- 扩展性:如果需要添加新的图形,只需要添加一个新的图形类和一个对应的工厂类,而不需要修改现有代码
- 灵活性:可以在运行时根据条件动态地选择创建哪个类的实例
- 遵循开闭原则:对扩展开放(可以添加新的图形和工厂),对修改关闭(不需要修改现有类)
抽象工厂
软件系统中,面临 “一系列相互依赖的对象”
的创建工作,同时,由于需求的变化,往往存在更多系列对象的创建工作
eg: 设计圆形方形,会有着不同的颜色
// 抽象工厂
class AbstractFactory {
public:virtual Shape* createCircle() = 0;virtual Shape* createSquare() = 0;virtual ~AbstractFactory() {}
};// 具体工厂
class BlackAndWhiteFactory : public AbstractFactory {
public:Shape* createCircle() override {return new Circle();}Shape* createSquare() override {return new Square();}
};// 客户端代码
AbstractFactory* factory = new BlackAndWhiteFactory();
Shape* myCircle = factory->createCircle();
Shape* mySquare = factory->createSquare();
- 封装性:抽象工厂模式将一组具有相同主题的单独工厂封装起来,在客户端中只需要知道它们是如何相互协作的,而不需要知道具体实现细节
- 易于交换产品系列:由于具体工厂类负责创建具体的产品对象,因此可以通过替换具体工厂类来切换整个产品系列
- 符合开闭原则:添加新的产品系列时,不需要修改现有系统,只需要添加新的具体工厂和产品类
- 减少对象间的依赖:客户端代码只依赖于抽象工厂类和抽象产品类,而不依赖于具体的实现类
c++中,子类的构造函数,会先调用父类的构造函数,如果在父类的构造函数中,调用虚函数;此时,就无法使用多态的性质,因为子类还没有被构造,子类的虚函数还没有;这就出现了问题,无法调用到子类的虚函数;所有c++中父类构造函数不能调用虚函数