多例模式

多例模式就是单例模式的自然推广,属于对象。多例模式限制了对象的数量,并且有可能对对象进行复用。

特点

  1. 多例可以有多个实例
  2. 多例必须能够自我创建并自我管理自己的实例,并且向外界提供自己的实例。

场景

  1. 引用设计模式之禅中的案例,一般情况下,一个王朝的皇帝其实都是只有一个,但是在历史上,大明王朝在土木堡之变中被瓦刺俘虏的皇帝,皇帝突然有两个,一个执政,另外一个则被俘虏了。当俘虏皇帝获救之后,这个时候王朝有两个皇帝。这两个皇帝其实也就对应了两个对象实例,多例模式下的现实场景。
  2. 在Java学习过程中,有一个池子的概念一直存在,好比作线程池,数据库连接池,这个池子是用来对线程,或者数据库连接对象进行管理的,第一,限制了池子中的对象数量,第二就是能够在使用过程中达到复用的效果,线程中的线程在执行完毕后,不会被直接回收掉,而会切换成等待状态,等待下一个任务提交,执行。数据库连接池也是如此,数据库操作在连接的时候,如果对数据库操作完毕后,会把资源释放,然后等待下一个数据库操作进行连接。这种设计其实是将对象的应用最大化了,避免了每次连接的时候都需要去创建一个对象。造成对象冗余或者内存升高。

代码

package cn.sbx0.designdemo;

import java.util.ArrayList;
import java.util.Random;

public class MultitionPattern {

    public static void main(String[] args) {
        Emperor emperor = Emperor.getInstance();
        System.out.println(emperor);
        Emperor emperor1 = Emperor.getInstance(0);
        System.out.println(emperor1);
        Emperor emperor2 = Emperor.getInstance(1);
        System.out.println(emperor2);
    }

    static class Emperor {
        private static final int maxNumberOfEmperor = 2;
        private static ArrayList emperorInfoList = new ArrayList(maxNumberOfEmperor);
        private static ArrayList emperorList = new ArrayList(maxNumberOfEmperor);

        private static int countNumOfEmperor = 0;

        static {
            for (int i = 0; i < maxNumberOfEmperor; i++) {
                emperorList.add(new Emperor("第" + i + "皇帝"));
            }
        }

        private Emperor() {

        }

        private Emperor(String info) {
            emperorInfoList.add(info);
        }

        public static Emperor getInstance(int num) {
            countNumOfEmperor = num;
            if (num >= 0 && num <= maxNumberOfEmperor) {
                return (Emperor) emperorList.get(num);
            } else {
                System.out.println("error");
                return null;
            }
        }

        public static Emperor getInstance() {
            Random random = new Random();
            countNumOfEmperor = random.nextInt(maxNumberOfEmperor);
            return (Emperor) emperorList.get(countNumOfEmperor);
        }

        @Override
        public String toString() {
            return (String) emperorInfoList.get(countNumOfEmperor);
        }
    }
}

参考文献

【设计模式九之多例模式】多例模式详解