假如要讓你封裝jedis以便讓外界調(diào)用你大概率會像下面方法一樣實現(xiàn)。
@Service
public class JedisSpringDemo {
@Resource(name = "shardedJedisPool")
private ShardedJedisPool shardedJedisPool;
public String set(String key, String value){
ShardedJedis shardedJedis = null;
try{
// 從連接池中獲取jedis分片對象
shardedJedis = shardedJedisPool.getResource();
// 設置值到redis中
return shardedJedis.set(key, value);
}catch (Exception e){
System.out.println(e.getMessage());
}finally {
if(null != shardedJedis){
shardedJedis.close();
}
}
return null;
}
public String get(String key){
ShardedJedis shardedJedis = null;
try{
// 從連接池中獲取jedis分片對象
shardedJedis = shardedJedisPool.getResource();
// 從redis中獲取key對應value
return shardedJedis.get(key);
}catch (Exception e){
System.out.println(e.getMessage());
}finally {
if(null != shardedJedis){
shardedJedis.close();
}
}
return null;
}
}
上面的這段代碼違反了DRY原則戳葵,兩個方法get()和set()大部分代碼是相同的(try就乓,catch,finally這部分代碼)拱烁,唯一不同的就是我們return的那一行具體的調(diào)用方法档址,如果像這種方法很多的話(jedis提供了幾十種類似的方法),我們的代碼重復率是很高的邻梆,代碼重復率一旦高起來守伸,相應的維護成本也會提高,下面我們就來引進一種改進方法--回調(diào)機制浦妄。
首先尼摹,我們創(chuàng)建一個接口類,該接口定義Jedis的操作剂娄,代碼如下:
public interface RedisOperations {
<T> T execute(ConnectionCallback<T> action);
String set(final String key, final String value);
String get(final String key);
}
其次蠢涝,定義連接Redis服務器的回調(diào)接口,代碼如下:
public interface ConnectionCallback<T> {
T doInRedis(ShardedJedis shardedJedis);
}
最后定義具體的操作服務類阅懦,代碼如下:
@Service("redisTemplate")
public class RedisTemplate implements RedisOperations{
@Resource(name = "shardedJedisPool")
private ShardedJedisPool shardedJedisPool;
@Override
public <T> T execute(ConnectionCallback<T> action) {
ShardedJedis shardedJedis = null;
try{
// 從連接池中獲取jedis分片對象
shardedJedis = shardedJedisPool.getResource();
return action.doInRedis(shardedJedis);
}catch (Exception e){
System.out.println(e.getMessage());
}finally {
if(null != shardedJedis){
shardedJedis.close();
}
}
return null;
}
/**
* attention:真正封裝的方法和二,非常的簡潔干脆
*/
public String set(final String key, final String value){
return execute(new ConnectionCallback<String>() {
@Override
public String doInRedis(
ShardedJedis shardedJedis) {
return shardedJedis.set(key, value);
}
});
}
public String get(final String key){
return execute(new ConnectionCallback<String>(){
@Override
public String doInRedis(ShardedJedis shardedJedis) {
return shardedJedis.get(key);
}
});
}
}
通過上面的代碼,我們可以清晰的看到耳胎,將try惯吕,catch,finally部分的公共代碼都封裝到了execute()函數(shù)中怕午,在具體方法內(nèi)實現(xiàn)回調(diào)方法的具體業(yè)務邏輯即可废登,代碼的復用率更高了。
如果大家對spring jdbc或者是spring data redis的源碼研究過郁惜,就應該知道JdbcTemplate和RedisTemplate這兩個類堡距,這兩個框架中用到了大量的callback機制。
一言以蔽之--如果你調(diào)用我,那么我就回調(diào)你傳給我的對象的方法羽戒。