zoukankan      html  css  js  c++  java
  • 这个路口再次遇见你------单例模式在读取配置文件时的应用

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

         

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

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

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

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

    //读取配置文件类。
    /**
     * 采用单例模式解析sys-config.xml文件。
     * 解析sys-config.xml文件。
     *
     *
     */
    public class XmlConfigReader {
    	
    	//饿汉式。
    	//私有的静态的成员变量。
    	private static XmlConfigReader instance = new XmlConfigReader();
    	
    	//保存jdbc相关配置信息对象。
    	private JdbcConfig jdbcconfig = new JdbcConfig();
    	
    	//私有的构造方法。
    	private XmlConfigReader()
    	{
            SAXReader reader = new SAXReader();
    		
    		//拿到当前线程。
    		InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("sys-config.xml");
    		try {
    			Document doc = reader.read(in);
    			//取得xml中的Element。1 、取出驱动器的名字。
    			Element driverNameElt = (Element)doc.selectObject("/config/db-info/driver-name");
    			
    			
    			//2 、取出url字符串。
    			Element urlElt = (Element)doc.selectObject("/config/db-info/url");
    			//3、取出用户名称和密码。
    			Element userNameElt = (Element)doc.selectObject("/config/db-info/user-name");
    			Element passwordElt = (Element)doc.selectObject("/config/db-info/password");
    			
    			//取得jdbc相关配置信息。
    			jdbcconfig.setDriverName(driverNameElt.getStringValue());
    			jdbcconfig.setUrl(urlElt.getStringValue());
    			jdbcconfig.setUserName(userNameElt.getStringValue());
    			jdbcconfig.setPassword(passwordElt.getStringValue());
    			
    			
    			
    			//可以取出标签中的值。取出驱动的名称。
    		/*	String driverName = driverNameElt.getStringValue();
    			String url = urlElt.getStringValue();
    			String username = userNameElt.getStringValue();
    			@SuppressWarnings("unused")
    			String password = passwordElt.getStringValue();
    			*/
    			
    		} catch (DocumentException e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    		
    	}
    	
    	//公共的静态的入口方法。
    	public static XmlConfigReader getInstance()
    	{
    		return instance;
    	}
    	
    	/**
    	 * 返回jdbc相关配置。
    	 * @return
    	 */
    	public JdbcConfig getJdbcConfig(){
    		
    		return jdbcconfig;
    	}
    	


     

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

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

         饿汉式:
            public class Singleton{
                private static Singleton singleton = new Singleton ();
                private Singleton (){}
                public Singleton getInstance(){return singletion;}
           } 
    
         懒汉式:
           public class Singleton{
                private static Singleton singleton = null;
                public static synchronized synchronized getInstance(){
                     if(singleton==null){
                         singleton = new Singleton();
                     }
                    return singleton;
                }
           } 


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

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

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

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

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

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

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

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

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

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

           

     

     

            总之,选择设计模式中的模式要权衡利弊,看程序的主打性能是哪方面,就像不同的人有不同的学习方法,性格,不同的世界,不同的人生,不同的活法,但快乐的感受是相同的。。。

  • 相关阅读:
    0529学习进度条
    0523-学习进度条
    0515-学习进度条
    实验三-进程模拟调度
    0501-学习进度条
    0424-学习进度条
    0422—操作系统作业调度
    0415-同学博客评价
    0414-复利计算再升级
    0409-学习进度条
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3228856.html
Copyright © 2011-2022 走看看