欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > 设计模式-单例模式

设计模式-单例模式

2025/3/17 6:34:42 来源:https://blog.csdn.net/qq_35885952/article/details/139618028  浏览:    关键词:设计模式-单例模式

一、单例模式核心思想

单例模式是一种特殊的工厂方法模式,它适合于一个类只有一个实例的情况,比如窗口管理器打印缓冲池和文件系统。典型的情况是,那些对象的实例能够被整个软件系统的不同对象访问,因此需要一个全局的访问指针,这便是众所周知的单例模式的应用。当然这只有在不再需要任何多于一个的实例的情况下出现。

通过单例模式你可以:

  • 确保一个类只有一个实例被建立。
  • 提供了一个对对象的全局访问指针。
  • 在不影响单例类的客户端的情况下允许将来有多个实例。

单例模式的实例在全局中有且只有一个,并且该实例必须由自身创建,不能够被克隆。为了满足这些要求,一个标准的单例模式需要包含如下4个要素:

(1) 拥有一个私有的静态实例,该实例禁止外部访问。
(2) 拥有私有的默认构造函数,防止使用构造函数进行实例化。
(3) 拥有一个静态工厂方法,并且必须是同步的,防止多线程环境同时执行。
(4) 重写clone0)函数,并返回当前实例对象,默认的clone()函数会创建新的实例。

根据以上4点要求,完成的标准单例模式代码如下程序所示:

package creation.singleton;public class SingletonFactory {//(1)私有的防止外部引用private static SingletonFactory _instance = null;//(2)私有的默认构造函数,防止使用构造函数进行实例化private SingletonFactory(){}//(3)单例静态工厂方法,同步防止多线程环境同时执行synchronized public static SingletonFactory getInstance(){if( _instance == null){_instance = new SingletonFactory();}return _instance;}//(4)重写该函数,默认的cloneO函数会创建新的实例public SingletonFactory clone(){return getInstance();}
}

以上单例模式的代码中的各项缺一不可,读者可以作为单例模式的标准模板使用,在后面的示例中我们也将使用该模板进行开发。

二、何时使用单例模式

使用单例模式有一个前提条件:就是在一个系统中某一个类的实例必须只有一个,如果可以有多个实例存在,就不能够使用单例模式。以上的说法比较抽象,具体的可以应用在如下场景:

  • 系统的全局变量、存储区域。
  • 系统的全局配置文件。
  • 系统的全局操作函数。

由此可见,只要希望在全局使用一个统一的对象,就可以使用单例模式。

三、属性文件加载工厂实例

根据以上的场景,我们举例说明。以属性文件为例,在一个系统中,通常需要配置全局的属性文件,例如用户名和密码文件,如下程序所示:

属性文件user.properties

admin=123
liuzhongbing=123
guest=123

为了在系统中使用该属性文件中定义的用户名和密码,可以根据以上的单例模式模板文件SingletonFactory.java创建一个工厂类,其中定义一个私有变量 properties,用来在系统启动时将文件读取数据存储在该变量中,并提供一个按照用户名查找密码的函数getConfigO。完整的代码如下程序所示:

属性文件工厂PropertiesFactory.java

import java.util.Properties;
import java.io.FilelnputStream;public class PropertiesFactory {//(1)私有的防止外部引用private static PropertiesFactory instance = null;private Properties properties = new Properties();//(2)私有的默认构造函数,防止使用构造函数进行实例化private PropertiesFactory(){try {properties.load(newFileInputStream("sre/creation/singleton/user.properties'));}catch (Exception e) {e.printStackTrace();}}//(3)单例静态工厂方法,同步防止多线程环境同时执行public static synchronized PropertiesFactory getInstance(){if( instance == null){instance = new PropertiesFactory();return instance;}}//(4)重写该函数,默认的clone()函数会创建新的实例public PropertiesFactory clone(){return getInstance();}public String getConfg(String key){return properties.getProperty(key);}}

编写测试类来读取其中的密码,如下程序所示:

测试类PropertiesFactoryTest.java

package creation.singleton;publie class PropertiesFactoryTest {public static void main(String[] args){PropertiesFactory factory= PropertiesFactory.getInstance():String pwdl = factory.getConfig("admin");System.out.println(pwdl);}
}

运行该程序即会输出密码:123。

四、Java中的应用–日历单例类 Calendar

package java.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io .ObjectOutputStream;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import sun.util.BuddhistCalendar;
import sun.util.calendar.Zonelnfo;
import sun.util.resources.LocaleData;
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>{protected Calendar(){this(TimeZone.getDefaultRef(), Locale.getDefault());sharedZone = true;}protected Calendar(TimeZone zone, Locale aLocale){fields = new int[FIELD_COUNT];isSet = new boolean[FIELD_COUNT];stamp = new int[FIELD_COUNT];this.zone = zone;setWeekCountData(aLocale);}public static Calendar getInstance() {Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());cal.sharedZone = true;return cal;}public static Calendar getInstance(TimeZone zone) {return createCalendar(zone, Locale.getDefault());}public statie Calendar getInstance(Loeale aLocale) {Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale)cal.sharedZone = true;return cal;}public static Calendar getInstance(TimeZone zone, Locale aLocale) {return createCalendar(zone, aLocale);}}

从代码可以看出,该单例类的应用并不是严格遵守单例模式的四项规则。所以,在实际的开发中,可以根据实际的需要来自由运用。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词