最近项目组里有一个bug,虽然我们大家都没有因为他而享受到“深夜静静改bug”的“乐趣”,但他也着实郁闷了我们一番。还好我们的Mr S同学已经将他拿下,在这篇blog,将记录下我看到这个bug时的思考:
bug描述:我们既存的一个连接池出现了泄漏问题。
bug原因:
我们有下面这么一个函数
void freeConnection(String type, ConnectionAdapter con);
因为我们有两个连接池,一个叫做Derby,一个叫做demo,使用一个字符串指明链接要网哪里还。然而问题来了,以前的一位同事,写下了下面这样的代码:
String dbConnType = "derby"
......
db.freeConnection("dbConnType", conn);
是的,因为根本不存在dbConnType这么一个连接池。所以运行一段时间之后,我们的的连接池里面没有了链接。
bug改修:
那么这个bug该怎么改呢? 拿掉那个变量的双引号?我想不是的。好的办法我认为有几个,最后一个是前面几个的递进,但他们思考的角度都是让接口更友善,让使用更方便:
1. 从freeConnection的角度思考,在freeConnection里面加卫语句。
既然我们能确定我们的代码中只有两个pool,那么当freeConnection在接受到"derby"和"demo"这两个参数以为的参数的时候,他就应该报告他的调用者,说:“嗨,你使用我使用错了。” 比如我们可以抛出一个IllegalArgumentException。
2. 从freeConnection的调用者的角度思考。改变freeConnection的调用参数。
这个问题的一个很隐晦的地方在于,使用了字符串来标识,我们要释放拿个池的链接。而程序中又充值着这样的使用方法。
db.freeConnection("derby", conn); //想加引号,因为想直接释放derby这个池
db.freeConnection("dbConnType", conn); //不想加引号,无用了,但是编译器没有帮我们区分过来。
这两个用法本身就很容易混,那么从freeConnection函数的使用者看来,完全有理由呼吁一个更友善的接口,比如像下面这样
ConnectionManager{
...
public static final ConnectionPool DERBY_POOL = ...
public static final ConnectionPool DEMO_POOL = ...
...
}
void freeConnection( ConnectionPool pool , ConnectionAdapter con);
这样做的好处是,利用类型保证了参数不会被误传,但是这样做的同时也暴露了很多东西,引来了其他的一些不可取之处。比如带着一个没用的参数,还是一个链接池,在代码各处跑来跑去,这么麻烦我们当初还为什么要写ConnectionManager
3. 综上,所以有了方法三:freeConnection方法的接口其实根本就应该是这样的;
freeConnection(Connection conn);
是的,总之是用户传递错误了参数,那么与其像上面那样,帮助用户传递正确的参数,到不如压根就不要求用户传递这个参数。而且,既然你有意要做一个ConnectionManage,那么关于这个池那个池的,本身就应该封装在你的里面,Don't make user think了。
恩,事情说完了。<!----><!---->
<!---->保证质量是多方面的,不是很努力的测就可以解决的问题,先撇开测试调试的技巧之类,其势必也受质量等其他因素的制约。好的设计从哪里来呢?好的设计应该即是程序员推敲的结果,又是他们的直觉使然。
分享到:
相关推荐
温昱老师根据实践经验总结出五个不同质量级别的项目案例,这些案例从不同的角度揭示了设计对项目成功的关键作用: 1. **优秀**:设计合理,团队成员有成就感,项目按时完成,Bug少。 2. **良好**:设计尚可,项目能...
在编程领域,派生类是面向对象编程中的一个重要概念,它是从一个已有的基类(这里指`CEDIT`)创建新类的方式。`CEDIT`通常是指MFC(Microsoft Foundation Classes)框架中的CEdit类,它是一个用于处理文本编辑控件的...
- 重新审视类的设计,确保每个类都有清晰的职责。 #### 7. Data Clumps(数据簇) **定义:** 数据簇是指一组总是同时出现的数据。这通常是因为这些数据紧密相关,但被错误地分散在多个类或方法中。 **问题:** -...
因此,DBA需要具备能够从不同角度审视问题,并且在必要时能够打破常规思维,创造性地找到问题的解决方法。 经验传承是书中另一个重要主题。顾问级DBA通常拥有丰富的实践经验,而如何将这些经验有效地传授给其他DBA...
19. 角度转换:看待问题时,尝试站在他人的角度,这有助于增进理解,改善团队关系,也有利于解决开发中的冲突。 20. 简单与本质:如同白开水与五彩饮料,软件开发有时也需要回归本质,专注于解决核心问题,避免被...
理解基本概念如变量、数据类型、运算符、控制流语句等是学习的基础。不要急于求成,把这些基础知识牢牢掌握。 2. 多加练习 理论知识固然重要,但实践演练更为关键。每学会一个新概念,都要亲自动手编写示例代码,并不断...
在这篇年终总结中,我将详细分享我在过去一年中的经历与成就,以此作为自我审视和规划未来职业生涯的重要依据。 一、技术学习的扎实根基 作为软件工程师,技术的不断学习与进步是职业生涯的核心。今年,我开始了对...
合理地使用代码缩进、分割长语句、正确地书写函数参数以及大括号的使用规范,都是编写可读性强的代码所不可或缺的要素。 此外,模块化编程是嵌入式系统开发中不可或缺的技能。在实际工作中,通常需要与团队其他成员...