9.2.2 利用优秀的框架
9.2.2 利用优秀的框架
使用框架可以大大提高系统的开发效率。除非开发一个非常小的系统,而且是开发后无须修改的系统,才可以完全抛弃框架。
优秀的框架本身就是从实际开发中抽取的通用部分,使用框架就可以避免重复开发通用部分。使用优秀的框架不仅可以直接使用框架中的基本组件和类库,还可以提高软件开发人员对系统架构设计的把握。使用框架有如下几个优势
1.提高生产效率
框架是在实际开发过程中抽取出来的通用部分。使用框架可以避免开发重复的代码,看下面的JDBC数据库访问代码。
上面的代码是连接数据库执行数据更新的代码。而这个过程的大部分都是固定的,包括连接数据库创建Statement及执行更新等,唯一需要变化的是SQL语句。
在实际的开发过程中,不可能总是采用这种步骤进行数据库访问,为避免代码重复,可在实际的开发中提取出如下方法:
上面的代码可以大大减少代码的重复量,但依然需要开发者完成连接数据库、创建PreparedStatement等步骤。如果使用Spring的JDBC抽象框架,上面的代码则可以简化为如下:
借助于Spring的JDBC抽象框架,数据库访问无须手动获取连接,无须创建Statement等对象。只需要传入一个Data Source对象,由Jdbc Template完成Data Source获取数据库连接;创建Statement对象执行数据库更新的通用步骤。而软件开发者只需要提供简单的SQL语句即可。
另外,使用框架可以缩短系统的开发时间,特别是对于大型项目的开发,使用框架的优势将更加明显。
2.具有更稳定、更优秀的性能
如果不使用己有的框架,系统开发者将面临着需要自己完成所有的底层部分。除非开发者丝毫不遵守软件复用的原则,总是重复书写相同代码。
系统开发者从系统开发中提取出的共同部分,也可成为框架。不可否认,完全由开发者自己提取框架有自己的优势,开发人员更加熟悉框架的运行,无须投入成本学习新的技术;但借助于已有框架的优势更加明显,已有的框架通常已被非常多的项目验证过,框架的性能等通常更有保障,而开发者自己提取的框架则可能包含许多未知的隐患。
因此为了更好地了解框架底层的运行,建议使用开源框架。
3.更好的保值性
采用框架开发的系统使模块组织更加一致,从而降低了软件开发者之间的沟通成本,使系统具有更好的可读性,从而让软件系统具有更好的保值性
后期的更新、维护也是企业级应用开发的重要组成部分。而使用框架的系统具有很大的相似性,从而有利于后期的更新及维护。
9.2 如何面对挑战 9.2.1 使用建模工具
9.2 如何面对挑战
除了上文介绍的所面临的各种技术挑战之外,企业级应用还有更多的挑战。每个行业都有各自复杂的规则,软件开发者往往缺乏对行业规则的了解。企业级应用的开发通常需要软件开发者和行业专家齐心协作,但系统开发中的沟通成本相当高,因为软件开发者与行业专家之间的沟通往往存在不少障碍,这些都会影响系统的开发。
面对这些挑战,本书提供如下建议。
9.2.1 使用建模工具
此处的建模工具不一定是ROSE等,可以是简单的手画草图。当然,借助于专业的建模工具可以更好地确定系统模型。
任何语言的描述都很空洞,而且具有很大的歧义性。使用图形则更加直观,而且意义更加明确。推荐使用建模工具主要出于如下两个方面的考虑。
- 用于软件开发者与行业专家之间沟通,正如前文所介绍的,行业专家与软件开发者之间对系统的理解可能存在少许差异。使用图形来帮助交流是不错的主意,通过建模工具绘制的各种图形,可使软件系统的模型更加清晰化.
- 用于软件开发者之间的沟通。即使在软件开发者内部,对于软件模型的认识往往也不是非常统一的。使用建模工具可以减少软件开发者对于系统的理解分歧,从而降低沟通成本.
关于建模工具,推荐采用统一建模语言:UML。但UML的使用也需要掌握分寸,在软件开发人员内部使用时,尽可能使用规范的UML;但用于与行业专家沟通时,则应该尽量增加文字说明,而不要拘泥于UML图形的表现上,切忌仅将一个图形生硬摆出。
9.1.4 花费最小化 利益最大化
9.1.4 花费最小化 利益最大化
这是个永恒的话题,任何一个商业组织都希望尽可能地降低开销。对开发者而言,降低开销主要是如何使在开发上的投资更有保值效果;即开发的软件系统具有很好的复用性,而不是每次面临系统开发任务时,总是需要重复开发。
尽可能让软件可以有高层次的复用,这也是软件行业的发展趋势。早期软件多采用结构化的程序设计语言,此时的软件复用多停留在代码复用的层次。面向对象的程序设计语言的出现,使代码复用提高到了类的复用。
在良好的Java EE架构设计中,复用是一个永恒的追求目标。架构设计师希望系统中大部分的组件可以复用,甚至能让系统的整个层可以复用。对于采用DAO模式的系统架构,如果数据库不发生大的改变,整个DAO层都不需要变化。
9.1.3 稳定性 高效性
9.1.2 快捷 可控的开发
9.1.2 快捷 可控的开发
如果没有时间限制,任何一个软件系统在理论上都是可实现的。但这样的条件不存在,软件系统必须要及时投放市场。对于企业级应用,时间的限制则更加严格。正如前文介绍的,企业的信息是瞬息万变的,与之对应的系统必须能与时俱进。因此快捷、可控是企业信息化系统必须面对的挑战。
软件开发人员常常乐于尝试各种新的技术,总希望将各种新的技术带入项目的开发中,因而难免有时会将整个项目陷入危险的境地。
当然,采用更优秀、更新颖的技术,通常可以保证软件系统的性能更加稳定。例如,从早期的C/架构向BS架构的过渡,以及从Model 1到Model2的过渡等。这些都提高了软件系统的可扩展性及可伸缩性。
但采用新的技术所带来的风险也是不得不考虑的,开发架构必须重新论证,开发人员必须重新培训,这都需要成本投入。如果整个团队缺乏精通该技术的领导者,项目的开发难免会陷入技术难题,从而导致软件的开发过程变成不可控的——这是非常危险的事情。
成功的企业级应用,往往可以保证其良好的可扩展性及可伸缩性,并建立在良好的可控性的基础上。
9.1 企业应用开发面临的挑战 9.1.1 可扩展性 可伸缩性
9.1 企业应用开发面临的挑战
企业应用的开发是相当复杂的,这种复杂除表现在技术方面外,还表现在行业本身所蕴含的专业知识上。企业级应用的开发往往需要面对更多的问题:大量的并发访问,复杂的环境,网络的不稳定,还有外部的Crack行为等。因此企业级应用必须提供更好的多线程支持,具备良好的适应性及良好的安全性等。
由于各行业的应用往往差别非常大,因此企业级应用往往具有很强的行业规则,尤其是优良的企业级应用往往更需要丰富的行业知识。企业应用的成功开发,也需要很多人的共同协作。
下面对企业应用开发面临的挑战作具体分析。
9.1.1 可扩展性、可伸缩性
市场是瞬息万变的,企业也是随之而变的。而信息化系统是为企业服务的,随着企业需求的变化企业应用的变化也是必然的
在多年开发过程中,经常听到软件开发者对于需求变更的抱怨。当开发进行到中间时,大量的工作需要重新开始,确实给人极大的挫败感,难免软件开发者会抱怨。不过,一个积极的软件开发者应该可以正确对待需求的变更。需求的变更,表明有市场前景,只有有变化的产品才是有市场的产品。
优秀的企业级应用必须具备良好的可扩展性和可伸缩性。因为良好的可扩展性可允许系统动态增加新功能,而不会影响原有的功能。
良好的可扩展性建立在高度的解耦之上。使用Delphi、 Power Builder等工具的软件开发人员对ini文件一定不会陌生。使用ini文件是一种基本的解耦方式,将运行所需资源、模块的耦合等从代码中分离出来,放入配置文件管理。这是一种优秀的设计思路,最理想的情况是允许使用可插拔式的模块(类似于Eclipse的插件方式)。
在Java EE应用里,大多采用XML文件作为配置文件。使用XML配置文件可以避免修改代码,从而能极好地提高程序的解耦。XML文件常用于配置数据库连接信息,通过使用XML文件的配置方式,可以让应用在不同的数据库平台上轻松切换;从而避免在程序中使用硬编码的方式来定义数据库的连接,也避免了在更改数据库时,需要更改程序代码,从而提供更好的适应性.
下面是使用Spring的Bean定义数据源的代码。
1 | <!-- 定义数据源Bean,使用C3P0数据源实现,并注入数据源的必要信息 --> |
上面的配置文件可用于建立数据库的连接,且等同于如下代码:
1 | //创建数据源实例 |
可以看出,第一种方式明显比第二种方式更优秀。因为当系统的数据库发生变化时(这是相当常见的情形),开发用的数据库与实际应用的数据库不可能是同一个数据库,当软件系统由客户使用时,其数据库系统也是需要改变的。采用第一种方式则无须修改系统源代码,仅通过修改配置文件就可以让系统适应数据库的改变。
使用XML配置文件提高解耦的方式,是目前企业级应用最常用的解耦方式,而依赖注入的方式则提供了更高层次的解耦。使用依赖注入可以将各模块之间的调用从代码中分离出来,并通过配置文件来装配组件。此处的依赖注入并非特指Spring,事实上,依赖注入容器很多,如HiveMind等。
第9章企业应用开发的思考和策略 9.0 本章要点
第9章企业应用开发的思考和策略 9.0 本章要点
- 企业应用开发的挑战
- 解决企业应用开发中挑战的思考方式
- 设计模式的背景
- 单例模式
- 简单工厂
- 工厂方法和抽象工厂
- 代理模式
- 命令模式
- 策略模式
- 门面模式
- 桥接模式
- 观察者模式
- 软件架构设计的原则
- 贫血模式
- 领域对象模型
- 领域对象模型的简化设计
企业级应用的开发平台相当多,如Java EE、.NET、PHP和Ruby On rails等。这些平台为企业级应用的开发提供了丰富的支持,都实现了企业应用底层所需的功能:缓冲池、多线程及持久层访问等。虽然有如此之多的选择,企业级应用的开发依然困难重重。
本章将会简要介绍企业开发应用过程中所面临的困难,以及面对这些困难时常用的思考方式和应对策略。开发一个大型企业级应用时,常常必须面对各种各样的问题,而这些问题常常具有特定的场景,而且往往会重复出现,借助于前人已有的、较为成熟的解决方案来解决这些问题,既可提高应用开发的效率,也可保证应用开发的质量。这些前人已有的、较为成熟的解决方案就是所谓的设计模式,本章将会深入介绍Java EE应用中常用的设计模式。
所有企业级应用的开发平台都提供了高级、抽象的API,但仅依靠这些API构建企业级的应用远远不够。在这些高级API基础上,搭建一个良好的开发体系,也是企业级应用开发必不可少的步骤。本章将从理论上介绍如何搭建一个良好、可维护、可扩展、高稳定性且能够快速开发的应用架构,本章还会重点介绍Java EE应用中常用的架构模型。
8.6.3 使用@Transactional
8.6.3 使用@Transactional
Spring还允许将事务配置放在Java类中定义,这需要借助于@Transactional注解,@Transactional注解既可用于修饰Spring Bean类,也可用于修饰Bean类中的某个方法。
- 如果使用
@Transactional修饰Bean类,则表明这些事务设置对整个Bean类起作用; - 如果使用
@Transactional修饰Bean类的某个方法,则表明这些事务设置只对该方法有效。
使用@Transactional时可指定如下属性。
| 属性 | 描述 |
|---|---|
isolation |
用于指定事务的隔离级别。默认为底层事务的隔离级别。 |
noRollbackFor |
指定遇到特定异常时强制不回滚事务。 |
noRollbackForClassName |
指定遇到特定的多个异常时强制不回滚事务。该属性值可以指定多个异常类名 |
propagation |
指定事务传播行为 |
readOnly |
指定事务是否只读 |
rollbackFor |
指定遇到特定异常时强制回滚事务。 |
rollbackForClassName |
指定遇到特定的多个异常时强制回滚事务。该属性值可以指定多个异常类名。 |
timeout |
指定事务的超时时长。 |
根据上面的解释不难看出,其实该注解所指定的属性与<tx:advice.>元素中所指定的事务属性基本上是对应的,它们的意义也基本相似。
程序示例
1 | E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\Transactional |
下面使用@Transactional修饰需要添加事务的方法。
1 | ... |
上面Bean类中的insert()方法使用了 @Transactional修饰,表明该方法具有事务性。仅使用这个注解修饰还不够,还需要让Spring根据注解来配置事务代理,所以还需要在Spring配置文件中增加如下配置片段。
1 | <?xml version="1.0" encoding="GBK"?> |