
4.2 为什么一定要学习设计模式
先来看一个生活案例,当我们开心时,也许会寻求享乐。在学习设计模式之前,你可能会这样感叹:

学完设计模式之后,你可能会这样感叹:

大家对比一下前后的区别,有何感受?

回到代码中,我们来思考一下,设计模式能解决哪些问题?
4.2.1 写出优雅的代码
先来看一段笔者很多年前写的代码。


优化之后的代码如下。


4.2.2 更好地重构项目
平时我们写的代码虽然满足了需求,但往往不利于项目的开发与维护,以下面的JDBC代码为例。



上述代码的功能没问题,但是代码重复得太多,因此可以进行抽取,把重复代码放到一个工具类JdbcUtil里。

只需要在实现类中直接调用工具类JdbcUtil中的方法即可。



虽然完成了重复代码的抽取,但数据库中的账号、密码等直接显示在代码中,不利于后期账户密码改动的维护。可以建立一个db.propertise文件,用来存储这些信息。

只需要在工具类JdbcUtil中获取里面的信息即可。


代码抽取到这里,貌似已经完成,但在实现类中,依然存在部分重复代码,在DML操作中,除了SQL和设置值的不同,其他都相同,把相同的部分抽取出来,把不同的部分通过参数传递进来,无法直接放在工具类中。此时,可以创建一个模板类JdbcTemplate,创建一个DML和DQL的模板来对代码进行重构。


实现类直接调用方法即可。

这样重复的代码基本就解决了,但有一个很严重的问题,就是这个程序DQL操作中只能处理Student类和t_student表的相关数据,无法处理其他类,比如Teacher类和t_teacher表。不同的表(不同的对象)应该有不同的列,不同列处理结果集的代码就应该不一样,处理结果集的操作只有DAO自己最清楚。也就是说,处理结果的方法根本就不应该放在模板方法中,应该由每个DAO自己来处理。因此,可以创建一个IRowMapper接口来处理结果集。


DQL模板类中调用IRowMapper接口中的handle方法,提醒实现类自己去实现mapping方法。

实现类自己去实现IRowMapper接口的mapping方法,想要处理什么类型的数据在里面定义即可。


到这里为止,实现ORM的关键代码已经大功告成,但是DQL查询不单单要查询学生信息(List类型),还要查询学生数量,这时就要通过泛型来完成。

StudentRowMapper类的代码如下。


这样,不仅可以查询List,还可以查询学生数量。

这样,重构设计就已经完成,好的代码能让我们以后维护更方便,因此学会对代码重构是非常重要的。
4.2.3 经典框架都在用设计模式解决问题
比如,Spring就是一个把设计模式用得淋漓尽致的经典框架。本书会结合JDK、Spring、MyBatis、Netty、Tomcat、Dubbo等经典框架的源码对设计模式展开分析,帮助大家更好、更深入地理解设计模式在框架源码中的落地。