工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,我们可以考虑将一些相关的产品组成一个“产品族,由同一个工厂来统一生产,这就是我们本文将要学习的抽象工厂模式的基本思想。
“工厂方法模式”实现多区域水果类图
1.当我们想添加一个新产品的时候,比如葡萄,虽然不用修改代码,但是我们需要添加大量的类,而且还需要添加相对的工厂。(系统开销,维护成本)
2.如果我们使用同一地域的水果(日本,日本,日本),那么我们需要分别创建具体的工厂,如果选择出现失误,将会造成混乱,虽然可以加一些约束,但是代码实现变得复杂。
模式中的角色和职责
抽象工厂(Abstract Factory)角色:它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
具体工厂(Concrete Factory)角色:它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
抽象产品(Abstract Product)角色:它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
具体产品(Concrete Product)角色:它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
抽象工厂模式案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//抽象苹果类
class AbstractApple
{
public:
virtual void showName() = 0;
};
//抽象香蕉
class AbstractBanana
{
public:
virtual void showName() = 0;
};
//抽象鸭梨
class AbstractPear
{
public:
virtual void showName() = 0;
};
//中国苹果
class ChineseApple : public AbstractApple
{
public:
virtual void showName()
{
cout << "中国苹果" << endl;
}
};
//美国苹果
class AmericanApple : public AbstractApple
{
public:
virtual void showName()
{
cout << "美国苹果" << endl;
}
};
//日本苹果
class JapaneseApple : public AbstractApple
{
public:
virtual void showName()
{
cout << "日本苹果" << endl;
}
};
//中国香蕉
class ChineseBanana : public AbstractBanana
{
public:
virtual void showName()
{
cout << "中国香蕉" << endl;
}
};
//美国香蕉
class AmericanBanana : public AbstractBanana
{
public:
virtual void showName()
{
cout << "美国香蕉" << endl;
}
};
//日本香蕉
class JapaneseBanana : public AbstractBanana
{
public:
virtual void showName()
{
cout << "日本香蕉" << endl;
}
};
//中国鸭梨
class ChinesePear : public AbstractPear
{
public:
virtual void showName() {
cout << "中国鸭梨" << endl;
}
};
//美国鸭梨
class AmericanPear : public AbstractPear
{
public:
virtual void showName()
{
cout << "美国鸭梨" << endl;
}
};
//日本鸭梨
class JapanesePear : public AbstractPear
{
public:
virtual void showName()
{
cout << "日本鸭梨" << endl;
}
};
//抽象工厂
class AbstractFactory
{
public:
virtual AbstractApple* CreateApple() = 0;
virtual AbstractBanana* CreateBanana() = 0;
virtual AbstractPear* CreatePear() = 0;
};
//中国工厂
class ChineseFactory : public AbstractFactory
{
public:
virtual AbstractApple* CreateApple()
{
return new ChineseApple;
}
virtual AbstractBanana* CreateBanana()
{
return new ChineseBanana;
}
virtual AbstractPear* CreatePear()
{
return new ChinesePear;
}
};
//美国工厂
class AmericanFactory : public AbstractFactory
{
public:
virtual AbstractApple* CreateApple()
{
return new AmericanApple;
}
virtual AbstractBanana* CreateBanana()
{
return new AmericanBanana;
}
virtual AbstractPear* CreatePear()
{
return new AmericanPear;
}
};
//美国工厂
class JapaneseFactory : public AbstractFactory
{
public:
virtual AbstractApple* CreateApple()
{
return new JapaneseApple;
}
virtual AbstractBanana* CreateBanana()
{
return new JapaneseBanana;
}
virtual AbstractPear* CreatePear()
{
return new JapanesePear;
}
};
void test01()
{
AbstractFactory* factory = NULL;
AbstractApple* apple = NULL;
AbstractBanana* banana = NULL;
AbstractPear* pear = NULL;
factory = new ChineseFactory; //创建中国工厂
apple = factory->CreateApple();
banana = factory->CreateBanana();
pear = factory->CreatePear();
apple->showName();
banana->showName();
pear->showName();
delete pear;
delete banana;
delete apple;
delete factory;
factory = new AmericanFactory; //创建美国工厂
apple = factory->CreateApple();
banana = factory->CreateBanana();
pear = factory->CreatePear();
apple->showName();
banana->showName();
pear->showName();
delete pear;
delete banana;
delete apple;
delete factory;
factory = new JapaneseFactory; //创建日本工厂
apple = factory->CreateApple();
banana = factory->CreateBanana();
pear = factory->CreatePear();
apple->showName();
banana->showName();
pear->showName();
delete pear;
delete banana;
delete apple;
delete factory;
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
抽象工厂模式的优缺点
优点:
(1)拥有工厂方法模式的优点
(2)当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
(3)增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
适用场景
(1) 系统中有多于一个的产品族。而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
(2) 产品等级结构稳定。设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。