`
java苹果+番茄
  • 浏览: 65752 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

单例模式应用【创建模式第八篇】

SQL 
阅读更多
预定式存储:
为了保证在任何情况下键值都不会出现重复,应当使用预定式键值存储办法。在请求一个键值时,首先将数据库中的键值更新为下一个可用值,
然后将旧值提供给客户端。这样万一出现运行中断的话,最多就是这个键值被浪费掉。
记录式存储:
键值首先被返还给客户端,然后记录到数据库中。这样做的缺点是,一旦系统中断,就有可能出现客户端已经使用了一个键值,而这个键值却
没有来得及存储到数据库中的情况。在系统重启后,系统还会从这个已经被使用过的键值开始,从而导致错误。

单例模式应用:序列键管理器
方案一:没有数据库的情况
	//序列键生成器(单例类)
	public class KeyGenerator{
		private static KeyGenerator keygen = new KeyGenerator();
		private int key = 1000;
		
		private KeyGenerator(){}
		
		//静态工厂方法,提供自己的实例
		public static KeyGenerator getInstance(){
			return keygen;
		}
		//取值方法,提供一个合适的键值
		public synchronized int getNextKey(){
			return key ++;
		}
	}
	
	//客户端
	public class Client{
		private static KeyGenerator keygen;
		
		public static void main(String args[]){
			keygen = KeyGenerator.getInstance();
			System.out.println("Key = " + keygen.getNextKey());
			System.out.println("Key = " + keygen.getNextKey());
			System.out.println("Key = " + keygen.getNextKey());
		}
	}
	//当系统重启时,计数就要重新开始
	
方案二:有数据库的情况:
	//序列键生成器(单例类)
	public class KeyGenerator{
		private static KeyGenerator keygen = new KeyGenerator();
		private int key = 1000;
		
		private KeyGenerator(){}
		
		//静态工厂方法,提供自己的实例
		public static KeyGenerator getInstance(){
			return keygen;
		}
		//取值方法,提供一个合适的键值
		public synchronized int getNextKey(){
			return getNextKeyFromDB();
		}
		
		private int getNextKeyFromDB(){
			String sql1 = "UPDATE KeyTable SET keyValue = keyValue + 1";
			String sql2 = "SELECT keyValue FROM KeyTable";
			//execute the update SQL
			//run the select query
			//示意性的返还一个数值
			return 1000;
		}
	}
	//每次都向数据库查询键值,将这个键值登记到表里,然后将查询结果返还给客户端
	
方案三:键值的缓存方案
	//序列键生成器(单例类)
	public class KeyGenerator{
		private static KeyGenerator keygen = new KeyGenerator();
		private static final int POOL_SIZE = 20;		//用于缓存20条记录
		private KeyInfo key;
		
		private KeyGenerator(){
			key = new KeyInfo(POOL_SIZE);
		}
		
		//静态工厂方法,提供自己的实例
		public static KeyGenerator getInstance(){
			return keygen;
		}
		//取值方法,提供一个合适的键值
		public synchronized int getNextKey(){
			return key.getNextKey();
		}
	}
	
	//KeyInfo类
	public class KeyInfo{
		private int keyMax;
		private int keyMin;
		private int nextKey;
		private int poolSize;
		
		public KeyInfo(int poolSize){
			this.poolSize = poolSize;
			retrieveFromDB();				//retrieve(检索)
		}
		
		//取值方法,提供键的最大值
		public int getKeyMax(){
			return keyMax;
		}
		
		public int getKeyMin(){
			return keyMin;
		}
		
		//取值方法,提供键的当前值
		public int getNextKey(){
			if(nextKey > keyMax){
				retrieveFromDB();
			}
			return nextKey ++;
		}
		
		//内部方法,从数据库提取键的当前值
		private void retrieveFromDB(){
			String sql1 = "UPDATE KeyTable SET keyValue = keyValue +" + poolSize + 
			"WHERE keyName = 'PO_NUMBER'";
			
			String sql2 = "SELECT keyValue FROM KeyTable WHERE keyName = 'PO_NUMBER'";
			//execute the above queries in a transaction and commit it		//commit提交/委托
			//assume the value returned is 1000					//assume假设
			int keyFromDB = 1000;
			keyMax = keyFromDB;
			keyMin = keyFromDB - poolSize + 1;
			nextKey = keyMin;
		}
	}
	
	//客户端
	public class Client{
		private static KeyGenerator keygen;
		
		public static void main(String args[]){
			keygen = KeyGenerator.getInstance();
			for(int i = 0; i < 20; i ++){
				System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey());
			}
		}
	}
	
方案四:有缓存的多序列键生成器
	//KeyGenerator
	import java.util.HashMap;
	
	public class KeyGenerator{
		private static KeyGenerator keygen = new KeyGenerator();
		private static final int POOL_SIZE = 20;
		private HashMap keyList = new HashMap(10);
		
		private KeyGenerator(){
			
		}
		
		public static KeyGenerator getInstance(){
			return keygen;
		}
		
		public synchronized int getNextKey(String keyName){
			KeyInfo keyInfo;
			if(keyList.containsKey(keyName)){
				keyInfo = (KeyInfo)keyList.get(keyName);
				System.out.println("Key found");
			}else{
				keyInfo = new KeyInfo(POOL_SIZE,keyName);
				keyList.put(keyName,keyInfo);
				System.out.println("New key created");
			}
			return keyInfo.getNextKey(keyName);
		}
	}
	
	//KeyInfo类
	public class KeyInfo{
		private int keyMax;
		private int keyMin;
		private int nextKey;
		private int poolSize;
		private String keyName;
		
		public KeyInfo(int poolSize,String keyName){
			this.poolSize = poolSize;
			this.keyName = keyName;
			retrieveFromDB();				//retrieve(检索)
		}
		
		//取值方法,提供键的最大值
		public int getKeyMax(){
			return keyMax;
		}
		
		public int getKeyMin(){
			return keyMin;
		}
		
		//取值方法,提供键的当前值
		public int getNextKey(){
			if(nextKey > keyMax){
				retrieveFromDB();
			}
			return nextKey ++;
		}
		
		//内部方法,从数据库提取键的当前值
		private void retrieveFromDB(){
			String sql1 = "UPDATE KeyTable SET keyValue = keyValue +" + poolSize + 
			"WHERE keyName = " + keyName + "";
			
			String sql2 = "SELECT keyValue FROM KeyTable WHERE keyName = " + keyNAme + "";
			//execute the above queries in a transaction and commit it		//commit提交/委托
			//assume the value returned is 1000					//assume假设
			int keyFromDB = 1000;
			keyMax = keyFromDB;
			keyMin = keyFromDB - poolSize + 1;
			nextKey = keyMin;
		}
	}
	
	//客户端
	public class Client{
		private static KeyGenerator keygen;
		
		public static void main(String args[]){
			keygen = KeyGenerator.getInstance();
			for(int i = 0; i < 20; i ++){
				System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey("PO_NUMBER"));
			}
		}
	}273P
	
方案五:多例模式
	//KeyGennerator
	import java.util.HashMap;
	public class KeyGenerator{
		private static HashMap Kengens = new HashMap(10);
		private static final int POOL_SIZE = 20;
		private KeyInfo keyinfo;
		
		private KeyGenerator(){}
		
		private KeyGenerator(String keyName){
			keyinfo = new KeyInfo(POOL_SIZE,keyName);
		}
		
		public static synchronized KeyGenerator getInstance(String keyName){
			KeyGenerator keygen;
			if(kengens.containsKey(keyName)){
				keygen = (KeyGenerator)kengens.get(keyName);
			}else{
				keygen = new KeyGenerator(keyName);
			}
			return keygen;
		}
		
		public synchronized int getNextKey(){
			return keyinfo.getNextKey();
		}
		//KeyInfo类与方案四里的相同
	}
	
	//客户端
	public class Client{
		private static KeyGenerator keygen;
		
		public static void main(String args[]){
			keygen = KeyGenerator.getInstance("PO_NUMBER");
			for(int i = 0; i < 20; i ++){
				System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey());
			}
		}
	}
分享到:
评论

相关推荐

    java设计模式

    第8章 工厂方法模式 8.1 女娲造人的故事 8.2 工厂方法模式的定义 8.3 工厂方法模式的应用 8.3.1 工厂方法模式的优点 8.3.2 工厂方法模式的使用场景 8.4 工厂方法模式的扩展 8.5 最佳实践 第9章 抽象工厂模式 9.1 ...

    Delphi模式编程第一分卷

    第8章 原型模式(Prototype) 8.1 模式解说 8.2 结构和用法 8.2.1 模式结构 8.2.2 代码模板 8.3 范例与实践 8.3.1 Delphi对象的克隆 8.3.2 用原型模式克隆字体 8.3.3 Delphi对象流化与原型模式 8.3.4 范例...

    Delphi模式编程第二分卷

    第8章 原型模式(Prototype) 8.1 模式解说 8.2 结构和用法 8.2.1 模式结构 8.2.2 代码模板 8.3 范例与实践 8.3.1 Delphi对象的克隆 8.3.2 用原型模式克隆字体 8.3.3 Delphi对象流化与原型模式 ...

    OBJECTIVE-C编程之道 IOS设计模式解析电子书+源代码

    C中实现单例模式7.4 子类化Singleton7.5 线程安全7.6 在Cocoa Touch框架中使用单例模式7.6.1 使用UIApplication类7.6.2 使用UIAccelerometer类7.6.3 使用NSFileManager类7.7 总结第三部分 接口适配第8章 适配器8.1 ...

    C#电话本 控制台应用程序 软件项目课程设计

    3.使用电话簿单例模式,保证开发过程中,PhoneBook类尽能被唯一生成一次。 4.使用MyFile类实现文件名为多个类共享 5.整个过程中若存在f:/person.dat则导入(使用PhoneBook构造函数自动加载),不存在则创建只在...

    java设计模式选择题复习题.doc

    工厂系列模式的优缺点: 让用户的代码和某个特定类的子类的代码解耦 用户不必知道它所使用的对象是怎样创建的,只需知道该对象有哪些方法 抽象工厂模式可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱...

    二十三种设计模式【PDF版】

    我上面这些描述其实都是一种模式,创建模式的人是大师,但是拘泥于模式的人永远是工匠. 再回到传统建筑中,中国的传统建筑是过分注重模式了,所以建筑风格发展不大,基本分南北两派,大家有个感觉,旅游时,到南 方,你发现...

    《iOS6开发指南》精彩书摘

    第8章“应用程序的设置”。介绍了用中设置和配置的概念,然后通过对二者差异的探讨,介绍了什么样的项目适合放在设置里,什么样的项目适合放在配置里。 第9章“应用程序本地化”。了解本地化概念、内容和目录结构,...

    Java经典编程源码基础例程300.zip

    实例046 单例模式的应用 69 实例047 汉诺塔问题求解 70 实例048 编写同名的方法 71 实例049 构造方法的应用 72 实例050 统计图书的销售量 73 实例051 两只完全相同的宠物 74 实例052 重新计算对象的哈希码 76 实例...

    超级有影响力霸气的Java面试题大全文档

    当客户机第一次调用一个Stateful Session Bean 时,容器必须立即在服务器中创建一个新的Bean实例,并关联到客户机上,以后此客户机调用Stateful Session Bean 的方法时容器会把调用分派到与此客户机相关联的Bean实例...

    scala从入门到精通技术教学视频

    第八章 特质 00.导学 01.类继承单个特质 02.类继承多个特质 03.单例对象继承特质 04.演示trait中的成员 05.动态混入trait 06.使用trait实现适配器设计模式 07.使用trait实现模板方法模式 08.使用trait实现...

    面向对象技术与UML课件及源代码-by 南邮-陈杨

    第8章实验指导2 第9章异常处理 第10章Java常用API 第11章Java IO操作 第12章多线程开发 第13章反射技术 第14章实验指导3 下篇UML 第15章UML入门 第16章用例图 第17章类图和对象图 第18章实验指导4...

    JAVA面向对象详细资料

    32 单例模式 47 32.1 饿汉模式 47 32.2 懒汉模式 47 33 接口(interface) 48 33.1 如何创建一个接口。 48 33.2 如何使用接口 48 33.3 如何使用类实现一个接口 49 33.4 接口的细节 49 34 接口的应用(面向对象分析)...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例088 单例模式的应用 109 实例089 祖先的止痒药方 110 实例090 统计图书的销售量 111 实例091 汉诺塔问题求解 112 实例092 不能重写的方法 113 5.3 包装类的使用 114 实例093 将字符串转换成整数 114 实例094 ...

Global site tag (gtag.js) - Google Analytics