第5章 单例模式_第1页
第5章 单例模式_第2页
第5章 单例模式_第3页
第5章 单例模式_第4页
第5章 单例模式_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章单例模式本章教学内容单例模式模式动机与定义模式结构与分析模式实例与解析模式效果与应用模式扩展引例

---读取配置文件的内容

考虑这样一个应用,读取配置文件的内容。很多应用项目,都有与应用相关的配置文件,这些配置文件很多是由项目开发人员自定义的,在里面定义一些应用需要的参数数据。当然在实际的项目中,这种配置文件多采用xml格式,也有采用properties格式的,毕竟使用Java来读取properties格式的配置文件比较简单。现在要读取配置文件的内容,该如何实现呢?

直接读取文件的内容,然后把文件内容存放在相应的数据对象里面就可以了。真的这么简单吗?先实现看看吧。假设系统采用的是properties格式的配置文件。(1)直接使用Java来读取配置文件的示例代码如下:

//读取应用配置文件publicclassAppConfig{

privateStringparameterA;//用来存放配置文件中参数A的值

privateStringparameterB;

//用来存放配置文件中参数B的值

publicStringgetParameterA(){

//注意:只有访问参数的方法,没有设置参数的方法

returnparameterA;

}

publicStringgetParameterB(){

returnparameterB;

}//构造方法

publicAppConfig(){//调用读取配置文件的方法

readConfig();

}}

privatevoidreadConfig(){//读取配置文件,把配置文件中的内容读出来设置到属性上

Propertiesp=newProperties();

InputStreamin=null;

try{

in=AppConfig.class.getResourceAsStream(

"AppCperties");

p.load(in);//把配置文件中的内容读出来设置到属性上

this.parameterA=p.getProperty("paramA");

this.parameterB=p.getProperty("paramB");

}catch(IOExceptione){

System.out.println("装载配置文件出错了,具体堆栈信息如下:");

e.printStackTrace();

}finally{

try{

in.close();

}catch(IOExceptione){

e.printStackTrace();

}

}

}

(2)应用的配置文件,名字是AppCperties,放在AppConfig相同的包里面。简单示例如下:paramA=aparamB=b(3)写个客户端来测试一下。示例代码如下:publicclassClient{

publicstaticvoidmain(String[]args){//创建读取应用配置的对象

AppConfigconfig=newAppConfig();

StringparamA=config.getParameterA();

StringparamB=config.getParameterB();System.out.println("paramA="+paramA+",paramB="+paramB);

}}

运行结果如下:

paramA=a,paramB=b有何问题

看看客户端使用这个类的地方,是通过new一个AppConfig的实例来得到一个操作配置文件内容的对象。如果在系统运行中,有很多地方都需要使用配置文件的内容,也就是说很多地方都需要创建AppConfig对象的实例。换句话说,在系统运行期间,系统中会存在很多个AppConfig的实例对象,这有什么问题吗?

当然有问题了,试想一下,每一个AppConfig实例对象里面都封装着配置文件的内容,系统中有多个AppConfig实例对象,也就是说系统中会同时存在多份配置文件的内容,这样会严重浪费内存资源。如果配置文件内容较少,问题还小一点,如果配置文件内容本来就多的话,对于系统资源的浪费问题就大了。事实上,对于AppConfig这种类,在运行期间,只需要一个实例对象就是够了。把上面的描述进一步抽象一下,问题就出来了:在一个系统运行期间,某个类只需要一个类实例就可以了,那么应该怎样实现呢?单例模式模式动机对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。单例模式模式动机如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。单例模式模式定义单例模式(SingletonPattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。单例模式又名单件模式或单态模式。单例模式模式定义SingletonPattern:Ensureaclasshasonlyoneinstanceandprovideaglobalpointofaccesstoit.Frequencyofuse:mediumhigh

单例模式模式结构单例模式模式结构单例模式包含如下角色:Singleton:单例单例模式模式分析单例模式的目的是保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式包含的角色只有一个,就是单例类——Singleton。单例类拥有一个私有构造函数,确保用户无法通过new关键字直接实例化它。除此之外,该模式中包含一个静态私有成员变量与静态公有的工厂方法,该工厂方法负责检验实例的存在性并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。单例模式模式分析单例模式的实现代码如下所示:单例模式模式分析在单例模式的实现过程中,需要注意如下三点:单例类的构造函数为私有;提供一个自身的静态私有成员变量;提供一个公有的静态工厂方法。单例模式单例模式实例与解析实例一:身份证号码在现实生活中,居民身份证号码具有唯一性,同一个人不允许有多个身份证号码,第一次申请身份证时将给居民分配一个身份证号码,如果之后因为遗失等原因补办时,还是使用原来的身份证号码,不会产生新的号码。现使用单例模式模拟该场景。单例模式单例模式实例与解析实例一:身份证号码单例模式单例模式实例与解析实例一:身份证号码演示……单例模式单例模式实例与解析实例二:打印池在操作系统中,打印池(PrintSpooler)是一个用于管理打印任务的应用程序,通过打印池用户可以删除、中止或者改变打印任务的优先级,在一个系统中只允许运行一个打印池对象,如果重复创建打印池则抛出异常。现使用单例模式来模拟实现打印池的设计。单例模式单例模式实例与解析实例二:打印池单例模式单例模式实例与解析实例二:打印池演示……单例模式模式优缺点单例模式的优点提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它,并为设计及开发团队提供了共享的概念。由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。允许可变数目的实例。我们可以基于单例模式进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例。单例模式模式优缺点单例模式的缺点由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致对象状态的丢失。单例模式模式适用环境在以下情况下可以使用单例模式:系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。在一个系统中要求一个类只有一个实例时才应当使用单例模式。反过来,如果一个类可以有几个实例共存,就需要对单例模式进行改进,使之成为多例模式。单例模式模式应用(1)java.lang.Runtime类publicclassRuntime{privatestaticRuntimecurrentRuntime=newRuntime();publicstaticRuntimegetRuntime(){ returncurrentRuntime;}privateRuntime(){}......}单例模式模式应用(2)一个具有自动编号主键的表可以有多个用户同时使用,但数据库中只能有一个地方分配下一个主键编号,否则会出现主键重复,因此该主键编号生成器必须具备唯一性,可以通过单例模式来实现。单例模式模式应用(3)默认情况下,Spring会通过单例模式创建bean实例:

单例模式模式扩展饿汉式单例类单例模式模式扩展懒汉式单例类单例模式模式扩展饿汉式单例与懒汉式单例类比较饿汉式单例类在自己被加载时就将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。懒汉式单例类在实例化时,必须处理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费大量时间,这意味着出现多线程同时首次引用此类的机率变得较大,需要通过同步化机制进行控制。本章小结单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。单例模式只包含一个单例角色:在单例类的内部实现只生成一个实例,同时它提供一个静态的工厂方法,让客户可以使用它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有。本章

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论