老王讲设计模式(四)多例模式

2018/08/10  |  from IT路  |  by 我是真老王  |  浏览 30

多例模式:在多例模式中,多例类可以有多个实例,而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。

多例模式 - 主图镇贴

早上,小蔡提着一杯现磨鲜豆浆,急冲冲的跑进办公室,把她的包往桌子上一扔,然后紧接着跑到了老王面前,大口大口喘着气。

老王被吓了一跳,问:“咋了?”

吓得老王K3都掉了

小蔡喘了好几口气,才说出话来:“快……快……快教……教我多例模式。”

老王依然很诧异,小心的问:“一个多例模式,至于这么着急么?”

小蔡说:“最近跟着你学习设计模式,所以昨天晚上和闺蜜喝茶的时候,在她面前显摆了一下。说我现在对设计模式了如指掌,当场就给她讲了单例模式,还跟她说昨天晚上我会把多例模式写到我的简书上……”

老王好奇的问:“你闺蜜也是搞软件的?”

小蔡说:“对啊,我大学同寝室的,肯定跟我同专业啊。哎呀~这不是重点,重点是教我多例模式,要不等她中午睡醒了,发现我没写,肯定要怀疑我的。”

老王心里暗暗嘀咕道:“中午睡醒了?不上班么?”

老王虽然心里在嘀咕,不过手上可没停下,一边打开电脑,一边说:“多例,就是有多个实例,你直接new就行了啊,想new多少个实例都行,new一堆实例都没人管你。要多少个例,就有多少个例。绝对多例。”

小蔡一下呆住了,不敢相信的念到:“new?new?new……这还叫设计模式吗?”

小蔡已扑街

老王看着小蔡呆住的表情,笑一笑接着说:“对啊,new的确可以多例啊,但是多例模式并不是new,多例模式是指有限多个实例,而不是无限多个。我马上用代码进行演示。”

//机器人

public class Droid {

       // 机器人容器,生产出来的机器人都放在这里面

       private static HashMap<String, Droid> droids = new HashMap<>();

       // 为机器人选了两个名字,一个叫阿尔法狗,另一个叫骂死他

       public static final String[] names = { "阿尔法狗", "骂死他" };

       // 机器人应该有自己名字

       private String name;

       // 直接制造两个机器人,放入机器人容器

       static {

              // 第一个机器人是阿尔法狗

              Droid alphaGo = new Droid(names[0]);

              droids.put(names[0], alphaGo);

              // 第二个机器人是骂死他

              Droid master = new Droid(names[1]);

              droids.put(names[1], master);

       }<o:p></o:p>

       // 构造机器人的时候,应该取好名字

       // 私有构造函数,在外部无法进行构造

       private Droid(String name) {

              this.name = name;

       }

       // 随便抓一个机器人,无论是谁,是机器人就行

       public static Droid getRandomInstance() {

              Random random = new Random();

              int index = random.nextInt(2);

              String name = names[index];

              return droids.get(name);

       }

       // 叫机器人的名字,找到和名字匹配的那个机器人

       public static Droid getInstance(String name) {

              return droids.get(name);

       }<o:p></o:p>

       // 机器人有一个应答功能,会报告自己名字

       public void reply() {

              System.out.println("I am " + name + ", I'm here.");

       }

}

老王接着说:“下面我们再点名,看看这些机器人如何应答。”

//对机器人进行点名

public class Call {

       public static void main(String[] args) {

              //随便抓机器人,抓6次,每抓一个机器人出来,就让它报自己的名字

              for(int i=0; i<6; i++){

                     Droid droid = Droid.getRandomInstance();

                     droid.reply();

              }

              System.out.println("");

              System.out.println("=====华丽丽的分隔符=====");

              //找到阿尔法狗,让它报道

              Droid alphaGo = Droid.getInstance(Droid.names[0]);

              alphaGo.reply();

              //找到骂死他,让它报道

              Droid master = Droid.getInstance(Droid.names[1]);

              master.reply();

       }

}

老王接着说:“最后来看看运行结果。”

运行结果

小蔡恍然大悟状,说:“哦~我懂了。原来是这样,通过集合保存实例,然后通过私有构造阻止构造。”

恍然大悟

老王哈哈笑道:“孺子可教也,的确如你所说,多例模式的几个关键点就在于:1. 通过实例容器保存容器。2. 利用私有构造阻止外部构造。3. 提供 getInstantce()方法获取实例。”

小蔡又问:“那多例模式有啥好处呢?”

老王推了推自己的眼镜说道:“这个问题问得好,我们来设想一个场景:假设我们通过单例模式,用一个数据库操作类的实例来操作数据库,那么如果我们有多个数据库时,单例模式是不是就不再适合了呢?这时候多例模式将是更好的选择。”

老王又推眼镜了

小蔡高兴的笑道:“谢谢老王,这下不怕在闺蜜面前丢脸了。”

老王微微笑道,说:“你的闺蜜漂亮不?身材咋样?高不高啊?要不下次我们分享知识时,你把她也叫上?”

老王的迷之微笑

小蔡说:“你在想什么呢?对了,我们不是建了QQ群了么?我告诉她QQ群号好了。到时看她愿不愿意加进来。至于其他人,如果也想进@_@流,就直接给你发简信吧。好了。不多说了,我要去简书上写学习笔记去了。”