这个路口再次遇见你------单例模式在读取配置文件时的应用

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

     

        第一次遇见:单例模式,几乎是见名之意,单例(个,只有一个,实例)。第一次看设计模式方面的书单纯的是为了理解而理解,现在想想当时真的不应该在那个地方花费太长的时间,因为什么东西都不可能一遍就能会的~~~而且理论和实践有相当长的距离~~~(~ 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++中需要程序员手动释放资源,这个单例就依赖于程序员了,增加了程序员的负担,一旦程序员不小心忘记了。。。会导致内存泄露问题。。。

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

       

 

 

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

原文地址:https://www.cnblogs.com/jiangu66/p/3228856.html