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

键值生成策略
本文探讨了不同场景下键值生成的几种策略,包括无数据库情况下的简单递增、有数据库情况下的实时查询、缓存机制的引入以及多序列键生成器的设计等。
预定式存储:
为了保证在任何情况下键值都不会出现重复,应当使用预定式键值存储办法。在请求一个键值时,首先将数据库中的键值更新为下一个可用值,
然后将旧值提供给客户端。这样万一出现运行中断的话,最多就是这个键值被浪费掉。
记录式存储:
键值首先被返还给客户端,然后记录到数据库中。这样做的缺点是,一旦系统中断,就有可能出现客户端已经使用了一个键值,而这个键值却
没有来得及存储到数据库中的情况。在系统重启后,系统还会从这个已经被使用过的键值开始,从而导致错误。

单例模式应用:序列键管理器

方案一:没有数据库的情况
//序列键生成器(单例类)
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());
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值