现在的位置: 首页 > 综合 > 正文

单例模式应用

2012年04月04日 ⁄ 综合 ⁄ 共 4607字 ⁄ 字号 评论关闭

 单例模式已经不陌生了,这次在这个路口再次遇见了。

     

 

        第一次遇见:单例模式,几乎是见名之意,单例(个,只有一个,实例)。第一次看设计模式方面的书单纯的是为了理解而理解,现在想想当时真的不应该在那个地方花费太长的时间,因为什么东西都不可能一遍就能会的~~~而且理论和实践有相当长的距离~~~(~
o ~)~

 

        官方这样描述在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对象,这样有利于协调系统整体行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了再复杂环境下的配置管理。

 

        第二次遇见:在应用简单工厂改造的抽象工厂+配置文件中,由于每次都要去实例化工厂对象,每个调用的都要去实例化工厂类,会占用大量的内存资源,在抽象工厂类中加上单例模式。这样再调用工厂的时候不用每次都实例化工厂类,用的是懒汉式单例模式。那次的遇见,感受着他的“性格”,单例模式掌控着自己的人生,自己是自己的掌控者。。。

 

 

        第三次遇见:这个路口再次遇见,我不能放过了。。。不知道何时能牵手一直走。。。结合实际再次深入的理解理解。在java中读取xml配置文件的时候,每次都要调用这个读取的类来读取配置文件,于是,我们就只实例化一次读取配置文件的类就ok了,节省了资源。采用懒汉式单例模式。

 

[java] view
plain
copy

  1. //读取配置文件类。  
  2. /** 
  3.  * 采用单例模式解析sys-config.xml文件。 
  4.  * 解析sys-config.xml文件。 
  5.  * 
  6.  * 
  7.  */  
  8. public class XmlConfigReader {  
  9.       
  10.     //饿汉式。  
  11.     //私有的静态的成员变量。  
  12.     private static XmlConfigReader instance = new XmlConfigReader();  
  13.       
  14.     //保存jdbc相关配置信息对象。  
  15.     private JdbcConfig jdbcconfig = new JdbcConfig();  
  16.       
  17.     //私有的构造方法。  
  18.     private XmlConfigReader()  
  19.     {  
  20.         SAXReader reader = new SAXReader();  
  21.           
  22.         //拿到当前线程。  
  23.         InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("sys-config.xml");  
  24.         try {  
  25.             Document doc = reader.read(in);  
  26.             //取得xml中的Element。1 、取出驱动器的名字。  
  27.             Element driverNameElt = (Element)doc.selectObject("/config/db-info/driver-name");  
  28.               
  29.               
  30.             //2 、取出url字符串。  
  31.             Element urlElt = (Element)doc.selectObject("/config/db-info/url");  
  32.             //3、取出用户名称和密码。  
  33.             Element userNameElt = (Element)doc.selectObject("/config/db-info/user-name");  
  34.             Element passwordElt = (Element)doc.selectObject("/config/db-info/password");  
  35.               
  36.             //取得jdbc相关配置信息。  
  37.             jdbcconfig.setDriverName(driverNameElt.getStringValue());  
  38.             jdbcconfig.setUrl(urlElt.getStringValue());  
  39.             jdbcconfig.setUserName(userNameElt.getStringValue());  
  40.             jdbcconfig.setPassword(passwordElt.getStringValue());  
  41.               
  42.               
  43.               
  44.             //可以取出标签中的值。取出驱动的名称。  
  45.         /*  String driverName = driverNameElt.getStringValue(); 
  46.             String url = urlElt.getStringValue(); 
  47.             String username = userNameElt.getStringValue(); 
  48.             @SuppressWarnings("unused") 
  49.             String password = passwordElt.getStringValue(); 
  50.             */  
  51.               
  52.         } catch (DocumentException e) {  
  53.             // TODO: handle exception  
  54.             e.printStackTrace();  
  55.         }  
  56.           
  57.     }  
  58.       
  59.     //公共的静态的入口方法。  
  60.     public static XmlConfigReader getInstance()  
  61.     {  
  62.         return instance;  
  63.     }  
  64.       
  65.     /** 
  66.      * 返回jdbc相关配置。 
  67.      * @return 
  68.      */  
  69.     public JdbcConfig getJdbcConfig(){  
  70.           
  71.         return jdbcconfig;  
  72.     }  
  73.       


 

 

        懒汉式和饿汉式单例模式:

就不介绍懒汉式和饿汉式的由来,都是巨人们创造出来的,很形象很生动,让我们一下子就能知道他们的区别。我们能做的就是站在巨人的肩膀上学习。。学习好了才能进行创造。。。

 

[java] view
plain
copy

  1. <strong>    饿汉式:</strong>  
  2.        public class Singleton{  
  3.            private static Singleton singleton = new Singleton ();  
  4.            private Singleton (){}  
  5.            public Singleton getInstance(){return singletion;}  
  6.       }   
  7.   
  8.    <strong> 懒汉式:</strong>  
  9.       public class Singleton{  
  10.            private static Singleton singleton = null;  
  11.            public static synchronized synchronized getInstance(){  
  12.                 if(singleton==null){  
  13.                     singleton = new Singleton();  
  14.                 }  
  15.                return singleton;  
  16.            }  
  17.       }   

 


        没有写注释哦,观察这两个类的区别,很容易看到,饿汉式是在开始的时候就给这个类实例化一个对象,并供其他所有的对象使用。而懒汉式最初不会创建这个类的对象,而是在有请求的时候开始创建。并为了保证线程的安全问题,我们在 得到实例的方法getInstance()  前面加上了synchronized(同步的)修饰,这就相当于篮子了有很多白馒头,但一次只允许一个人来拿,并且这个人在拿馒头的时候是独占这个篮子的,把这个篮子上锁,直到拿完馒头为止,再让下一位拿馒头。

        这也是单例模式灵魂的所在,保证了这个类在一时间内只有一个自己的实例。懒汉式是以空间换取时间的方式来节省资源。

 

        饿汉式在在开始无论是有人用还是没有人用这个类的实例,在开始就new一个对象,因为在开始已经new了一个类的静态实例,所以不需要考虑java的线程同步问题啦。这种方式是以时间换取空间来节省资源空间。

 

        到底使用懒汉式还是饿汉式?

 

        你到底喜欢苹果还是蜜桃,这就取决于自己了,各自有各自的好处。取决于时间和空间上效率的取舍。

 

        每个人都有优点和缺点,单例模式也如此。

        优点就不用说了,缺点嘛。。。我们知道设计模式中讲述了程序的五大原则(捎带着复习一下O(∩_∩)O~):1、单一职责原则(一生的专注)2、开放-封闭原则(你自己的事情不需要其他人知道,你的秘密也不需要其他人知道,但你可以通过开朗的性格多交志同道合的朋友)3、依赖倒转原则(我们依赖于老师,老师依赖于学校,学校依赖于社会,低层模块依赖于高层模块)4、里氏替换原则(你父亲要退休了,你可以顶替他的位置。)5、迪米特法则(以前相亲的时候,两家通信是通过媒人来传达的,来表达双方的意思。。双方根本就不见面。。。)6、合成聚合复用原则(继承是强耦合,少生优生幸福一生。。。计算机的世界中是能做叔侄的不做父子。。。)

 

        1)可以看出单例模式不符合开闭原则,因为单例类的子类如果不去改写父类的静态方法,则使用的是和父类同一个实例,他们的联系太紧密了。。。扩展很困难。。。

 

        2)内存泄露问题。。。java中可以自动的释放资源,如果在C++中需要程序员手动释放资源,这个单例就依赖于程序员了,增加了程序员的负担,一旦程序员不小心忘记了。。。会导致内存泄露问题。。。

 

        大概总结到这,以后再遇见再理解啦。。。愿有一天你能融入我的生活中,融入我的血液中,携手到老。

抱歉!评论已关闭.