`
java苹果+番茄
  • 浏览: 67996 次
  • 性别: 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());
			}
		}
	}
分享到:
评论

相关推荐

    第八课 单例模式1

    单例模式是一种设计模式,它的主要目标是确保一个类在整个应用程序中只有一个实例存在,并提供一个全局访问点,以便任何地方都能方便地使用该实例。这种模式在需要频繁创建和销毁对象,或者对象创建代价较高的场景中...

    第五讲单例模式

    在本讲“第五讲单例模式”中,我们将深入探讨这个模式的原理、实现方式以及其在实际编程中的应用。 单例模式的核心思想是确保一个类在整个系统运行期间只有一个实例,并提供一个全局访问点来获取这个唯一的实例。...

    java模式设计之单例模式

    8. **Java中的单例模式注意事项** - 构造函数必须是私有的,防止外部直接创建实例。 - 使用静态工厂方法(`getInstance()`)返回实例,保持类的封闭性。 - 在多线程环境下,需要考虑线程安全性,如使用`...

    IOS基于ASIHttpRequest的封装,使用单例模式断点续传

    在这个项目中,使用单例模式创建一个全局的网络请求管理者,确保在整个应用生命周期内只有一个实例存在,这样可以方便地跟踪和控制下载任务,同时避免了资源浪费。 4. **CoreData**:CoreData是Apple提供的一种对象...

    PHP基于单例模式实现的mysql类

    在数据库操作中,单例模式通常用来封装数据库连接,以减少数据库连接的开销,提高应用程序的效率。以下是使用PHP实现单例模式封装MySQL类的具体知识点: 1. 单例模式的基本概念: 单例模式,顾名思义,即保证一个类...

    java设计模式

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

    iOS OC 单例

    通过文件`OC_SingletonTest`中的示例,我们可以进一步学习如何在实际项目中应用单例模式,例如创建一个网络请求管理器单例,用于统一处理网络请求,这样可以方便地管理和监控网络状态,同时减少代码的重复性。...

    DesignPatterns:初始提交 - 单例模式

    在Java编程中,单例模式的应用非常广泛,例如管理全局配置、提供缓存服务或者作为线程池的实现基础等。本项目主要探讨了单例模式的实现方式以及线程安全问题,并涉及如何通过反射技术破坏单例模式。 1. **单例模式...

    Javascript 设计模式系统讲解与应用视频资源地址.7z

    在JavaScript中,由于其全局作用域和函数作为第一级公民的特点,单例模式可以通过闭包实现,确保无论何时需要该实例,都只会返回同一个对象。 二、工厂模式 工厂模式是一种创建型设计模式,它提供了一个创建对象的...

    腊月一十八,聊聊 MyBatis 中的设计模式.docx

    装饰者模式是 MyBatis 中使用的第八个设计模式。例如 Cache 包中的 cache.decorators 子包中的各个装饰者的实现就是装饰者模式的应用。装饰者模式的定义是“动态地给一个对象添加一些额外的职责”。 9. 迭代器模式 ...

    java设计模式ppt

    单例模式是一种常用的对象创建型模式,其目的是确保一个类只有一个实例,并提供一个全局访问点。实现单例模式的关键在于如何确保实例的唯一性和线程安全性。通常有两种实现方式: - **懒汉式**:在第一次使用时才...

    ios一些案例的demo(单例模式,倒影,雪花,动画组,图片水印,画板,画饼图。。。)

    1. **单例模式**:单例模式是一种设计模式,保证一个类只有一个实例,并提供一个全局访问点。在iOS中,常用于配置管理、网络请求等场景。例如,网络请求管理器通常被设计为单例,确保在整个应用程序中只有一份实例,...

    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对象流化与原型模式 ...

    C#设计模式PDF 电子书

    《C#设计模式PDF 电子书》是一本专注于C#编程语言中设计模式的应用和解析的书籍,2005年04版意味着它在设计模式领域的应用尚处于早期阶段,但仍然具有很高的学习价值。设计模式是软件工程中经过实践验证的、解决常见...

    C++Qt设计模式第二版部分程序

    第八章可能涵盖了“创建型”设计模式,如单例模式(Singleton)、工厂模式(Factory Method)或抽象工厂模式(Abstract Factory)。单例模式确保一个类只有一个实例,并提供全局访问点。工厂模式则允许我们通过接口...

    java 设计模式试题

    常见的创建型模式包括工厂方法模式、抽象工厂模式、单例模式等。 ### 5. 依赖倒转原则 依赖倒转原则(D) 强调依赖于抽象而不是具体实现。这意味着我们应该通过接口而不是实现类来进行编程。这样做可以降低模块间的...

    《Java设计模式》课后习题参考答案-刘伟(20180723).pdf

    单例模式保证一个类只有一个实例,并提供一个全局访问点。在JDK中的例子有: - java.lang.Runtime#getRuntime(),获取Java运行时环境。 f) 适配器模式(Adapter) 适配器模式允许将一个类的接口转换成客户期望的...

    设计模式——刘伟

    1. **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。单例模式常用于控制资源的共享,如数据库连接、线程池等。实现方式有懒汉式(线程不安全)、饿汉式(线程安全)以及双重检查锁定等。 2. **工厂...

    Python编程实战 运用设计模式、并发和程序库创建高质量程序

    在Python中,一些经典的设计模式如工厂模式、单例模式、观察者模式等,都有其独特的应用。例如,工厂模式用于动态创建对象,而单例模式确保类只有一个实例,观察者模式则用于实现对象之间的松耦合通信。理解和运用...

Global site tag (gtag.js) - Google Analytics