




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、软件设计与体系结构单例模式单例模式l 意图=确保一个类仅有一个实例,且提供它的一个全局访问点l 动机=有时我们只想让一个类的单个实例在系统中存在。=例如,我们只想要一个窗口管理器。或者只想要一个产品系列的一个工厂=我们需要让该实例易于被访问=并且我们想要确保该类的其他实例不能被创建单例模式单例模式l 结构单例模式单例模式单例模式单例模式l 效果=收益对惟一实例的受控访问允许可变的实例数量单例模式的实现单例模式的实现l 我们将使用静态方法来允许客户获得对单个实例的引用,并且将使用私有构造器!/* * Singleton类是只允许一个实例化的类的实现 */public class Singleto
2、n / The private reference to the one and only instance.private static Singleton uniqueInstance = null;/ An instance attribute.private int data = 0;单例单例模式模式的实现的实现/* * Returns a reference to the single instance. * Creates the instance if it does not yet exist. * (This is called lazy instantiation.) */
3、public static Singleton instance() if(uniqueInstance = null) uniqueInstance = new Singleton();return uniqueInstance;/* * The Singleton Constructor. * Note that it is private! * No client can instantiate a Singleton object! */private Singleton() / Accessors and mutators here!单例模式的实现单例模式的实现l 下面是测试程序:p
4、ublic class TestSingleton public static void main(String args) / Get a reference to the single instance of Singleton.Singleton s = Singleton.instance();/ Set the data value.s.setData(34);System.out.println(First reference: + s);System.out.println(Singleton data value is: +s.getData();单例模式的实现单例模式的实现/
5、 Get another reference to the Singleton./ Is it the same object?s = null;s = Singleton.instance();System.out.println(nSecond reference: + s);System.out.println(Singleton data value is: +s.getData();l 下面是测试程序输出:First reference: Singleton1cc810Singleton data value is: 34Second reference: Singleton1cc8
6、10Singleton data value is: 34单例模式的实现单例模式的实现l 注意:单例只在需要时才创建。这被称作被动实例化。l 思考实验:如果两个线程同时调用instance() 方法会怎么样?会产生什么问题?l 是的! 能创建Singleton类的两个实例!l 如何能预防这种情况哪?有几个方法:=使得instance() 同步。但是,同步是昂贵的,只在创建惟一实例时才确实需要同步。=实例应主动实例化而不是被动实例化。单例模式的实现单例模式的实现(续续)单例模式的实现单例模式的实现(续续)l 下面是具有主动实例化的单例模式。l 我们将在静态初始化器中创建Singleton实例。保
7、证这种做法是线程安全的。/* * Singleton 类是只允许一个实例化的类的实现。 */public class Singleton / The private reference to the one and only instance./ Lets eagerly instantiate it here.private static Singleton uniqueInstance = new Singleton();/ An instance attribute.private int data = 0;单例模式的实现单例模式的实现(续续)/* * Returns a referen
8、ce to the single instance. */public static Singleton instance() return uniqueInstance;/* * The Singleton Constructor. * Note that it is private! * No client can instantiate a Singleton object! */private Singleton() / Accessors and mutators here!主动实例化与被动实例化的区别主动实例化:在uniqueInstance被加载时就将自己实例化。为静态实例化方式
9、。它在静态初始化期间或在类的构造器中分配变量。类一加载就实例化,所以要提前占用系统资源。被动实例化在第一次被引用时,才会将自己实例化。面临多线程访问的安全性问题,需要作双重锁定来保证安全。具有子类的具有子类的Singletonl 如果想要能够生成Singleton的子类并让单个实例是子类的实例时该怎么办?l 例如,假定MazeFactory已生成子类 EnchantedMazeFactory 和 AgentMazeFactory。我们只想实例化一个工厂,或者EnchantedMazeFactory 或者是AgentMazeFactory。l 我们能怎样做哪?有几个方法:=由MazeFactor
10、y 的静态instance() 方法决定某个子类的实例来实例化。这项工作能通过参数或环境变量来完成。在这种情况下子类的构造器不能是私有的,因此客户端不能实例化子类的其他实例。=由每个子类提供一个静态的instance() 方法。现在子类的构造器可以是私有的。具有子类的具有子类的Singleton方法方法1l 方法1:由MazeFactory 的instance() 方法决定将实例化的子类/* * MazeFactory 类是只允许一个子类实例化的类的实现 */public abstract class MazeFactory / The private reference to the one
11、 and only instance.private static MazeFactory uniqueInstance = null;/ The MazeFactory constructor./ If you have a default constructor, it can not be private/ here!protected MazeFactory() 具有子类的具有子类的Singleton方法方法1/ Return a reference to the single instance./ If instance not yet created, create enchant
12、ed as default.public static MazeFactory instance() if (uniqueInstance = null) return instance(enchanted);else return uniqueInstance;/ Create the instance using the specified String name.public static MazeFactory instance(String name) if(uniqueInstance = null)if (name.equals(enchanted)uniqueInstance
13、= new EnchantedMazeFactory();else if (name.equals(agent)uniqueInstance = new AgentMazeFactory();return uniqueInstance;具有子类的具有子类的Singleton方法方法1l 首先是创建工厂的客户代码:MazeFactory factory = MazeFactory.instance(enchanted);l 然后是访问工厂的客户代码:MazeFactory factory = MazeFactory.instance();l 注意:EnchantedMazeFactory和Age
14、ntMazeFactory 的构造器不能是私有的,因为MazeFactory必须能够实例化它们。因此,客户不可能实例化这些子类的其他实例。具有子类的具有子类的Singleton方法方法1 (续续)l The instance(String) 方法违反了开-闭原则,因为每个MazeFactory的新子类都必须修改它。l 我们可以将Java类名作为instance(String)方法的参数来使用,以产生更简单的代码:public static MazeFactory instance(String name) if (uniqueInstance = null)uniqueInstance = C
15、lass.forName(name).newInstance();return uniqueInstance;具有子类的具有子类的Singleton方法方法2l 方法2: 由每个子类提供一个静态的instance() 方法/* * MazeFactory类是只允许一个子类实例化的类的实现 * 该版本要求其子类提供静态instance() 方法的实现 */public abstract class MazeFactory / The protected reference to the one and only tected static MazeFactory uniq
16、ueInstance = null;/ The MazeFactory constructor./ If you have a default constructor, it can not be private/ here! protected MazeFactory() / Return a reference to the single instance.public static MazeFactory instance() return uniqueInstance;具有子类的具有子类的Singleton方法方法2 (续续)/* * Class EnchantedMazeFactor
17、y is an implementation of a class * that only allows one instantiation. */public class EnchantedMazeFactory extends MazeFactory / Return a reference to the single instance.public static MazeFactory instance() if(uniqueInstance = null)uniqueInstance = new EnchantedMazeFactory();return uniqueInstance;
18、/ Private subclass constructor!private EnchantedMazeFactory() 具有子类的具有子类的Singleton方法方法2l 首先是创建工厂的客户代码:MazeFactory factory = EnchantedMazeFactory.instance();l 然后是访问工厂的客户代码:MazeFactory factory = MazeFactory.instance();l 注意:子类的构造器现在是私有的。只能创建子类的一个实例!l 也要注意到如果在惟一的实例被创建前客户就调用MazeFactory.instance() ,客户就能到一个
19、null引用。l 最后,注意uniqueInstance 现在是被保护的!Java实例-系统日志(续续)几乎所有的系统都需要日志记录,其设计的原理就是采用单例模式,用文件提供日志记录,所有关联的日志都记录在同一个文件中。其实现的代码如下Java实例-系统日志(续续)先看客户调用程序:Public class Client public static void main(String args) /初始化 Logger Logger.initialize(); /获得实例 Logger loger=Logger.getLogger(); loger.logMsg(“client log mess
20、age”); Java实例-系统日志(续续)Logger的详细调用import java.text.SimpleDateFormat;import java.util.GregorianCalendar;import java.util.Properties;import java.io.InputStream;import java.io.;import java.io.PrintStream;import java.io.IOException;public class Logger private String ; private Properties properties; priva
21、te Priority priority; /* * Private constructor构造函数是私有的,因此,此类不能被继承 */ private Logger () logger = this; Java实例-系统日志(续续)/* * 日志级别:错误或信息等 * * return level, int */ public int getRegisteredLevel () int i = 0; try InputStream inputstream = getClass ().getResourceAsStream ( Lperties); properties.lo
22、ad (inputstream); inputstream.close (); i = Integer.parseInt (properties.getProperty ( *logger.registeredlevel*); if (i 3) i = 0; Java实例-系统日志(续续)catch (Exception exception) System.out.println (Logger: Failed in the getRegisteredLevel method); exception.printStackTrace (); return i; Java实例-系统日志(续续)/* * One be made daily. So, putting date time in file * name. * * param gc GregorianCalendar * return String, name of file */private String get (GregorianCalendar gc) SimpleDateFormat dateFormat1 = new SimpleDateFormat (dd-MMM-yyyy); String dateString = dateFormat1.format (gc.g
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 供应链透明度教育区块链技术的核心应用
- 医疗设备维修流程的优化与实施
- 办公自动化在医疗物资管理中的应用研究
- 以客户为中心构建基于区块链的供应金融服务体验
- 医疗科技发展下的伦理决策新挑战
- 小升初工程画图教案课件
- 东营吊车出租合同范例
- 中班幼儿教育心得体会模版
- 保险计划服务合同范例
- 乐昌劳动合同范例
- 2025届贵州省遵义第四中学高考全国统考预测密卷英语试卷含解析
- 2025年北京市丰台区九年级初三一模物理试卷(含答案)
- 湖北省武汉市2025届高中毕业生四月调研考试数学试卷及答案(武汉四调)
- 2025年四川省自然资源投资集团有限责任公司招聘笔试参考题库附带答案详解
- 建筑工程中BIM技术应用论文
- 巡察工作流程图1
- 药品经营企业质量管理工作流程图资料
- 1干混砂浆的工艺流程
- 思想政治教育心理学教学大纲
- 离子交换器用户手册
- 石子检验报告(共5页)
评论
0/150
提交评论