设计模式之工厂模式

一、工厂模式概述

       工厂生产产品、产量大、质量保证、在程序中生产某一类对象,不用担心生产对象有问题,只要工厂类没有问题,可以生产很多种对象、但是必须是兄弟关系、都继承一个父类。

二、简单工厂模式

简单工厂模式创建步骤:

  • 创建一个新的类,可以称之为工厂类,对于简单工厂模式来说,需要的工厂类只有一个。
  • 在这个工厂类里面添加一个公共成员函数,通过这个函数我们可以创建需要的对象,这个函数可以称之为工厂函数。
  • 关于使用,首先创建一个工厂类的对象,通过这个对象调用工厂函数,这样就可以生产出指定类型的实例对象(兄弟关系)。

三、简单工厂模式代码及解释

// 定义抽象汽车类
class AbstractCar
{
public:
	virtual void engine() = 0;  // 纯虚函数,定义发动机相关操作,子类需实现
	virtual void chassis() = 0; // 纯虚函数,定义底盘相关操作,子类需实现
	virtual ~AbstractCar() {}  // 虚析构函数,确保正确释放子类对象资源
};

// 轿车类,继承自抽象汽车类
class SedanCar : public AbstractCar
{
public:
	virtual void engine() override  // 重写父类的发动机操作
	{
		cout << "轿车->小型汽油发动机" << endl;
	}
	virtual void chassis() override  // 重写父类的底盘操作
	{
		cout << "轿车->轻型底盘" << endl;
	}
};

// SUV 类,继承自抽象汽车类
class SUVCar : public AbstractCar
{
public:
	virtual void engine() override  // 重写父类的发动机操作
	{
		cout << "SUV->大型汽油发动机" << endl;
	}
	virtual void chassis() override  // 重写父类的底盘操作
	{
		cout << "SUV->坚固底盘" << endl;
	}
};

// 卡车类,继承自抽象汽车类
class TruckCar : public AbstractCar
{
public:
	virtual void engine() override  // 重写父类的发动机操作
	{
		cout << "卡车->柴油发动机" << endl;
	}
	virtual void chassis() override  // 重写父类的底盘操作
	{
		cout << "卡车->重载底盘" << endl;
	}
};

enum class Type :char { SedanCar, SUVCar, TruckCar };  // 定义一个枚举类型,表示汽车类型

class CarFactor
{
public:
	AbstractCar * createCar(Type type)  // 根据给定的汽车类型创建相应的汽车对象
	{
		AbstractCar*ptr = nullptr;  // 初始化指针为空
		switch (type)  // 根据传入的汽车类型进行选择
		{
		case Type::SedanCar:  // 如果是轿车类型
			ptr = new SedanCar;  // 创建轿车对象
			break;
		case Type::SUVCar:  // 如果是 SUV 类型
			ptr = new SUVCar;  // 创建 SUV 对象
			break;
		case Type::TruckCar:  // 如果是卡车类型
			ptr = new TruckCar;  // 创建卡车对象
			break;
		}
		return ptr;  // 返回创建的汽车对象指针
	}
};

int main()
{
	CarFactor*factory = new CarFactor;  // 创建汽车工厂对象
	AbstractCar*obj = factory->createCar(Type::SedanCar);  // 创建轿车对象
	obj->engine();  // 调用轿车的发动机操作
	obj->chassis();  // 调用轿车的底盘操作
	delete obj;  // 释放轿车对象内存
	delete factory;  // 释放工厂对象内存
	return 0;
}

大致思路:在产品类的父类中定义一些接口也就是虚函数,定义为纯虚函数子类必须要重写这个方法,给父类提供一个虚析构函数,多态避免内存泄漏,再定义几个子类继承父类,创建一个工厂类,创建公共成员函数,参数定义枚举可以进行错误检查,工厂函数内部通过switch进行判断,用父类指针指向子类对象,主函数创建工厂类的对象,听过工厂对象调用工厂方法。简单工厂模式其实是对多态的一个应用。

简单工厂模式缺点:已经开发好的不能进行修改如果只有一个工厂函数那可定会修改、工厂函数内部代码量太多不容易被维护、可读性随着代码增越来越低。

四、工厂模式

        工厂模式是对简单工厂的解耦、一对一的关系创建n个工厂类、削弱了工厂类的功能尽可能让工厂类的功能单一、遵循单一原则。遵循设计模式三原则、增加新的可以直接添加子工厂类不需要修改。

工厂模式对简单工厂的解耦合

在简单工厂模式中,工厂类通常包含了创建所有产品对象的逻辑,这导致工厂类的职责过于复杂和庞大。而工厂模式通过将每个产品的创建逻辑分离到各自对应的工厂类中,实现了工厂类与产品类之间的解耦合。

例如,在汽车制造的例子中,简单工厂可能在一个类中处理轿车、SUV 和卡车的创建,而工厂模式则为轿车、SUV 和卡车分别创建独立的工厂类。

一对一的关系创建 n 个工厂类

每个具体的产品都有一个对应的工厂类,建立了明确的一对一映射关系。这种明确的关系使得系统的结构更加清晰和易于理解。

比如,有轿车产品就有轿车工厂类,有 SUV 产品就有 SUV 工厂类,不会出现一个工厂类负责多种差异较大的产品创建。

削弱工厂类的功能,让其功能单一

每个工厂类只专注于创建一种特定类型的产品,功能变得单一而明确。这符合单一职责原则,即一个类应该只有一个引起它变化的原因。

以汽车工厂为例,轿车工厂只关心如何创建轿车,不需要了解 SUV 或卡车的创建细节,降低了工厂类内部的复杂性。

五、工厂模式代码及解释

// 定义抽象汽车类
class AbstractCar
{
public:
	virtual void engine() = 0;  // 发动机
	virtual void chassis() = 0; // 底盘
	virtual ~AbstractCar() {}
};

// 轿车类,继承自抽象汽车类
class SedanCar : public AbstractCar
{
public:
	virtual void engine() override
	{
		cout << "轿车->小型汽油发动机" << endl;
	}
	virtual void chassis() override
	{
		cout << "轿车->轻型底盘" << endl;
	}
};

// SUV 类,继承自抽象汽车类
class SUVCar : public AbstractCar
{
public:
	virtual void engine() override
	{
		cout << "SUV->大型汽油发动机" << endl;
	}
	virtual void chassis() override
	{
		cout << "SUV->坚固底盘" << endl;
	}
};

// 卡车类,继承自抽象汽车类
class TruckCar : public AbstractCar
{
public:
	virtual void engine() override
	{
		cout << "卡车->柴油发动机" << endl;
	}
	virtual void chassis() override
	{
		cout << "卡车->重载底盘" << endl;
	}
};

// 定义工厂类(父类)
class CarFactory
{
public:
	virtual AbstractCar* createCar() = 0;
	virtual ~CarFactory() {}
};

// 轿车工厂类,继承自工厂类
class SedanCarFactory : public CarFactory
{
public:
	AbstractCar* createCar()
	{
		return new SedanCar;
	}
	~SedanCarFactory()
	{
		cout << "SedanCarFactory 被析构掉了" << endl;
	}
};

// SUV 工厂类,继承自工厂类
class SUVCarFactory : public CarFactory
{
public:
	AbstractCar* createCar()
	{
		return new SUVCar;
	}
	~SUVCarFactory()
	{
		cout << "SUVCarFactory 被析构掉了" << endl;
	}
};

// 卡车工厂类,继承自工厂类
class TruckCarFactory : public CarFactory
{
public:
	AbstractCar* createCar()
	{
		return new TruckCar;
	}
	~TruckCarFactory()
	{
		cout << "TruckCarFactory 被析构掉了" << endl;
	}
};

int main()
{
	CarFactory* factory = new SedanCarFactory;
	AbstractCar* obj = factory->createCar();
	obj->engine();
	obj->chassis();
	delete obj;
	delete factory;
	return 0;
}

总的来说,工厂模式通过解耦合、功能单一化和遵循设计原则,使得软件系统在面对产品种类的变化和扩展时,能够更加灵活、易于维护和扩展,减少了因为修改现有代码而引入新错误的风险。

 本篇文章主要通过制造汽车这个场景介绍了简单工厂模式工厂模式,希望您可以对工厂模式有一个初步理解!看完点赞哟(爱心)!


 

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工厂模式是一种常见的创建型设计模式,用于创建对象,而不是通过直接调用构造函数来创建它们。工厂模式定义了一个接口,用于创建相关对象,但是让子类决定要实例化的类。在C++中,工厂模式可以通过以下步骤实现: 1. 创建一个抽象基类,该类定义了一个纯虚拟函数,该函数将返回一个指向基类的指针。这个基类就是我们的工厂接口。 ```c++ class Product { public: virtual ~Product() {} virtual void operation() = 0; }; ``` 2. 创建具体的产品类,它们继承自抽象基类,并实现了其纯虚拟函数。这些类就是我们的具体产品。 ```c++ class ConcreteProductA : public Product { public: void operation() override { /* 具体产品 A 的操作 */ } }; class ConcreteProductB : public Product { public: void operation() override { /* 具体产品 B 的操作 */ } }; ``` 3. 创建一个工厂类,该类实现了工厂接口,并根据需要创建具体的产品。这个工厂类就是我们的具体工厂。 ```c++ class Factory { public: virtual ~Factory() {} virtual std::unique_ptr<Product> createProduct() = 0; }; class ConcreteFactoryA : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductA>(); } }; class ConcreteFactoryB : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductB>(); } }; ``` 4. 在客户端代码中使用具体工厂创建具体产品。 ```c++ int main() { std::unique_ptr<Factory> factory = std::make_unique<ConcreteFactoryA>(); std::unique_ptr<Product> product = factory->createProduct(); product->operation(); return 0; } ``` 这就是工厂模式的基本实现方式。通过这种方式,我们可以将对象的创建过程与客户端代码分离,从而更好地实现模块化和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值