这两天学习了下设计模式中的工厂模式,写个总结方便以后记忆和查看。
工厂模式包括:简单工厂模式、工厂方法模式和抽象工厂模式,其中简单工厂模式不是23种标准的设计模式
并且简单工厂模式也没有遵循开闭原则,抽象工厂模式在每一个系列的子系列中符合开闭原则,整个系列不符合,
下面将通过实例分别来讲解三种设计模式
是简单工厂模式的核心,它负责实现创建所有工厂实例的内部逻辑。工厂类可以被外界直接调用,创建用户需要的产品对象
抽象产品角色:
是简单工厂模式所有创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
还需要在工厂类中增加创建的条件。
负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
当一个类希望由它的子类来指定它所创建的对象的时候
负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
客户:
仅仅使用由抽象工厂和抽象产品类声明的方法
一个系统要由多个产品系列中的一个来配置时
当你要强调一系列相关的产品对象的设计以便进行联合使用时
当你提供一个产品类库,而只想显示它的接口而不是实现
工厂模式包括:简单工厂模式、工厂方法模式和抽象工厂模式,其中简单工厂模式不是23种标准的设计模式
并且简单工厂模式也没有遵循开闭原则,抽象工厂模式在每一个系列的子系列中符合开闭原则,整个系列不符合,
下面将通过实例分别来讲解三种设计模式
一 简单工厂模式
参与者:
工厂角色:是简单工厂模式的核心,它负责实现创建所有工厂实例的内部逻辑。工厂类可以被外界直接调用,创建用户需要的产品对象
抽象产品角色:
是简单工厂模式所有创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
适用性:
工厂类负责创建的对象比较少时客户只关心传入工厂类的参数,对于如何创建对象(逻辑)不关心
实例:
#include "stdafx.h"
#include <iostream>
#include <assert.h>
using namespace std;
//抽象产品角色
class CFruit
{
public:
virtual void sayName() = 0;
};
//具体产品角色 芒果类
class CMango : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a Mango" << endl;
}
};
//具体产品角色 苹果类
class CApple : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a Apple" << endl;
}
};
//工厂角色
class CFactory
{
public:
CFruit* create(const char const * p)
{
if (strcmp(p, "mango") == 0)
{
return new CMango();
}
else if (strcmp(p, "apple") == 0)
{
return new CApple();
}
else
{
return NULL;
}
}
};
int main(int argc, char* argv[])
{
printf("start!!\n");
system("pause");
CFactory* factory = new CFactory();
CFruit* pMango = factory->create("mango");
assert(pMango != NULL);
pMango->sayName();
system("pause");
CFruit* pApple= factory->create("apple");
assert(pApple != NULL);
pApple->sayName();
system("pause");
delete factory;
factory = NULL;
delete pMango;
pMango = NULL;
delete pApple;
pApple = NULL;
return 0;
}
补充:
在简单工厂模式中,如果我们需要重新增加一种水果,比如香蕉,那么我们不仅仅需要增加一个CBanana类,还需要在工厂类中增加创建的条件。
二 工厂方法模式
参与者:
抽象工厂角色:负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
适用性:
当一个类不知道它锁不许创建的对象的类的时候当一个类希望由它的子类来指定它所创建的对象的时候
实例:
//抽象产品角色
class CFruit {
public:
virtual void sayName() = 0;
};
//具体产品角色 芒果类
class CMango : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a Mango" << endl;
}
};
//具体产品角色 苹果类
class CApple : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a Apple" << endl;
}
};
//抽象工厂角色
class CFactory
{
public:
virtual CFruit* create() = 0;
};
//具体工厂角色 芒果工厂类
class CMangoFactory : public CFactory
{
public:
CFruit* create()
{
return new CMango();
}
};
//具体工厂角色 苹果工厂类
class CAppleFactory : public CFactory
{
public:
CFruit* create()
{
return new CApple();
}
};
int main(int argc, char* argv[])
{
printf("start!!\n");
system("pause");
CMangoFactory* pMangoFac = new CMangoFactory();
CFruit* pMango = pMangoFac->create();
pMango->sayName();
system("pause");
CAppleFactory* pAppleFac = new CAppleFactory();
CFruit* pApple = pAppleFac->create();
pApple->sayName();
system("pause");
delete pMangoFac;
pMangoFac = NULL;
delete pMango;
pMango = NULL;
delete pAppleFac;
pAppleFac = NULL;
delete pApple;
pApple = NULL;
return 0;
}
补充:
当抽象方法模式中需要新增一种水果类型,如香蕉时,只需要新增一个香蕉类,一个香蕉工厂即可,并不会影响其原有代码。因此其遵循开闭原则。三 抽象工厂模式
参与者:
抽象工厂角色:负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
客户:
仅仅使用由抽象工厂和抽象产品类声明的方法
适用性:
一个系统要独立于它的产品的创建、组合和表示时一个系统要由多个产品系列中的一个来配置时
当你要强调一系列相关的产品对象的设计以便进行联合使用时
当你提供一个产品类库,而只想显示它的接口而不是实现
实例:
//抽象产品角色
class CFruit {
public:
virtual void sayName() = 0;
};
//具体产品角色 本地芒果类
class CLocalMango : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a local Mango" << endl;
}
};
//具体产品角色 本地苹果类
class CLocalApple : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a local Apple" << endl;
}
};
//具体产品角色 外地芒果类
class CFieldMango : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a Field Mango" << endl;
}
};
//具体产品角色 外地苹果类
class CFieldApple : public CFruit
{
public:
virtual void sayName()
{
cout << "I am a Field Apple" << endl;
}
};
//抽象工厂角色
class CFactory
{
public:
virtual CFruit* createMango() = 0;
virtual CFruit* createApple() = 0;
};
//具体工厂角色 本地水果工厂类
class CLocalFruitFactory : public CFactory
{
public:
CFruit* createMango()
{
return new CLocalMango();
}
CFruit* createApple()
{
return new CLocalApple();
}
};
//具体工厂角色 外地水果工厂类
class CFieldFruitFactory : public CFactory
{
public:
CFruit* createMango()
{
return new CFieldMango();
}
CFruit* createApple()
{
return new CFieldApple();
}
};
int main(int argc, char* argv[])
{
printf("start !!\n");
system("pause");
CLocalFruitFactory* pLocalfac = new CLocalFruitFactory();
CFruit* pLocalApple = pLocalfac->createApple();
pLocalApple->sayName();
system("pause");
CFruit* pLocalMango = pLocalfac->createMango();
pLocalMango->sayName();
system("pause");
CFieldFruitFactory* pFieldfac = new CFieldFruitFactory();
CFruit* pFiledApple = pFieldfac->createApple();
pFiledApple->sayName();
system("pause");
CFruit* pFieldlMango = pFieldfac->createMango();
pFieldlMango->sayName();
system("pause");
delete pLocalfac;
pLocalfac = NULL;
delete pLocalApple;
pLocalApple = NULL;
delete pLocalMango;
pLocalMango = NULL;
delete pFieldfac;
pFieldfac = NULL;
delete pFiledApple;
pFiledApple = NULL;
delete pFieldlMango;
pFieldlMango = NULL;
return 0;
}
补充:
当用抽象工厂新增加一个系列时,只需要创建一个产品具体类和产品系列工厂,
这符合开闭原则,当需要增加一款产品时,则需要改动原来的代码,则不符合开闭原则,
因此其每一个系列的子系列中符合开闭原则,整个系列不符合