zoukankan      html  css  js  c++  java
  • 设计模式(四)多例模式

      多例模式是相对单例模式而言的。单例模式有且仅有一个实例,但是多例模式,顾问思义:允许存在有限个实例。 什么叫“有限个实例”? 就是说:有多少实例,我们是知道的,并不是不可以预知的, 如果一个类的构造函数是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 }

      运行结果:

      

      

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

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

       

  • 相关阅读:
    hdu-5492 Find a path(dp)
    hdu-5493 Queue(二分+树状数组)
    bzoj-2243 2243: [SDOI2011]染色(树链剖分)
    codeforces 724
    codeforces 422A A. Borya and Hanabi(暴力)
    codeforces 442C C. Artem and Array(贪心)
    codeforces 442B B. Andrey and Problem(贪心)
    hdu-5918 Sequence I(kmp)
    poj-3739. Special Squares(二维前缀和)
    hdu-5927 Auxiliary Set(树形dp)
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/5910864.html
Copyright © 2011-2022 走看看