C++设计模式之工厂方法模式(一)

1、工厂方法模式概述

    在简单工厂模式中只提供一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它需要知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类。简单工厂模式最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,需要在其中加入必要的业务逻辑,这违背了“开闭原则”。此外,在简单工厂模式中,所有的产品都由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,严重影响了系统的灵活性和扩展性,而工厂方法模式则可以很好地解决这一问题。

    在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构。工厂方法模式定义如下:

   工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),是一种类创建型模式。

    工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法,而由其子类来具体实现工厂方法,创建具体的产品对象。工厂方法模式结构如图所示: 

工厂方法模式结构图

    在工厂方法模式结构图中包含如下几个角色:

    Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。

    ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。

    Factory(抽象工厂):在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。

    ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户端调用,返回一个具体产品类的实例。


2、QQ空间背景风格的设计与实现


    项目需求:QQ空间提供了多种背景风格供用户选择,用户可以根据需要选择不同风格类型的背景装扮空间。现模仿QQ空间背景风格的实现,设计一套能够让用户自由选择的背景风格。要求系统具有弹性,能够拓展任意类型的背景风格。

    背景风格类实现代码如下:

#ifndef _BACKGROUND_STYLE_H_
#define _BACKGROUND_STYLE_H_
#include <iostream>
#include <string>
using namespace std;

//背景风格抽象类
class BackgroundStyle
{
public:
	//虚方法,显示背景风格
	virtual void DisplayStyle() = 0;
};


//古典风格背景类
class ClassicalStyle : public BackgroundStyle
{
public:
	void DisplayStyle()
	{
		cout << "古典风格背景" << endl;
	}
};


//潮流风格背景类
class FashionStyle : public BackgroundStyle
{
public:
	void DisplayStyle()
	{
		cout << "潮流风格背景" << endl;
	}
};


//艺术风格背景类
class ArtStyle : public BackgroundStyle
{
public:
	void DisplayStyle()
	{
		cout << "艺术风格背景" << endl;
	}
};

#endif

    BackgroundStyle背景风格抽象类是抽象的产品类,提供了一个DisplayStyle方法,显示具体的QQ背景风格。ClassicalStyle古典风格背景类、FashionStyle潮流风格背景类、ArtStyle艺术风格背景类是具体的产品类。

    背景风格工厂类实现代码如下:

#ifndef _STYLE_FACTORY_H_
#define _STYLE_FACTORY_H_

#include "backgroundStyle.h"


//背景风格抽象工厂
class StyleFactory
{
public:
	//工厂方法,具体背景风格由子类完成创建操作
	virtual BackgroundStyle * CreateBackGroundStyle() = 0;
};


//古典风格工厂
class ClassicalStyleFactory : public StyleFactory
{
public:
	BackgroundStyle * CreateBackGroundStyle()
	{
		BackgroundStyle * pClassicalStyle = new ClassicalStyle();

		return pClassicalStyle;
	}
};



//潮流风格工厂
class FashionStyleFactory : public StyleFactory
{
public:
	BackgroundStyle * CreateBackGroundStyle()
	{
		BackgroundStyle * pFashionStyle = new FashionStyle();

		return pFashionStyle;
	}
};




//艺术风格工厂
class ArtStyleFactory : public StyleFactory
{
public:
	BackgroundStyle * CreateBackGroundStyle()
	{
		BackgroundStyle * pArtStyle = new ArtStyle();

		return pArtStyle;
	}
};


#endif
    
<span style="font-family:SimSun;font-size:18px;">    StyleFactory背景风格抽象工厂,该抽象类中提供一个工厂方法CreateBackGroundStyle,用于创建具体的QQ背景样式。具体创建QQ背景样式的过程由子类工厂去实现。具体的工厂如:ClassicalStyleFactory古典风格工厂,创建古典风格的背景样式;FashionStyleFactory潮流风格工厂,创建潮流风格背景样式;ArtStyleFactory艺术风格工厂,创建艺术风格的背景样式。</span>
    测试文件实现代码如下:
#include <iostream>
#include "backgroundStyle.h"
#include "StyleFactory.h"

using namespace std;


int main()
{

	BackgroundStyle * pBackgroundStyle = NULL;

	/**********************创建古典风格背景***************************/
	StyleFactory * pClassicalStyleFactory = new ClassicalStyleFactory();
	pBackgroundStyle = pClassicalStyleFactory->CreateBackGroundStyle();
	pBackgroundStyle->DisplayStyle();

	delete pClassicalStyleFactory;
	pClassicalStyleFactory = NULL;

	delete pBackgroundStyle;
	pBackgroundStyle = NULL;

	/**********************创建潮流风格工厂***************************/
	StyleFactory * pFashionStyleFactory = new FashionStyleFactory();
	pBackgroundStyle = pFashionStyleFactory->CreateBackGroundStyle();
	pBackgroundStyle->DisplayStyle();
	
	delete pFashionStyleFactory;
	pFashionStyleFactory = NULL;
	
	delete pBackgroundStyle;
	pBackgroundStyle = NULL;

	/**********************创建艺术风格工厂***************************/
	StyleFactory * pArtStyleFactory = new ArtStyleFactory();
	pBackgroundStyle = pArtStyleFactory->CreateBackGroundStyle();
	pBackgroundStyle->DisplayStyle();
	
	delete pArtStyleFactory;
	pArtStyleFactory = NULL;
	
	delete pBackgroundStyle;
	pBackgroundStyle = NULL;

	return 0;
}

    编译并执行,结果如下:


    如果需要添加其它风格的QQ背景,只需要定义一个其它风格的背景类,继承于抽象背景风格类;定义一个对应的工厂类,继承于抽象背景风格工厂类就可以了,不需要修改之前的代码,符合"开放封闭原则"。对于每一个背景风格类,都有一个创建该背景风格的工厂类与之相对应,符合"单一原则"。客户端只需要认识抽象的背景风格类就可以了,不需要认识具体背景风格类,降低了客户端和具体背景风格类的耦合度。也就是说客户端针对接口进行编程,符合"针对接口进行编程而不是针对具体进行编程原则"。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值