C++ 工厂模式

本文介绍了面向对象设计模式中的简单工厂、工厂方法和抽象工厂。简单工厂适用于快速解耦产品与工厂,但不遵循开闭原则;工厂方法则允许在不修改原有工厂类的情况下增加新产品,职责更单一;抽象工厂进一步扩展,适用于复杂场景,如汽车工厂同时生产汽车及其配件。每种模式各有优缺点,适用于不同场景。
摘要由CSDN通过智能技术生成

简单工厂

简单工厂,定义一个类负责创建其他对象类的实例,而被创建的对象类一般都有共同的基类。
一般来说简单工厂如果想创建一个对象类,只需要根据名字进行实例化,工厂就会创建相应的对象类。
特点:简单的对不同类对象的创建进行了一层很薄的封装

#include <iostream>
#include<memory>
//对象类的基类
class Traffic {
public:
	virtual ~Traffic() {}
	virtual void Show() = 0;
};
//汽车
class CarTraffic : public Traffic {
public:
	void Show() { std::cout << "this is CarTraffic" << std::endl; }
};
//自行车
class BicycleTraffic : public Traffic {
public:
	void Show() { std::cout << "this is BicycleTraffic" << std::endl; }
};
enum TRAFFIC_TYPE { CAR, BICYCLE, PLANE };
//交通工具生产厂
class TrafficFactory {
public:
	std::shared_ptr<Traffic> TrafficCreate(TRAFFIC_TYPE type)
	{
		switch (type) {
		case CAR:
			return std::make_shared<CarTraffic>();
			break;
		case BICYCLE:
			return std::make_shared<BicycleTraffic>();
			break;
		default:
			return nullptr;
			break;
		}
	}
};
int main()
{
	TrafficFactory factory;
	auto           car = factory.TrafficCreate(TRAFFIC_TYPE::CAR);
	auto           bicycle = factory.TrafficCreate(TRAFFIC_TYPE::BICYCLE);
	auto           plane = factory.TrafficCreate(TRAFFIC_TYPE::PLANE);

	if (car) {
		car->Show();
	}
	if (bicycle) {
		bicycle->Show();
	}
	if (plane) {
		plane->Show();
	}
	return 0;
}

简单工厂的最大问题:
当有新的对象类要加入时,就必须修改工厂类,这与我们写代码的“开闭原则”相违背。所以这时候应运而生了2.0版本的“工厂方法”

工厂方法

工厂方法的组成部分

  • 接口工厂类:提供创建具体对象类的接口,由该对象的具体的工厂类实现。
  • 对象工厂类:继承于接口工厂类,实现创建对象类的接口。
  • 接口对象类:所有要创建对象都需要拥有的方法基类。
  • 对象实体类:继承接口对象类,并要实现对应的方法,对应的工厂将会实例化该对象
#include <iostream>
#include<memory>
//===================================================================//
//对象类的基类
class Traffic {
public:
	virtual ~Traffic() {}
	virtual void Show() = 0;
};
//汽车
class CarTraffic : public Traffic {
public:
	void Show() { std::cout << "this is CarTraffic" << std::endl; }
};
//自行车
class BicycleTraffic : public Traffic {
public:
	void Show() { std::cout << "this is BicycleTraffic" << std::endl; }
};
//飞机
class PlaneTraffic : public Traffic {
public:
	void Show() { std::cout << "this is PlaneTraffic" << std::endl; }
};
//===================================================================//
//工厂类的基类
class Factory {
public:
	virtual ~Factory() {}
	virtual std::shared_ptr<Traffic> TrafficCreate() = 0;
};
//汽车工厂
class CarFactory : public Factory {
public:
	std::shared_ptr<Traffic> TrafficCreate() { return std::make_shared<CarTraffic>(); }
};
//自行车
class BicycleFactory  : public Factory {
public:
	std::shared_ptr<Traffic> TrafficCreate() { return std::make_shared<BicycleTraffic>(); }
};
//飞机
class PlaneFactory : public Factory {
public:
	std::shared_ptr<Traffic> TrafficCreate() { return std::make_shared<PlaneTraffic>(); }
};
//===================================================================//

int main()
{
	{
		auto factory = std::make_shared<CarFactory>();
		auto traffic = factory->TrafficCreate();
		traffic->Show();
	}
	{
		auto factory = std::make_shared<BicycleFactory>();
		auto traffic = factory->TrafficCreate();
		traffic->Show();
	}
	{
		auto factory = std::make_shared<PlaneFactory>();
		auto traffic = factory->TrafficCreate();
		traffic->Show();
	}
	return 0;
}

工厂方法的优劣
优势:

  • 当需要增加一个新的对象类时,无需修改原有的工厂类及对象类
  • 职责单一,每个工厂负责维护自己的产品(对象)类

缺点:

  • 当需要增加一个或多个产品(对象)时,需要创建一一对应的工厂,一下子变得又繁琐起来
  • 当对象类的基类要增加某一个公用方法时,所有的产品类都需要修改。

这时当我们有不同交通工具配件需要生产怎么办?这时候可以把简单工厂与工厂方法进行整合实现抽象工厂模式(3.0)

抽象工厂

假设我们这时小汽车厂要同时生产小汽车的轮胎,那么我们只需要对工厂进行扩充方法,来实现一个工厂来生产不同的产品

#include <iostream>
#include <memory>
//===================================================================//
//对象类的基类
class Traffic {
public:
	virtual ~Traffic() {}
	virtual void Show() = 0;
};
//交通工具轮胎
class TrafficTyre {
public:
	virtual void TyreName() = 0;
	virtual ~TrafficTyre() {}
};
//汽车
class CarTraffic : public Traffic {
public:
	void Show() { std::cout << "this is CarTraffic" << std::endl; }
};
//汽车轮胎
class CarTyre : public TrafficTyre {
public:
	void TyreName() { std::cout << "this is CarTyre" << std::endl; }
};

//===================================================================//
//工厂类的基类
class Factory {
public:
	virtual ~Factory() {}
	virtual std::shared_ptr<Traffic>     TrafficCreate() = 0;
	virtual std::shared_ptr<TrafficTyre> TyreCreate()    = 0;
};
//汽车工厂
class CarFactory : public Factory {
public:
	std::shared_ptr<Traffic>     TrafficCreate() { return std::make_shared<CarTraffic>(); }
	std::shared_ptr<TrafficTyre> TyreCreate() { return std::make_shared<CarTyre>(); }
};
//===================================================================//

int main()
{
	auto factory = std::make_shared<CarFactory>();
	auto traffic = factory->TrafficCreate();
	auto tyre    = factory->TyreCreate();
	tyre->TyreName();
	traffic->Show();
	return 0;
}

简单工厂、工厂方法与抽象工厂的理解

工厂方法:适用于结构比较唯一的场景,为同一类的产品提供创建的接口,比如只区分汽车和飞机,自行车。
抽象工厂:适用与同一级结构比较复杂的场景,比如汽车工厂同时要生产不同型号高中低档的车。
简单工厂:更适用快速的把产品与工厂进行解耦。
个人体验:简单工厂和工厂方法用的较多。而抽象工厂更像是把一类东西划成一族时时使用,自己几乎很少在工程中使用。

参考连接

C++ 中使用工厂模式更为常见,因为 C++ 支持面向对象编程。下面是一个 C++ 工厂模式的例子,使用了抽象基和纯虚函数: ```c++ #include <iostream> using namespace std; // 定义抽象基 class Shape { public: virtual void draw() = 0; virtual ~Shape() {} }; // 定义具体 class Rectangle : public Shape { public: void draw() { cout << "This is a rectangle." << endl; } }; class Circle : public Shape { public: void draw() { cout << "This is a circle." << endl; } }; // 定义工厂 class ShapeFactory { public: Shape* createShape(char type) { switch (type) { case 'r': return new Rectangle(); case 'c': return new Circle(); default: return NULL; } } }; int main() { ShapeFactory factory; Shape* shape1 = factory.createShape('r'); Shape* shape2 = factory.createShape('c'); shape1->draw(); shape2->draw(); delete shape1; delete shape2; return 0; } ``` 在上面的代码中,我们定义了一个抽象基 `Shape`,它有一个纯虚函数 `draw`,用于在派生中实现。然后,我们又定义了两个具体 `Rectangle` 和 `Circle`,它们分别继承自 `Shape`,并实现了 `draw` 函数。 接下来,我们定义了一个工厂 `ShapeFactory`,它有一个函数 `createShape`,根据型参数创建相应的对象。如果型参数是 `'r'`,则创建一个 `Rectangle` 对象;如果型参数是 `'c'`,则创建一个 `Circle` 对象。注意,这里我们返回的是 `Shape*` 型,因为 `Rectangle` 和 `Circle` 都继承自 `Shape`,所以它们可以被转化为 `Shape` 型的指针。 最后,我们在 `main` 函数中使用工厂创建了两个对象,并调用它们的 `draw` 函数输出了对象的信息。注意,我们在程序结束时需要手动释放对象占用的内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值