让代码飞

做人难 ,做码农更难

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

23种设计模式 之单例设计模式

一、定义

确保某一个类只有一个实例,而且自行实例化,并且向整个系统提供这个实例。

二、优点

减少了内存的开支,减少系统的性能开销,避免了对于资源的多重占用,优化其资源访问。

三、缺点

扩展困难,对于测试不利。

四、注意

单例设计模式模式对于使用于系统资源小号过多的操作中,例如IO或者连接数据库。

五、故事继续

  站在“唐”酒楼的顶层,看看着下面的灯红酒绿,车水马龙,李实名不由得有点伤感,想想自己做皇帝的时候,唉...........

一个月前:

         “吾皇万岁,万岁,万万岁!!!”

    “众爱卿平身.”

          “谢皇上!”

          李实名,“堂”朝的开国皇帝,万人之上(没有之下),每日最重要的事就是早朝,天天的早朝使得他不禁有了一些反感,常常生出做一个普通人的想法。

1 package danli;
2  public class HuangShang
3 {
4 //皇帝的名号
5   private String nameString;
6 //皇帝的年龄
7   private int age;
8 private static HuangShang huangShang = new HuangShang("李实名", 25);
9 //私有构造,你想new皇上,反贼!!!
10   private HuangShang(String naString,int age)
11 {
12 this.setNameString(naString);
13 this.setAge(age);
14 }
15
16 public static HuangShang getHuangShang()
17 {
18 return huangShang;
19 }
20 public String getNameString()
21 {
22 return nameString;
23 }
24 public void setNameString(String nameString)
25 {
26 this.nameString = nameString;
27 }
28 public int getAge()
29 {
30 return age;
31 }
32 public void setAge(int age)
33 {
34 this.age = age;
35 }
36 //时间是一把杀猪刀
37   public void time()
38 {
39 System.out.println("时间过去一年..............");
40 this.setAge(this.age+1);
41 }
42
43 public void say()
44 {
45 System.out.println("我是皇上"+this.getNameString()+",今年"+this.getAge());
46 }
47 }

场景类:

package danli;  
public class Client  
{  
    public static void main(String[] args)  
    {  
        HuangShang huangShang = HuangShang.getHuangShang();  
        huangShang.say();  
        //一年以后  
        huangShang.time();  
        HuangShang huangShang1 = HuangShang.getHuangShang();  
        huangShang1.say();  
    }  
} 

结果:

我是皇上李实名,今年25

时间过去一年..............

我是皇上李实名,今年26

说到这里,可能有知道这个模式的人会说:不是还有一种方式么?是,我们下面看看:
package danli;  
public class HuangShang  
{  
    //皇帝的名号  
    private String nameString;  
    //皇帝的年龄  
    private int age;  
    private static HuangShang huangShang = null;  
    //私有构造,你想new皇上,反贼!!!  
    private HuangShang(String naString,int age)  
    {  
        this.setNameString(naString);  
        this.setAge(age);  
    }  
      
    public static HuangShang getHuangShang()  
    {  
        if (huangShang == null)  
        {  
            huangShang = new HuangShang("李世明", 25);  
        }  
        return huangShang;  
    }  
    public String getNameString()  
    {  
        return nameString;  
    }  
    public void setNameString(String nameString)  
    {  
        this.nameString = nameString;  
    }  
    public int getAge()  
    {  
        return age;  
    }  
    public void setAge(int age)  
    {  
        this.age = age;  
    }  
    //时间是一把杀猪刀  
    public void time()  
    {  
        System.out.println("时间过去一年..............");  
        this.setAge(this.age+1);  
    }  
      
    public void say()  
    {  
        System.out.println("我是皇上"+this.getNameString()+",今年"+this.getAge());  
    }  
}

场景类一样,结果呢?也一样......

大家经常把第一种称为饿汉式,第二种称为懒汉式,那他们有什么不同呢?

如果是你,你会选择那种呢?大部分人会选择第二种,看起来牛B,其实我推荐大家选择第一种,why?因为,第二种方式,可能会出现线程问题,第一个实例做到判断是否为null时,第二个实例也在初始化,这时虚拟机认为该对象还未初始化,他就会初始化,然后第一个接着完成初始化,这样就会有两个对象在内存中,这样就会出现问题。

    “皇上,您的仙丹来了!”一个公公急急地跑来。

    “是吗?拿来给朕看看。”

    “嗻!”

    “皇上,您要三思啊!”一位重臣说道

    “没事”说着李实名就把“仙丹”吞了。

现实:

    “唉.....早知道就不吃了”李世民想到:“跑到这个鬼地方,不过这样也有意思,让我过过普通人的生活。”

卖掉了身上的玉佩,租了这间酒楼,李实名决心在这里大干一场,这才有了开始的一幕(见我写的:穿越的故事,设计模式之我见1)

故事回到现实,顶楼的李实名挥了挥手,像是把以前的一切都赶走,又像是向回不去的过去告别............................

posted on 2011-06-08 08:29  saoba  阅读(1431)  评论(9)    收藏  举报