文章插图
1、使用框架的意义与Spring的主要内容
随着软件结构的日益庞大 , 软件模块化趋势出现 , 软件开发也需要多人合作 , 随即分工出现 。如何划分模块 , 如何定义接口方便分工成为软件工程设计中越来越关注的问题 。良好的模块化具有以下优势:可扩展、易验证、易维护、易分工、易理解、代码复用 。
优良的模块设计往往遵守“低耦合高内聚”的原则 。而“框架”是对开发中良好设计的总结 , 把设计中经常使用的代码独立出来 , 所形成的一种软件工具 。用户遵守它的开发规则 , 就可以实现良好的模块化 , 避免软件开发中潜在的问题 。广义上的框架无处不再 , 一个常见的例子就是PC硬件体系结构 , 人们只要按照各自需要的主板、显卡、内存等器件就可以任意组装成自己想要的电脑 。而做主板的厂商不用关心做显卡厂商的怎么实现它的功能 。软件框架也是如此 , 开发人员只要在Spring框架中填充自己的业务逻辑就能完成一个模块划分清晰纷的系统 。
这里主要通过一个银行通知用户月收支记录的小例子来介绍轻型J2EE框架Spring的主要内容、它所解决的问题和实现的方法 。
Spring框架主要可以分为3个核心内容:
- 容器
- 控制反转(IoC , Inversion of Control)
- 面向切面编程(AOP , Aspect-Oriented Programming)
2、一个简单的例子程序
假设有一个如下应用场景:(1)一个银行在每月的月初都需要向客户发送上个月的账单 , 账单发送的方式可以为纸质邮寄、或者短信方式 。(2)还有一个潜在的需求:为了安全起见 , 在每个函数操作过程中都需要记录日志 , 记录参数传入是否正常 , 函数是否正常结束 , 以便出错时系统管理员查账 。
那么对这个需求进行简单实现 。系统框图如下所示:
文章插图
首先定义一个账单输出的接口:
//接口public interface ReportGenerator{ public void generate(String[][] table) ;}
实现“打印纸质账单”与“发送短信”两个具体功能:
//账单报表实现类 public class PageReportGenerator implement ReportGenerator { public void generate(String[][] table) { log4j.info( ... ); //输出日志...打印操作 , 以便工作人员邮递给客户 log4j.info( ... ); //输出日志} }
//短信报表实现类 public class SMSReportGenerator implement ReportGenerator { public void generate(String[][] table) { log4j.info( ... ); ...短信发送操作 log4j.info( ... ); }}
上层业务逻辑对上个月的账目进行统计并调用接口产生纸质或者短信结果:
//上层业务中的服务类 public class ReportService{private ReportGenerator reportGenerator = new SMSReportGenerator();public void generateMonthlyReport(int year, int month) {log4j.info( ... );String[][] statistics = null ;...reportGenerator.generate(statistics);}}
这个实现源代码请查看文章结尾附录中的"BankOld" 。源代码中与例子中程序略有区别:由于使用log4j需要引用外部的包 , 并且需要写配置文件 , 为了方便 , 源代码中的日志输出用system.out.println()代替 。3、Spring中的容器
A、模块化后出现的问题与隐患
假设随着工程的复杂化 , 上面的例子需要分成两个模块 , 以便开发时分工 , 一般会以如下结构划分:
文章插图
划分后再看原来的代码:
//上层业务中的服务类 public class ReportService{private ReportGenerator reportGenerator = new SMSReportGenerator(); //隐患public void generateMonthlyReport(int year, int month) {...} }
在服务类有private ReportGenerator reportGenerator = new SMSReportGenerator();这么一行代码 , ReportService类与SMSReportGenerator类不属于同一个模块 , 当开发人员B对内部实现进行修改时 , 由于存在依赖 , 开发人员A也要进行修改(比如之前喜欢短信收账单的客户感觉短信不够详细 , 希望以后改用邮件收账单 , 那么开发人员B需要实现一个MailReportGenerator类 , 在开发人员B修改代码时 , 开发人员A也需要改代码------声明部分修改) 。如果系统庞大new
推荐阅读
- eclipse下创建Maven风格的java项目
- java中的参数传递
- Java 如何实现线程死锁?
- 如何搭建java的运行环境
- Java多线程编程——锁优化
- 九种跨域方式实现原理
- Java泛型大全
- JavaScript获取json中key所对应的value值的简单方法
- Java进程CPU占用高导致的网页请求超时的故障排查
- 谁说JAVA不适合做神经网络,那来看看Encog这款框架吧