编码素养问题收集2:连接不归还池,不学TemplateCallback惹的祸
2013-12-05 17:02
253 查看
关于连接池大家常常用的代码:(1)从池中申请链接;(2)使用链接;(3)归还连接。以Jedis操作Redis为例:
如果上述代码在整个工程中只出现1次,那没问题;如果上述代码在工程中出现N次,这代码素养就有问题。你没法保证每个程序员都会归还池,更不能保证每个程序员都会在finally里面归还池。程序的设计者应该去保证程序的使用者不那么容易犯错误才对。
重新设计:
使用样例:
这个思维过程是怎么样的? 先看段简单代码:
很快大家发现打印的信息很多是冗余的,三个语句只有名字不同,大家马上会抽象出用一个输入参数来存储名称,于是:
同样的道理,当我们发现(1)从池中申请链接;(2)使用链接;(3)归还连接 类似的代码使用N遍的时候,其中只有第2步不同,我们就需要消除冗余代码。问题的关键在于第2部不是个简单变量,因为它可能是jedis.hget(),也可能是jedis.hmset(),又或者是jedis.get() 变化的不仅是jedis实例对象,而且还有方法也在变。我们可以理解把一份数据(一个变量)传递来传递去,但是很难想象把一个行为,一个动作传递来传递去。实际上这个想法早就有了,C里面的“函数指针”就是让一个行为传递来传递去的。但JAVA里面没有函数指针,为什么?因为JAVA是面向对象的,对象本身就是数据+行为的结合体。所以jedis.hget(),也可能是jedis.hmset(),又或者是jedis.get()
可以整体抽象为一个“对象”,但是这个对象更多关心的是“函数传递”,这就是为什么JAVA里面会有“匿名内部类”这种东东(等效函数指针)。最后,Spring的JdbcTemplate也是这种机制,大家用jdbc的时候,从来没有申请链接,归还连接这个动作,而是从来就是使用就够了。
ShardedJedis jedis = RedisUtil.getMyShardedJedisPool().getResource(); try { jedis.hmset(XXX)//其他N多地方出现jedis.get()或者set等操作 } finally { if (jedis != null) { RedisUtil.getMyShardedJedisPool().returnResource(jedis); } }
如果上述代码在整个工程中只出现1次,那没问题;如果上述代码在工程中出现N次,这代码素养就有问题。你没法保证每个程序员都会归还池,更不能保证每个程序员都会在finally里面归还池。程序的设计者应该去保证程序的使用者不那么容易犯错误才对。
重新设计:
public static <T> T execute(RedisCallback<T> redisCallback) { //TemplateCallback Pattern (Genericity Supported Callback) ShardedJedis jedis = RedisUtil.getMyShardedJedisPool().getResource(); try { return redisCallback.doCmd(jedis); } finally { if (jedis != null) { RedisUtil.getMyShardedJedisPool().returnResource(jedis); } } }
使用样例:
/* 写入redis */ RedisUtil.execute(new RedisCallback<String>() { @Override public String doCmd(ShardedJedis jedis) { return jedis.hmset(cookieId, valueMap); } });
这个思维过程是怎么样的? 先看段简单代码:
System.out.println("张三,您好,欢迎加入XX大家庭。"); System.out.println("李四,您好,欢迎加入XX大家庭。"); System.out.println("王五,您好,欢迎加入XX大家庭。");
很快大家发现打印的信息很多是冗余的,三个语句只有名字不同,大家马上会抽象出用一个输入参数来存储名称,于是:
sayHi("张三"); sayHi("李四"); sayHi("王五"); private static void sayHi(String name) { System.out.println(name+",您好,欢迎加入XX大家庭。"); }
同样的道理,当我们发现(1)从池中申请链接;(2)使用链接;(3)归还连接 类似的代码使用N遍的时候,其中只有第2步不同,我们就需要消除冗余代码。问题的关键在于第2部不是个简单变量,因为它可能是jedis.hget(),也可能是jedis.hmset(),又或者是jedis.get() 变化的不仅是jedis实例对象,而且还有方法也在变。我们可以理解把一份数据(一个变量)传递来传递去,但是很难想象把一个行为,一个动作传递来传递去。实际上这个想法早就有了,C里面的“函数指针”就是让一个行为传递来传递去的。但JAVA里面没有函数指针,为什么?因为JAVA是面向对象的,对象本身就是数据+行为的结合体。所以jedis.hget(),也可能是jedis.hmset(),又或者是jedis.get()
可以整体抽象为一个“对象”,但是这个对象更多关心的是“函数传递”,这就是为什么JAVA里面会有“匿名内部类”这种东东(等效函数指针)。最后,Spring的JdbcTemplate也是这种机制,大家用jdbc的时候,从来没有申请链接,归还连接这个动作,而是从来就是使用就够了。
相关文章推荐
- 编码素养问题收集1:基于名称映射的单例模式的并发控制
- 编码素养问题收集4:MySQL数据导入导出如何证明结果是正确的?
- 编码素养问题收集3:TeamLeader应该“有教无类”
- 编码素养5:减少冗余代码-让一段方法Template-callback
- mysql 连接诡异问题收集
- pom文件格式编码的问题,导致收集不到覆盖率
- 连接不同字符集编码Oracle问题处理过程
- SSH连接出错问题收集
- java三大框架之spring配置template连接数据库中文乱码问题
- c++连接mysql的中文编码问题
- Hibernate连接MySQL的编码问题
- JSP连接MYSQL查询编码问题解决
- 终于解决了jsp连接mysql的中文编码问题!
- IntelliJ下使用Code/Live Template加快编码速度:程序员的工作不是写程序,而是写程序解决问题
- IntelliJ下使用Code/Live Template加快编码速度:程序员的工作不是写程序,而是写程序解决问题
- (转)MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结
- JAVA 数据库连接编码问题
- Jenkins连接TFS出现错误:“jenkins com.microsoft.tfs.core.exceptions.TECoreException”的问题收集
- linux安装mysql全纪录[包括yum和rpm安装,编码,远程连接以及大小写问题]
- (转)MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结