工厂模式-现代C++设计模式

工厂方法

应用场景

将要创造的对象的某一属性有特定类型,不能时任意类型,只能让用户选择类型进行生成。
用户可以仅仅通过调用类型对应的函数,便可得到对象。

核心处理方法

  • 构造函数声明为受保护的
  • 构造不同类型对象对应的生成方法

实现代码

#include<iostream>
#include <memory>
using namespace std;
enum class Material {
	brick,
	aerated_concrete,
	drywall
};

struct Point2D {  
	int x, y;
	Point2D(int xx, int yy) :x(xx), y(yy) {
	}
};

class Wall {
	Point2D start, end;
	int elevation, height;
public:
	
	Wall(Point2D start, Point2D end, int elevation, int height) 
	:start{ start }, end{ end }, elevation{ elevation }, height{ height } {
	}
};

class SolidWall :public Wall { 
	int width;
	Material material;
public:      //改为非public时,无法使用make_unique
	SolidWall(const Point2D start, const Point2D end, const int elevation, 
	const int height, const int width, const Material material) 
		:Wall(start, end, elevation, height), width{ width }, material{material}
	{
	
	}
public: 
 //以下是三种为工厂方法,强制用户创建特定类型而非任意类型的墙
	static SolidWall create_main(Point2D start, Point2D end, 
	int elevation, int height) {
		return SolidWall(start, end, elevation, height, 375, Material::aerated_concrete); 
		//按值返回
	}

	static unique_ptr<SolidWall> create_partition(Point2D start, Point2D end, 
	int elevation, int height) {
		return make_unique<SolidWall>(start, end, elevation, height, 120, Material::brick); 
		//按指针返回
	}
	static shared_ptr<Wall> create_wall(Point2D start, Point2D end,
	 int elevation, int height,Material type,int width) {
		return make_shared<SolidWall>(start, end, elevation, height, width, type);
		//多态形式,只能按指针返回	
	}
};
int main() {
	 auto main_wall = SolidWall::create_main({ 0,0 }, { 1,1 },100,200);//调用方法
}

抽象工厂模式

应用场景

可以追踪所有已经创建的对象,通过调用接口时选择属性,便可以返回对应类型的对象

核心处理方法

  • 最底层是一个抽象类用来派生。
  • 定义不同派生类,分别设置他们的属性
  • 设置顶层接口,用来交付给用户调用

代码实现

#include<iostream>
#include <memory>
#include<map>
using namespace std;

//----------------类型定义
struct HotDrink {
	virtual void prepare(int volume) = 0;
};

struct Tea:HotDrink
{
	void prepare(int volume) override {
		cout << "Tea " << endl;
	}
};
struct Coffee :HotDrink
{
	void prepare(int volume) override {
		cout << "Coffee " << endl;
	}
};
//----------------


//----------------抽象工厂基类,顾名思义声明为纯虚函数
class HotDrinkFactory {
public: virtual unique_ptr<HotDrink> make() const = 0;
};



//----------------派生各个工厂,各个工厂构造过程不同
class CoffeeFactory:public HotDrinkFactory { 
public:
	unique_ptr<HotDrink> make() const override {
		return make_unique<Coffee>();
	}
};

class TeaFactory :public HotDrinkFactory {
public:
	unique_ptr<HotDrink> make() const override {
		return make_unique<Tea>();
	}
};

//----------------定义最高级别接口,选择属性即可生成对象
class DrinkFactory {
	map<string, unique_ptr<HotDrinkFactory>> hot_factories;
public:
	DrinkFactory() {
		hot_factories["coffee"] = make_unique<CoffeeFactory>();
		hot_factories["tea"] = make_unique<TeaFactory>();
	}
	unique_ptr<HotDrink> make_drink(const string& name) {
		auto drink = hot_factories[name]->make();
		drink->prepare(200);
		return drink;
	}
};


int main() {
	DrinkFactory temp;  //顶级接口
	auto p1 = temp.make_drink("coffee");
}

工厂模式好处

  • 可以知道已经创建的特定类型的对象的数量。
  • 可以修改或者完全替换整个对象的创建过程
  • 使用智能指针时,则可以通过观察对象的引用次数获得对象全局的引用数量。
  • 相比于构造器模式,可以一次创造完整的对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值