设计模式(四)多例模式

  多例模式是相对单例模式而言的。单例模式有且仅有一个实例,但是多例模式,顾问思义:允许存在有限个实例。 什么叫“有限个实例”? 就是说:有多少实例,我们是知道的,并不是不可以预知的, 如果一个类的构造函数是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 #include <iostream>
 15 #include <vector>
 16 #include <string>
 17 #include <sstream>
 18 #include <time.h>
 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<string> nameList;
 30     //定义一个vector,容纳所有Emperor实例
 31     static vector<CEmperor*> 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<string> CEmperor::nameList(0);
 47 vector<CEmperor*> 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 }

  运行结果:

  

  

  看,果然每个大臣参拜的皇帝都肯可能不一样。

  这种需要产生固定数量对象的模式就叫做有上限的多例模式,它是单例模式的一种扩展,采用有上限的多例模式,我们可以在设计时决定在内存中有多少个实例,方便系统进行扩展,修正单例可能存在的性能问题,提高系统的响应速度。

   

原文地址:https://www.cnblogs.com/codingmengmeng/p/5910864.html