工厂模式
1.工厂模式定义
工厂模式是一种创建型设计模式,它通过定义一个创建对象的接口,将对象的实例化过程延迟到子类,从而实现解耦和扩展性。
工厂模式的核心思想是将对象的创建与使用分离,使得客户端代码不需要直接依赖具体的类,而是通过工厂类来获取对象。这种模式在软件开发中非常常见,尤其是在需要灵活创建对象的场景中。
2.工厂模式的主要类型
1.简单工厂模式
简单工厂模式通过一个工厂类根据传入的参数决定创建哪种具体产品类的实例。它的优点是客户端不需要知道具体产品的类名,只需知道工厂类和产品类的接口即可。然而,它的缺点是工厂类的职责过重,增加新产品时需要修改工厂类,违反了开闭原则。
class Product
{
public:
virtual ~Product()
{
}
virtual void use() const = 0; // 纯虚函数,具体产品必须实现
};
class ConcreteProductA
: public Product
{
public:
void use() const override
{
std::cout << "Using ConcreteProductA" << std::endl;
}
};
class ConcreteProductB
: public Product
{
public:
void use() const override
{
std::cout << "Using ConcreteProductB" << std::endl;
}
};
class SimpleFactory
{
public:
static Product* createProduct(const std::string& type)
{
if (type == "A")
{
return new ConcreteProductA();
}
else if (type == "B")
{
return new ConcreteProductB();
} else
{
throw std::invalid_argument("Unknown product type");
}
}
};
int main()
{
Product* productA = SimpleFactory::createProduct("A");
productA->use(); // 输出: Using ConcreteProductA
delete productA; // 记得释放内存
Product* productB = SimpleFactory::createProduct("B");
productB->use(); // 输出: Using ConcreteProductB
delete productB; // 记得释放内存
return 0;
}
2.工厂方法模式
工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。这种模式将对象的创建延迟到子类,从而提高了系统的扩展性和灵活性。
class Product
{
public:
virtual void use() const = 0;
virtual ~Product() {}
};
class ConcreteProductA
: public Product
{
public:
void use() const override
{
std::cout << "Using ConcreteProductA" << std::endl;
}
};
class ConcreteProductB
: public Product
{
public:
void use() const override
{
std::cout << "Using ConcreteProductB" << std::endl;
}
};
class Creator
{
public:
virtual std::unique_ptr<Product> factoryMethod() const = 0; // 工厂方法声明为纯虚函数,强制子类实现它。
virtual ~Creator()
{
} // 虚析构函数确保派生类的正确析构。
};
class ConcreteCreatorA
: public Creator
{
public:
std::unique_ptr<Product> factoryMethod() const override
{ // 子类实现具体的工厂方法。
return std::make_unique<ConcreteProductA>(); // 返回具体产品类的实例。
}
};
class ConcreteCreatorB
: public Creator
{
public:
std::unique_ptr<Product> factoryMethod() const override
{ // 子类实现具体的工厂方法。
return std::make_unique<ConcreteProductB>(); // 返回具体产品类的实例。
}
};
int main()
{
ConcreteCreatorA creatorA;
auto productA = creatorA.factoryMethod(); // 使用ConcreteCreatorA的工厂方法。
if (productA) productA->use(); // 使用产品。
ConcreteCreatorB creatorB; // 另一个创建者。
auto productB = creatorB.factoryMethod(); // 使用ConcreteCreatorB的工厂方法。
if (productB) productB->use(); // 使用产品。
return 0; // 结束程序。
}
3.抽象工厂模式
抽象工厂模式提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。它适用于需要创建多个相关对象的场景,例如不同操作系统的界面组件。
在C++中实现抽象工厂模式,通常涉及到以下几个关键组件:
抽象产品类:定义产品的接口。
具体产品类:实现抽象产品类的接口。
抽象工厂类:声明生成抽象产品的方法。
具体工厂类:实现抽象工厂类,生成具体产品。
客户端:通过抽象工厂来创建产品。
// 图形接口
class Shape
{
public:
virtual ~Shape()
{
}
virtual void draw() const = 0;
};
// 图形风格接口
class Style
{
public:
virtual ~Style()
{
}
virtual void applyStyle() const = 0;
};
// 圆形和矩形类实现图形接口
class Circle
: public Shape
{
public:
void draw() const override
{
std::cout << "Drawing Circle" << std::endl;
}
};
class Rectangle
: public Shape
{
public:
void draw() const override
{
std::cout << "Drawing Rectangle" << std::endl;
}
};
// 实心和空心风格实现风格接口
class SolidStyle
: public Style
{
public:
void applyStyle() const override
{
std::cout << "Applying Solid Style" << std::endl;
}
};
class HollowStyle
: public Style
{
public:
void applyStyle() const override
{
std::cout << "Applying Hollow Style" << std::endl;
}
};
// 图形工厂接口
class ShapeFactory
{
public:
virtual ~ShapeFactory()
{
}
virtual Shape* createShape() const = 0;
virtual Style* createStyle() const = 0;
};
// 圆形工厂和矩形工厂实现图形工厂接口,并为每种形状提供相应的风格工厂方法。
class CircleFactory
: public ShapeFactory
{
public:
Shape* createShape() const override
{
return new Circle();
}
Style* createStyle() const override
{
return new SolidStyle();
} // 或 HollowStyle 根据需要选择风格
};
class RectangleFactory
: public ShapeFactory
{
public:
Shape* createShape() const override
{
return new Rectangle();
}
Style* createStyle() const override
{
return new HollowStyle();
} // 或 SolidStyle 根据需要选择风格
};
int main()
{
// 使用圆形工厂创建圆形和实心风格组合的图形对象。
ShapeFactory* factory = new CircleFactory(); // 可以替换为 RectangleFactory 以创建矩形和相应风格。
Shape* shape = factory->createShape(); // 创建形状对象。
Style* style = factory->createStyle(); // 创建风格对象。
style->applyStyle(); // 应用风格。
shape->draw(); // 绘制形状。
delete shape; // 清理资源。
delete style; // 清理资源。
delete factory; // 清理资源。
return 0;
}
3.工厂模式应用场景
日志记录:日志可能记录到本地硬盘、系统事件或远程服务器,用户可以选择记录日志的位置。
数据库访问:当系统需要支持多种数据库时,工厂模式可以屏蔽具体数据库的实现细节。
框架设计:例如支持多种协议的服务器框架,可以将协议作为产品类,通过工厂模式创建。
简单工厂模式:适用于产品种类不多且不频繁变动的场景,但不符合开闭原则。
工厂方法模式:适用于产品种类多且经常变动的场景,每增加一个产品只需要增加一个对应的工厂,符合开闭原则。
抽象工厂模式:适用于创建一系列相互依赖的产品对象的场景,但增加新的产品族时,改动大,符合开闭原则。