设计模式(简单工厂模式、工厂模式、抽象工厂模式)

前提

当逻辑较为简单时,可以直接创建对应的类。代码如下:

#include<iostream>
using namespace std;

class apple
{
public:
	void eat()
	{
		cout<<"吃苹果"<<endl;
	}
};
class banana
{
public:
	void eat()
	{
		cout<<"吃香蕉"<<endl;
	}
};
class pear
{
public:
	void eat()
	{
		cout<<"吃梨"<<endl;
	}
};
int main()
{
	apple m_apple;
	m_apple.eat();
	banana m_banana;
	m_banana.eat();
	pear m_pear;
	m_pear.eat();
	system("pause");
	return 0;
}

通过此代码可以发现,用户直接与客户接触,违背了DIP(依赖倒转)原则,过于麻烦,所以引出简单工厂模式。

简单工厂模式

#include<iostream>
using namespace std;
#include<string>
class Fruit
{
public:
	virtual void eat() = 0;
};
class apple:public Fruit
{
public:
	void eat()
	{
		cout<<"吃苹果"<<endl;
	}
};
class banana:public Fruit
{
public:
	void eat()
	{
		cout<<"吃香蕉"<<endl;
	}
};
class pear:public Fruit
{
public:
	void eat()
	{
		cout<<"吃梨"<<endl;
	}
};
class factory
{
public:
	Fruit *createFruit(string name)
	{
		if(name=="苹果")
		{
			fruit = new apple;
		}
		if(name=="香蕉")
		{
			fruit = new banana;
		}
		if(name=="梨")
		{
			fruit = new pear;
		}
		return fruit;
	}
private:
	Fruit *fruit;
};
int main()
{
	factory m_factory;
	string apple = "苹果";
	string banana = "香蕉";
	string pear = "梨";
	Fruit *m_apple = m_factory.createFruit(apple);
	m_apple->eat();
	Fruit *m_banana = m_factory.createFruit(banana);
	m_banana->eat();
	Fruit *m_pear = m_factory.createFruit(pear);
	m_pear->eat();
	system("pause");
	return 0;
}

在简单工厂模式中,用户直接与factory(工厂)交互,而不与产品(水果)交互,体现了DIP原则,但是当需要添加新的产品时,需要在factory中修改代码,这不符合OCP(开闭原则),因此引入工厂模式

工厂模式

#include<iostream>
using namespace std;
#include<string>
class Fruit
{
public:
	virtual void eat() = 0;
};
class apple:public Fruit
{
public:
	void eat()
	{
		cout<<"吃苹果"<<endl;
	}
};
class banana:public Fruit
{
public:
	void eat()
	{
		cout<<"吃香蕉"<<endl;
	}
};
class pear:public Fruit
{
public:
	void eat()
	{
		cout<<"吃梨"<<endl;
	}
};
class factory
{
public:
	virtual Fruit *createFruit()=0;
};
class appleFactory:public factory
{
public:
	Fruit *createFruit()
	{
		return new apple;
	}
};
class bananaFactory:public factory
{
public:
	Fruit *createFruit()
	{
		return new banana;
	}
};
class pearFactory:public factory
{
public:
	Fruit *createFruit()
	{
		return new pear;
	}
};
int main()
{
	factory *m_appleFactory = new appleFactory;
	Fruit *m_apple = m_appleFactory->createFruit();
	m_apple->eat();

	factory *m_bananaFactory = new bananaFactory;
	Fruit *m_banana = m_bananaFactory->createFruit();
	m_banana->eat();

	factory *m_pearFactory = new pearFactory;
	Fruit *m_pear = m_pearFactory->createFruit();
	m_pear->eat();
	
	system("pause");
	return 0;
}

在工厂模式中,每个工厂都对应一个特定的产品,当需要添加新的产品时,只需要继承产品类和继承工厂类即可,这体现可OCP原则,解决了简单工厂的问题。但是当产品族和产品等级结构较复杂时,这时需要使用抽象工厂模式。下面介绍产品族和产品等级结构。

产品族和产品等级结构

图1
红色框为一个产品族,代表中国的苹果、中国的香蕉和中国的梨。
在这里插入图片描述
蓝色框为一个产品等级结构,代表中国的苹果、美国的苹果和英国的苹果

抽象工厂模式

如果使用工厂模式实现上图,需要对每个国家的每种水果都需要创建一个工厂,总共需要9个工厂。但是在抽象工厂模式中,仅需使用三个抽象工厂即可完成任务,代码如下:

#include<iostream>
using namespace std;
#include<string>
//抽象层
class Apple
{
public:
	virtual void eat() = 0;
};
class Banana
{
public:
	virtual void eat() = 0;
};
class Pear
{
public:
	virtual void eat() = 0;
};
class Factory
{
public:
	virtual Apple *eatApple()=0;
	virtual Banana *eatBanana()=0;
	virtual Pear *eatPear()=0;
};
//架构层
class Eat
{
public:
	void eatAll(Apple *apple,Banana *banana,Pear *pear)
	{
		m_apple = apple;
		m_banana = banana;
		m_pear = pear;
	}
	void show()
	{
		m_apple->eat();
		m_banana->eat();
		m_pear->eat();
	}
private:
	Apple *m_apple;
	Banana *m_banana;
	Pear *m_pear;
};
//实现层
//中国的水果
class ChinaApple:public Apple
{
public:
	void eat()
	{
		cout<<"吃中国苹果"<<endl;
	}
};
class ChinaBanana:public Banana
{
public:
	void eat()
	{
		cout<<"吃中国香蕉"<<endl;
	}
};
class ChinaPear:public Pear
{
public:
	void eat()
	{
		cout<<"吃中国梨"<<endl;
	}
};
class ChinaFactory:public Factory
{
public:
	Apple *eatApple()
	{
		return new ChinaApple;
	}
	Banana *eatBanana()
	{
		return new ChinaBanana;
	}
	Pear *eatPear()
	{
		return new ChinaPear;
	}
};
//美国的水果
class USAApple:public Apple
{
public:
	void eat()
	{
		cout<<"吃美国苹果"<<endl;
	}
};
class USABanana:public Banana
{
public:
	void eat()
	{
		cout<<"吃美国香蕉"<<endl;
	}
};
class USAPear:public Pear
{
public:
	void eat()
	{
		cout<<"吃美国梨"<<endl;
	}
};
class USAFactory:public Factory
{
public:
	Apple *eatApple()
	{
		return new USAApple;
	}
	Banana *eatBanana()
	{
		return new USABanana;
	}
	Pear *eatPear()
	{
		return new USAPear;
	}
};
//英国的水果
class UKApple:public Apple
{
public:
	void eat()
	{
		cout<<"吃英国苹果"<<endl;
	}
};
class UKBanana:public Banana
{
public:
	void eat()
	{
		cout<<"吃英国香蕉"<<endl;
	}
};
class UKPear:public Pear
{
public:
	void eat()
	{
		cout<<"吃英国梨"<<endl;
	}
};
class UKFactory:public Factory
{
public:
	Apple *eatApple()
	{
		return new UKApple;
	}
	Banana *eatBanana()
	{
		return new UKBanana;
	}
	Pear *eatPear()
	{
		return new UKPear;
	}
};

int main()
{
	//中国苹果、美国香蕉和英国梨
	//中国苹果
	Factory *chinaFactory = new ChinaFactory;
	Apple *chinaApple = chinaFactory->eatApple();
	//美国香蕉
	Factory *usaFactory = new USAFactory;
	Banana *usaBanana = usaFactory->eatBanana();
	//英国梨
	Factory *ukFactory = new UKFactory;
	Pear *ukPear = ukFactory->eatPear();
	Eat eat;
	eat.eatAll(chinaApple,usaBanana,ukPear);
	eat.show();
	system("pause");
	return 0;
}

当需要添加产品族时,只需要在原有Factory(工厂)基础上继承新的Factory,符合OCP原则。
但是当需要添加新的产品等级结构时,需要修改抽象类中的代码,不符合OCP原则,所有抽象工厂模式适用于产品等级结构确定的情况使用。

工厂三兄弟总结

简单工厂模式不是Gof中的,但是由于其使用方便,所以目前也被作为一种设计模式。
1.当逻辑简单时,使用简单工厂
2.当逻辑复杂,使用工厂模式
3.在2的前提下,产品等级结构确定时,使用抽象工厂模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值