C++设计模式~工厂模式

设计模式~工厂模式

工厂模式

  • 工厂模式是典型的继承多态。【继承多态】
  • 工厂模式封装了对象的创建,即用户不逼自己调用产品的构造函数,是要通过相应的函数接口即可。
工厂模式的分类
  • 简单工厂(Simple Factory)
  • 工厂方法(Factory Method)
  • 抽象工厂(Abstract Factory)
简单工厂
#include <iostream>
#include <memory>
#include <string>
using namespace std;

// 基类
class Car
{
public:
	Car(string name):_name(name){}
	virtual void show() = 0; // 纯虚函数
protected:
	string _name;
};
// 宝马
class Bmw :public Car
{
public:
	Bmw(string name):Car(name){}
	void show()
	{
		cout << "获取一个宝马:" << _name << endl;
	}
};
// 奥迪
class Audi :public Car
{
public:
	Audi(string name) :Car(name) {}
	void show()
	{
		cout << "获取一个奥迪:" << _name << endl;
	}
};

enum CarType { BMW,AUDI };
class SimpleFactory
{
public:
	Car* createCar(CarType ct)
	{
		switch (ct)
		{
		case BMW:
			return new Bmw("x6");
		case AUDI:
			return new Audi("A8");
		default:
			cerr << "传入参数错误" << ct << endl;
			return nullptr;
		}
	}
};

int main()
{
    // 智能指针
	unique_ptr<SimpleFactory> factory(new SimpleFactory());
	unique_ptr<Car> p1(factory->createCar(BMW));
	unique_ptr<Car> p2(factory->createCar(AUDI));
	p1->show();
	p2->show();
    
    return 0;
}
  • 简单工厂将对象的创建封装到一个接口函数中,通过传入不同的类标识,然后返回不同的对象(汽车),可用不用知道对象创建的过程。
  • 但是简单工厂的在设计上违背了软件设计的开闭原则,因为createCar这个函数,一旦有新的工厂,就需要修改。
  • 同时也不符合实际情况,不同的品牌应该在不同的工厂。
工厂方法
#include <iostream>
#include <memory>
#include <string>
using namespace std;

// 汽车基类
class Car
{
public:
	Car(string name):_name(name){}
	virtual void show() = 0; // 纯虚函数
protected:
	string _name;
};
// 宝马
class Bmw :public Car
{
public:
	Bmw(string name):Car(name){}
	void show()
	{
		cout << "获取一个宝马:" << _name << endl;
	}
};
// 奥迪
class Audi :public Car
{
public:
	Audi(string name) :Car(name) {}
	void show()
	{
		cout << "获取一个奥迪:" << _name << endl;
	}
};

// 工厂基类
class Factory
{
public:
	virtual Car* createCar(string name) = 0;
};

// 宝马工厂
class BmwFactory:public Factory
{
	Car* createCar(string name)
	{
		return new Bmw(name);
	}
};
// 奥迪工厂
class AudiFactory :public Factory
{
	Car* createCar(string name)
	{
		return new Audi(name);
	}
};

int main()
{
	unique_ptr<Factory> bmwfactory(new BmwFactory());
	unique_ptr<Factory> audifactory(new AudiFactory());
	unique_ptr<Car> p1(bmwfactory->createCar("X6"));
	unique_ptr<Car> p2(audifactory->createCar("A8"));
	p1->show();
	p2->show();
	return 0;
}
  • 为工厂提供基类,不同产品的工厂由工厂基类派生,然后重写方法。这样的设计符合实际情况,不同的品牌有自己的工厂
  • 但是这样的设计还是需要改进,因为同一种品牌可能由多种产品,如果按照工厂方法设计,会出现大量的工厂类,难以维护
抽象工厂
// 汽车基类
class Car
{
public:
	Car(string name) :_name(name) {}
	virtual void show() = 0; // 纯虚函数
protected:
	string _name;
};
// 宝马
class Bmw :public Car
{
public:
	Bmw(string name) :Car(name){}
	void show()
	{
		cout << "获取一个宝马:" << _name << endl;
	}
};
// 奥迪
class Audi :public Car
{
public:
	Audi(string name) :Car(name){}
	void show()
	{
		cout << "获取一个奥迪:" << _name << endl;
	}
};

// 车灯基类
class Light
{
public:
	virtual void show() = 0;
};
// 宝马牌车灯
class BmwLight : public Light
{
public:
	void show()
	{
		cout << "获取一个宝马牌车灯" << endl;
	}
};
// 奥迪牌车灯
class AudiLight : public Light
{
public:
	void show()
	{
		cout << "获取一个奥迪牌车灯" << endl;
	}
};

// 工厂基类
class AbstractFactory
{
public:
	virtual Car* createCar(string name) = 0;
	virtual Light* createLight(string name) = 0;
};

// 宝马工厂
class BmwFactory :public AbstractFactory
{
	Car* createCar(string name)
	{
		return new Bmw(name);
	}
	Light*createLight()
	{
		return new BmwLight();
	}
};
// 奥迪工厂
class AudiFactory :public AbstractFactory
{
	Car* createCar(string name)
	{
		return new Audi(name);
	}
	Light*createLight()
	{
		return new AudiLight();
	}
};

int main()
{
	unique_ptr<AbstractFactory> bmwfactory(new BmwFactory());
	unique_ptr<AbstractFactory> audifactory(new AudiFactory());
	unique_ptr<Car> p1(bmwfactory->createCar("X6"));
	unique_ptr<Car> p2(audifactory->createCar("A8"));
	unique_ptr<Light> l1(bmwfactory->createLight("X6"));
	unique_ptr<Light> l2(audifactory->createLight("A8"));
	p1->show();
	p2->show();
	l1->show();
	l2->show();
	return 0;
}
  • 抽象工厂可以看作是工厂方法的改进,因为它将统一品牌的产品都设计在一个工厂生产,符合实际。

总结

  • 工厂模式的典型的继承多态,使用基类的指针接收派生类对象,虚函数重写,代码复用和多态。
  • 不同的场景可以使用不同的工厂模式,各有优缺点。

新手上路,如有错误,请指出!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值