浅谈设计模式-工厂模式的设计思想以及细节问题(上篇)
  AWwQJA71Um8k 2023年12月13日 21 0
  1. 1什么是工厂模式?

工厂模式,顾名思义,就是把将对象的实例化过程封装在工厂类中的方式。工厂负责生产相应的对象实例。

一般分为两种工厂模式:简单工厂;抽象工厂

优点:

  • 用户不需要解决具体的细节问题,利用工厂类进行生产产品细节;
  • 可以将对象的创建与使用代码分离,提供一种统一的接口来创建不同类型的对象。
  • 创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

缺点:简单工厂;抽象工厂各有各自的优缺点(后面详细展开)

  1. 2简单工厂SimpleFactory

浅谈设计模式-工厂模式的设计思想以及细节问题(上篇)_简单工厂

UML 类图分析:

1、抽象产品 (AbstractProduct)

2、产品的具体实现类(Product1 和 Product2)

3、工厂类 (Factory)

代码示例

头文件

抽象产品类Phone,提供虚函数接口
#ifndef _PHONE_HEAD_H
#define _PHONE_HEAD_H

class AbstractPhone
{
public:
	AbstractPhone() { std::cout << "AbstractPhone的构造函数 " << std::endl; }
	virtual ~AbstractPhone() { std::cout << "AbstractPhone的析构函数 " << std::endl; }

	virtual void  call() = 0;
	virtual void message() = 0;
};

#endif 


工厂类,提供父类指针指向函数接口,用来创建出相应的子类对象;
#ifndef _SIMPLE_FACTORY_HEAD_H
#define _SIMPLE_FACTORY_HEAD_H
#include"AndroidPhone.h"
#include"Iphone.h"
//#include<memory>
//工厂类,用于生产手机
class SimpleFactory
{
public:


	SimpleFactory() {
		std::cout << "SimpleFactory() call " << std::endl;
	}
	 ~SimpleFactory() {
		std::cout << "~SimpleFactory() call " << std::endl;
	}

	//使用多态,父类指针指向函数接口,用来创建出相应的子类对象
	static AbstractPhone* getPhone(const string &name ) {

		if (name == "AndroidPhone") {

			return new AndroidPhone;
		}
		else if (name == "Iphone") {

			return new IPhone;
		}		

		return nullptr;
	}

};

#endif

具体产品类安卓手机类,继承抽象产品Phone类,并且使用多态
#ifndef _ANDROID_PHONE_HEAD_H
#define _ANDROID_PHONE_HEAD_H
#include"Phone.h"
#include<iostream>
using namespace std;
class AndroidPhone :public AbstractPhone
{
public:

	AndroidPhone() {
		cout << "AndroidPhone构造函数 " << endl;
	}
	~AndroidPhone() {
		cout << "~AndroidPhone析构函数 " << endl;
	}

	void call() override {
		cout << "AndroidPhone call " << endl;
	}

	void message() override {
		cout << "AndroidPhone message " << endl;
	}


};

#endif // !_ANDROID_PHONE_HEAD_H

具体产品类Iphone类,继承抽象产品Phone类,并且使用多态
#ifndef _ANDROID_PHONE_HEAD_H
#define _ANDROID_PHONE_HEAD_H
#include"Phone.h"
#include<iostream>
using namespace std;
class AndroidPhone :public AbstractPhone
{
public:

	AndroidPhone() {
		cout << "AndroidPhone构造函数 " << endl;
	}
	~AndroidPhone() {
		cout << "~AndroidPhone析构函数 " << endl;
	}

	void call() override {
		cout << "AndroidPhone call " << endl;
	}

	void message() override {
		cout << "AndroidPhone message " << endl;
	}


};
#endif // !_ANDROID_PHONE_HEAD_H

main.cpp文件
#include<iostream>
#include"SimpleFactory.h"
using namespace std;

//mian函数中只需要向工厂要手机即可

int main()
{
	AbstractPhone* androidPhone = SimpleFactory::getPhone("AndroidPhone");
	AbstractPhone* iPhone = SimpleFactory::getPhone("Iphone");

	androidPhone->call();
	androidPhone->message();
	cout << "----------------------" << endl;
	iPhone->call();
	iPhone->message();

	return 0;
}

简单分析一下simple factory模式缺点

阅读上述代码不难发现,具体的产品都是通过这个函数来实例化的

static AbstractPhone* getPhone(const string &name ) 

而如果有新的需求,生产新产品锤子手机,就需要在该函数中修改添加相应代码;而如果需要有很多的新的需求呢,或者变更了需求呢,修改就随之变得非常繁琐;

在面向对象开发中有一个很重要的原则︰

开闭原则概念(程序扩展是开放的,程序修改是封闭的,扩展优于修改),在新增产品时,很明显的,我们要修改原有的工厂代码,违背了开闭原则。


  1. 3.抽象工厂AbstructFactory模式

引入抽象工厂模式时,不能说这个模式就一定高大上,主要还是看使用场景与工厂方法模式相比;

抽象 工厂模式主要是打破了工厂与产品一对一,使得具体工厂可以创造一个大类产品 (一系列产品)

浅谈设计模式-工厂模式的设计思想以及细节问题(上篇)_简单工厂_02

UML 类图分析:

  1. 引入了新的产品维度 (产品 A\B),即在原本的产品维度(1\2)基础上加上了产品维度(AB)
  2. 创建两个大类产品接口 AbstractProductA 和 AbstractProductB
  3. 编写产品的具体实现类: ProductA1、ProductA2、ProductB1,ProductB2
  4. 针对大类产品接口,编写大类工厂接口 AbstractFactory
  5. 编写俩个大类工厂类: ConcreteFactory1、 ConcreteFactory2

代码演示

//抽象父类按钮产品接口
class Button
{
public:
	
	Button()
	{
		cout << "父类Button的构造函数" << endl;
	}
	virtual ~Button()
	{
		cout << "父类Button的析构函数" << endl;
	}

	//抽象的产品接口render(),纯虚函数
	virtual void render() = 0;
};

//抽象工厂接口
class AbstructFactory
{
public:
	AbstructFactory()
	{
		cout << "父类AbstructFactory的构造函数 " << endl;
	}

	virtual ~AbstructFactory()
	{
		cout << "父类AbstructFactory的析构函数 " << endl;
	}
	//Button类指针指向一个纯虚函数,用于创建产品
	virtual Button* createButton() = 0;
};

//具体生产某一类Android产品的工厂,继承抽象工厂的接口
class AndroidFactory:public AbstructFactory
{
public:

	AndroidFactory()
	{
		cout << "AndroidFactory工厂的构造函数 " << endl;
	}

	 ~AndroidFactory()
	{
		cout << "AndroidFactory工厂的析构函数 " << endl;
	}

	Button* createButton() override {
		return new AndroidButton;
	}
};

//具体生产某一类IphoneFactory产品的工厂,继承抽象工厂的接口
class IphoneFactory :public AbstructFactory
{
public:

	IphoneFactory()
	{
		cout << "Iphone工厂的构造函数 " << endl;
	}

	~IphoneFactory()
	{
		cout << "Iphone工厂的析构函数 " << endl;
	}


	Button* createButton() override {
		return new IphoneButton;
	}
};

main.cpp

int main()
{
	AbstractPhone* androidPhone = SimpleFactory::getPhone("AndroidPhone");
	AbstractPhone* iPhone = SimpleFactory::getPhone("Iphone");

	androidPhone->call();
	androidPhone->message();
	cout << "----------------------" << endl;
	iPhone->call();
	iPhone->message();
  
	return 0;
}

不难发现 抽象工厂的设计思路与简单工厂不同:

  • 抽象工厂不仅提供了 抽象的工厂泛类 还提供了 产品的泛类
  • 具体工厂继承抽象工厂,具体产品继承抽象产品;并都使用多态

那么这样做的好处:

  • 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么产品的创建过程。
  • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
  • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合 “开闭原则”。

感谢看到这里,

下篇我将分析一下工厂模式中的一些细节问题,以及在程序设计的时候需要注意的问题

敬请期待后续更新中.....



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月13日 0

暂无评论

推荐阅读
AWwQJA71Um8k