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 }

      运行结果:

      

      

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

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

       

  • 相关阅读:
    swift 第十四课 可视化view: @IBDesignable 、@IBInspectable
    swift 第十三课 GCD 的介绍和使用
    swift 第十二课 as 的使用方法
    swift 第十一课 结构体定义model类
    swift 第十课 cocopod 网络请求 Alamofire
    swift 第九课 用tableview 做一个下拉菜单Menu
    swift 第八课 CollectView的 添加 footerView 、headerView
    swift 第七课 xib 约束的优先级
    swift 第六课 scrollview xib 的使用
    swift 第五课 定义model类 和 导航栏隐藏返回标题
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/5910864.html
Copyright © 2011-2022 走看看