多例模式是相对单例模式而言的。单例模式有且仅有一个实例,但是多例模式,顾问思义:允许存在有限个实例。 什么叫“有限个实例”? 就是说:有多少实例,我们是知道的,并不是不可以预知的, 如果一个类的构造函数是public 的,那么在任意地方都可以通过调用构造函数来创建实例,那么这样的实例是我们不能预知的。这是有上限多例模式,但是多例模式还有一种无上限多例模式。因此,多例模式有以下特点:
(1)允许有多个实例。
(2)多例类自己负责创建、管理自己的实例、并向外接提供自己的实例。因此,它的构造函数也是private的,这点跟单例模式是相同的。
举个例子:
还是用皇帝和大臣的例子吧。假设同一时期有多个皇帝。0.0
代码如下:
1 /* 2 Time:2016-9-26 21:06:18 3 Author:CodingMengmeng 4 Description: 5 多例模式:单例模式的扩展 6 思路: 7 指定实例的个数->用一个容器来存储实例->定义一个索引,用于查找指定的实例 8 当然,和单例模式一样,也需要将构造函数私有化 9 同时,实例个数,索引,容器等变量都是每个实例共有的,所以应声明为静态。 10 */ 11 /* 12 还是用之前单例模式中提到的皇帝的例子,假设有几个皇帝吧0.0 13 */ 14 #include15 #include 16 #include 17 #include 18 #include 19 using namespace std; 20 21 class CEmperor{ 22 private: 23 //构造函数私有化 24 CEmperor(string name); 25 ~CEmperor(); 26 //定义最多能产生的实例数量 27 static int maxNumOfEmperor; 28 //每个Emperor都有name,使用一个vector来容纳,且声明为静态的 29 static vector nameList; 30 //定义一个vector,容纳所有Emperor实例 31 static vector emperorList; 32 //当前emperor序列号 33 static int indexOfEmperor; 34 public: 35 //产生所有实例 36 static void ProduceAllInstances(); 37 //获取实例 38 static CEmperor* GetInstance(); 39 //实例的行为 40 static void EmperorSay(); 41 }; 42 43 //所有静态变量使用前必须在类外初始化 44 int CEmperor::indexOfEmperor = 0; 45 int CEmperor::maxNumOfEmperor = 3; 46 vector CEmperor::nameList(0); 47 vector CEmperor::emperorList(0); 48 //构造函数中,将name传入 49 CEmperor::CEmperor(string name) 50 { 51 nameList.push_back(name); 52 } 53 54 //析构函数,释放当前序号对应的实例 55 CEmperor::~CEmperor() 56 { 57 delete emperorList[indexOfEmperor]; 58 } 59 60 61 void CEmperor::ProduceAllInstances() 62 { 63 for (int i = 0; i < maxNumOfEmperor; i++) 64 { 65 stringstream ss;//为了将int转为string而定义。。 66 ss << i+1; 67 string str; 68 string str1 = "Emperor"; 69 string str2; 70 ss >> str2; 71 str = str1 + str2; 72 emperorList.push_back(new CEmperor(str));//传入name,生成maxNumOfEmperor个实例 73 } 74 } 75 76 CEmperor* CEmperor::GetInstance() 77 { 78 //随机获得一个CEmperor实例 79 indexOfEmperor = rand() % maxNumOfEmperor;//对maxNumOfEmperor求余,则indexOfEmperor的范围在[0,maxNumOfEmperor)中 80 return emperorList[indexOfEmperor]; 81 82 } 83 84 void CEmperor::EmperorSay() 85 { 86 string nameString = ""; 87 nameString = nameList[indexOfEmperor]; 88 cout << nameString << endl; 89 } 90 91 int main(void) 92 { 93 //首先产生实例 94 CEmperor::ProduceAllInstances(); 95 //假设有五位minister来参拜 96 int ministerNum = 5; 97 srand(time(0));//以当前时间为随机数种子~~! 98 for (int i = 0; i < ministerNum; i++) 99 {100 CEmperor* emperor = CEmperor::GetInstance();101 cout << "第" << i + 1 << "个Minister参拜的是:";102 emperor->EmperorSay();103 }104 return 0;105 }
运行结果:
看,果然每个大臣参拜的皇帝都肯可能不一样。
这种需要产生固定数量对象的模式就叫做有上限的多例模式,它是单例模式的一种扩展,采用有上限的多例模式,我们可以在设计时决定在内存中有多少个实例,方便系统进行扩展,修正单例可能存在的性能问题,提高系统的响应速度。