C++设计模式-Factory工厂模式
Factory
1、定义创建对象的接口,封装对象的创建
2、将实际创建工作延迟到子类中,例如,类A中药使用类B,B是抽象父类,但是在类A中不知道具体要实例化哪一个B的子类,但是在类A的子类D中是可以知道的。在A中无法使用 new B***()方法
3、将创建工作延迟到子类中后,核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂,只提供工厂子类必须实现的接口,这样的好处是可以不用修改已有的工厂类的情况下增加新的产品(每一种产品,都分别对应相应的工厂子类负责其创建工作)
使用场景:用于一类类(所创建的产品继承共同的产品基类)的创建
实现方式1:所谓的工厂方法模式,对每一个子类产品都分别对应一个工厂子类,用来创建相应的产品,这样若增加了新的产品,只需相应增加工厂子类即可
优点:不用修改已有代码,开放封闭原则:对扩展开放,对更改封闭
代码如下:
//IHuman.h #pragma once
class IHuman
{
public:
IHuman(void)
{
}
virtual ~IHuman(void)
{
}
virtual void Laugh() = ;
virtual void Cry() = ;
virtual void Talk() = ;
}; //YellowHuman.h #pragma once
#include "ihuman.h"
class CYellowHuman :
public IHuman
{
public:
CYellowHuman(void);
~CYellowHuman(void);
void Laugh();
void Cry();
void Talk();
}; //YellowHuman.cpp #include "StdAfx.h"
#include "YellowHuman.h"
#include <iostream>
using std::cout;
using std::endl;
CYellowHuman::CYellowHuman(void)
{
}
CYellowHuman::~CYellowHuman(void)
{
}
void CYellowHuman::Cry()
{
cout << "黄色人种会哭" << endl;
}
void CYellowHuman::Laugh()
{
cout << "黄色人种会大笑,幸福呀!" << endl;
}
void CYellowHuman::Talk()
{
cout << "黄色人种会说话,一般说的都是双字节" << endl;
} //WhiteHuman.h #pragma once
#include "ihuman.h"
class CWhiteHuman :
public IHuman
{
public:
CWhiteHuman(void);
~CWhiteHuman(void);
void Laugh();
void Cry();
void Talk();
}; //WhiteHuman.cpp #include "StdAfx.h"
#include "WhiteHuman.h"
#include <iostream>
using std::cout;
using std::endl;
CWhiteHuman::CWhiteHuman(void)
{
}
CWhiteHuman::~CWhiteHuman(void)
{
}
void CWhiteHuman::Cry()
{
cout << "白色人种会哭" << endl;
}
void CWhiteHuman::Laugh()
{
cout << "白色人种会大笑,侵略的笑声" << endl;
}
void CWhiteHuman::Talk()
{
cout << "白色人种会说话,一般都是单字节" << endl;
} //BlackHuman.h #pragma once
#include "ihuman.h"
class CBlackHuman :
public IHuman
{
public:
CBlackHuman(void);
~CBlackHuman(void);
void Laugh();
void Cry();
void Talk();
}; //BlackHuman.cpp #include "StdAfx.h"
#include "BlackHuman.h"
#include <iostream>
using std::cout;
using std::endl;
CBlackHuman::CBlackHuman(void)
{
}
CBlackHuman::~CBlackHuman(void)
{
}
void CBlackHuman::Cry()
{
cout << "黑人会哭" << endl;
}
void CBlackHuman::Laugh()
{
cout << "黑人会笑" << endl;
}
void CBlackHuman::Talk()
{
cout << "黑人可以说话,一般人听不懂" << endl;
} //IHumanFactory.h #pragma once
#include "IHuman.h"
class IHumanFactory
{
public:
IHumanFactory(void)
{
}
virtual ~IHumanFactory(void)
{
}
virtual IHuman * CreateHuman() = ;
};
//YellowHuman.h #pragma once
#include "ihumanfactory.h"
class CYellowHumanFactory :
public IHumanFactory
{
public:
CYellowHumanFactory(void);
~CYellowHumanFactory(void);
virtual IHuman * CreateHuman(void);
}; //YellowHumanFactory.cpp #include "StdAfx.h"
#include "YellowHumanFactory.h"
#include "YellowHuman.h"
CYellowHumanFactory::CYellowHumanFactory(void)
{
}
CYellowHumanFactory::~CYellowHumanFactory(void)
{
}
IHuman * CYellowHumanFactory::CreateHuman( void )
{
return new CYellowHuman();
}
//WhiteHuman.h #pragma once
#include "ihumanfactory.h"
class CWhiteHumanFactory :
public IHumanFactory
{
public:
CWhiteHumanFactory(void);
~CWhiteHumanFactory(void);
virtual IHuman * CreateHuman(void);
}; //WhiteHumanFactory.cpp #include "StdAfx.h"
#include "WhiteHumanFactory.h"
#include "WhiteHuman.h"
CWhiteHumanFactory::CWhiteHumanFactory(void)
{
}
CWhiteHumanFactory::~CWhiteHumanFactory(void)
{
}
IHuman * CWhiteHumanFactory::CreateHuman( void )
{
return new CWhiteHuman();
}
//BlackHuman.h #pragma once
#include "ihumanfactory.h"
class CBlackHumanFactory :
public IHumanFactory
{
public:
CBlackHumanFactory(void);
~CBlackHumanFactory(void);
virtual IHuman * CreateHuman();
};
//BlackHumanFactory.cpp #include "StdAfx.h"
#include "BlackHumanFactory.h"
#include "BlackHuman.h"
CBlackHumanFactory::CBlackHumanFactory(void)
{
}
CBlackHumanFactory::~CBlackHumanFactory(void)
{
}
IHuman * CBlackHumanFactory::CreateHuman()
{
return new CBlackHuman();
} //FactoryMethod.cpp // FactoryMethod.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "IHuman.h"
#include "YellowHuman.h"
#include "WhiteHuman.h"
#include "BlackHuman.h"
#include "SimpleHumanFactory.h"
#include "StandardHumanFactory.h"
#include "IHumanFactory.h"
#include "YellowHumanFactory.h"
#include "WhiteHumanFactory.h"
#include "BlackHumanFactory.h"
#include <iostream>
using std::cout;
using std::endl;
using std::string;
void DoFactoryMethod1()
{
cout << "----------第一批人是这样的:黄种人工厂来生产黄种人" << endl;
IHumanFactory *pHumanFactory = new CYellowHumanFactory();
IHuman *pHuman = pHumanFactory->CreateHuman();
pHuman->Cry();
pHuman->Laugh();
pHuman->Talk();
delete pHuman;
delete pHumanFactory;
}
void DoFactoryMethod2()
{
cout << "----------第二批人是这样的:白种人工厂来生产白种人" << endl;
IHumanFactory *pHumanFactory = new CWhiteHumanFactory();
IHuman *pHuman = pHumanFactory->CreateHuman();
pHuman->Cry();
pHuman->Laugh();
pHuman->Talk();
delete pHuman;
delete pHumanFactory;
}
void DoFactoryMethod3()
{
cout << "----------第一批人是这样的:黑种人工厂来生产黑种人" << endl;
IHumanFactory *pHumanFactory = new CBlackHumanFactory();
IHuman *pHuman = pHumanFactory->CreateHuman();
pHuman->Cry();
pHuman->Laugh();
pHuman->Talk();
delete pHuman;
delete pHumanFactory;
}
int _tmain(int argc, _TCHAR* argv[])
{
//工厂方法
cout << "----------工厂方法:" << endl;
DoFactoryMethod1();
DoFactoryMethod2();
DoFactoryMethod3(); _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
_CrtDumpMemoryLeaks();
return ;
}
实现方式2:所谓的简单工厂模式,通过参数传递来决定要创建哪一个具体产品。
若不需延迟实例化(将实例化放到子类中),则在Factory中增加对应的创建方法即可,如:Product* CreateConcreteProduct(int i);
若需要延迟实例化,则在抽象Factory与具体ConcreteFactory中增加相应方法,在ConcreteFactory中实现方法Product* CreateConcreteProduct(int i)
优点:无需新增产品工厂类ConcreteFactory
缺点:需要修改已有代码,存在风险
代码如下:
//Product.h
// Product.h: interface for the Product class.
//
////////////////////////////////////////////////////////////////////// #if !defined(AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_)
#define AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 class Product
{
public:
Product();
virtual ~Product(); }; class ConcreteProduct : public Product
{
public:
ConcreteProduct();
virtual ~ConcreteProduct(); }; class ConcreteProduct1 : public Product
{
public:
ConcreteProduct1();
virtual ~ConcreteProduct1(); }; #endif // !defined(AFX_PRODUCT_H__714E1D10_AFA3_473E_A16C_759490E60B92__INCLUDED_) //Product.cpp
// Product.cpp: implementation of the Product class.
//
////////////////////////////////////////////////////////////////////// #include "Product.h"
#include <iostream> using namespace std; //////////////////////////////////////////////////////////////////////
// Construction/Destruction
////////////////////////////////////////////////////////////////////// Product::Product()
{
} Product::~Product()
{
} ConcreteProduct::ConcreteProduct()
{
cout<<"ConcreteProduct..."<<endl;
} ConcreteProduct::~ConcreteProduct()
{
} ConcreteProduct1::ConcreteProduct1()
{
cout<<"ConcreteProduct1..."<<endl;
} ConcreteProduct1::~ConcreteProduct1()
{
} //Factory.h #if !defined(AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_)
#define AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 class Product;
class Factory
{
public:
virtual Product* CreateConcreteProduct(int i)=;
Factory();
virtual ~Factory() = ;
virtual Product* CreateProduct() = ;
virtual Product* CreateProduct1() = ;
}; class ConcreteFactory : public Factory
{
public:
ConcreteFactory();
virtual ~ConcreteFactory();
virtual Product* CreateProduct();
virtual Product* CreateProduct1();
virtual Product* CreateConcreteProduct(int i);
}; #endif // !defined(AFX_FACTORY_H__32B11FEA_57A7_484E_B289_AB0E12783D7D__INCLUDED_) //Factory.cpp // Factory.cpp: implementation of the Factory class.
//
////////////////////////////////////////////////////////////////////// #include "Factory.h"
#include "Product.h"
#include <iostream> using namespace std; //////////////////////////////////////////////////////////////////////
// Construction/Destruction
////////////////////////////////////////////////////////////////////// Factory::Factory()
{
} Factory::~Factory()
{
} ConcreteFactory::ConcreteFactory()
{
cout<<"ConcreteFactory..."<<endl;
} ConcreteFactory::~ConcreteFactory()
{
} Product* ConcreteFactory::CreateProduct()
{
return new ConcreteProduct();
} Product* ConcreteFactory::CreateProduct1()
{
return new ConcreteProduct1();
} Product* ConcreteFactory::CreateConcreteProduct(int i)
{
Product* pProduct = NULL;
switch(i)
{
case :
pProduct = new ConcreteProduct();
break;
case :
pProduct = new ConcreteProduct1();
break;
default:
break;
}
return pProduct;
} //main.cpp
#include "Factory.h"
#include "Product.h"
#include <iostream> using namespace std; int main()
{
Factory* pFactory = new ConcreteFactory(); Product* pProduct = pFactory->CreateProduct1(); //Product* pProduct = pFactory->CreateConcreteProduct(1);
return ;
}
若要为不同类的类提供一个创建对象的接口,要用AbstractFactory。
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式可以分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
区别
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
两者皆可。
C++设计模式-Factory工厂模式的更多相关文章
- 设计模式之工厂模式(Factory)
设计模式的工厂模式一共有三种:简单工厂模式,工厂模式,抽象工厂模式 简单工厂模式原理:只有一个工厂类,通过传参的形式确定所创建的产品对象种类 代码如下: #include <stdio.h> ...
- Java设计模式之工厂模式(Factory模式)介绍(转载)
原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...
- Golang设计模式—简单工厂模式(Simple Factory Pattern)
Golang设计模式--简单工厂模式 背景 假设我们在做一款小型翻译软件,软件可以将德语.英语.日语都翻译成目标中文,并显示在前端. 思路 我们会有三个具体的语言翻译结构体,或许以后还有更多,但现在分 ...
- 设计模式之工厂模式(Factory)
转载请标明出处:http://blog.csdn.net/shensky711/article/details/53348412 本文出自: [HansChen的博客] 设计模式系列文章: 设计模式之 ...
- python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)
十一回了趟老家,十一前工作一大堆忙成了狗,十一回来后又积累了一大堆又 忙成了狗,今天刚好抽了一点空开始写工厂方法模式 我看了<Head First 设计模式>P109--P133 这25页 ...
- 设计模式——抽象工厂模式及java实现
设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...
- iOS 设计模式之工厂模式
iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...
- 浅析JAVA设计模式之工厂模式(一)
1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...
- java 设计模式之工厂模式与反射的结合
工厂模式: /** * @author Rollen-Holt 设计模式之 工厂模式 */ interface fruit{ public abstract void eat(); } ...
随机推荐
- DTO概念
在开发过程中用到了DTO,简单了解了一下. DTO:数据传输对象,用来连接表现层和应用层之间的数据交互.数据传输对象是没有行为的POJO对象,它的目的只是为了对领域对象进行数据封装,实现层与层之间的数 ...
- iframe自定义高度
function setIframeHeight() { var iframe=document.getElementById("iframe_id"); iframe.heigh ...
- JavaScript基础--面向对象三大特性(八):继承封装多态
一.构造函数基本用法:function 类名(参数列表){ 属性=参数值} function Person(name,age){ this.name = name; this.age = age; } ...
- tornado autoreload 模式
在用tornado进行 网络程序编写的时候,肯定要对代码进行修修改改,如果每次都要重启server的话,会是很麻烦的事情.tornado提供了autoreload模式. 一,要开始autoreload ...
- C++ Daily《2》----vector容器的resize 与 reserve的区别
C++ STL 库中 vector 容器的 resize 和 reserve 区别是什么? 1. resize 改变 size 大小,而 reserve 改变 capacity, 不改变size. 2 ...
- c/c++ 函数指针 指针函数 数组的引用 指针数组 数组指针
1.指针数组数组指针 引用数组 数组的引用 int *a[10] 指针数组 每一个元素都是一个指针 Int (*a)[10] 数组指针 P指向一个含有10个元素的数组 Int (&a)[10] ...
- Debugging Process Startup
Debugging Process Startup Q: How do I debug a process's startup code? A: This depends on how the pr ...
- F - To the Max
Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous s ...
- tensorflow2
# step1 加载包import tensorflow as tf import numpy as np # step2 输入:随机产生数据 # Create 100 phony x, y data ...
- Mac下到Linux主机ssh免密码登录
最近忙得忘乎所以,写篇博客放松放松,RT,直接上命令好了 # Local ssh-keygen -t rsa scp ~/.ssh/id_rsa.pub username@server:~/.ssh/ ...