1. 前言
我相信很多在刚刚使用Spring的同事会考虑一个问题:
我们为什么要用Spring,Spring虽然给我们带来了一些好处,可是,似乎好处似乎不是那么明显。IOC的作用似乎也很牵强。
所以,冷凝沙漠在此记录了自己的一些Spring开发经验,与各位分享。
2. 一个常见的业务场景
2.1. 场景简介
一个非常常见的业务场景是:程序中会根据某一个特殊的参数,定义一系列不同的执行方式。
流程如下图所示:
2.2. 代码示例
形成代码之后大概会这么写:
publicclass Example1 { publicstaticvoid main(String[] args) { String specialParam = args[0];// 这是一个特定的参数
Object[] param1 = new Object[] {}; Object[] param2 = new Object[] {}; Object[] param3 = new Object[] {}; // ………… 以上是一堆常见、有规则的其他参数
if ("CanShu1".equals(specialParam)) {
// ………… 一堆冗长的程序
} elseif ("CanShu2".equals(specialParam)) { // ………… 又一堆冗长的程序
} elseif ("CanShu3".equals(specialParam)) {
// ………… 再一堆冗长的程序
} else {
// ………… 其他默认的冗长的程序 } } } |
2.3. 优缺点分析
从这个示例的角度,代码挺清晰的,但是到了实际应用中,可能就会有数十套逻辑,可能会有长达数千行代码,可能会绕晕很多人。
3. 一个常见的不好的修改方式
3.1. 场景简介与代码示例
如下是很常见的一个修改方式,将不同的流程提炼出独立的方法,让逻辑判断的位置独立出来。
publicclass Example2 {
publicstaticvoid main(String[] args) { String specialParam = args[0];// 这是一个特定的参数
Object[] param1 = new Object[] {}; Object[] param2 = new Object[] {}; Object[] param3 = new Object[] {}; // ………… 以上是一堆常见、有规则的其他参数
// 提炼独立方法 if ("CanShu1".equals(specialParam)) { handleCanShu1(param1, param2, param3); } elseif ("CanShu2".equals(specialParam)) { handleCanShu2(param1, param2, param3); } elseif ("CanShu3".equals(specialParam)) { handleCanShu3(param1, param2, param3); } else { handleDefault(param1, param2, param3); } }
publicstaticvoid handleCanShu1(Object[] param1, Object[] param2, Object[] param3) { // ………… 一堆冗长的程序 }
publicstaticvoid handleCanShu2(Object[] param1, Object[] param2, Object[] param3) { // ………… 又一堆冗长的程序 }
publicstaticvoid handleCanShu3(Object[] param1, Object[] param2, Object[] param3) { // ………… 再一堆冗长的程序 }
publicstaticvoid handleDefault(Object[] param1, Object[] param2, Object[] param3) { // ………… 其他默认的冗长的程序 } } |
3.2. 优缺点分析
相信各位维护的旧项目里面不会缺乏此类代码。
从维护的角度来看:
1. 如果要继续更新这个代码,也只能不断的在这个类上下功夫。很可能这个类未来会变成一个“只有上帝知道它是干嘛的”的复杂类。
2. 必须要有源码才能更新代码,才能重新编译。相信我,很多维护方没有源代码,这种修改对于程序员而言属于“Mission Impossible”。当然,对于搞IT的,天天玩程序员版的碟中谍,也是家常便饭。
因此,大部分Java培训师、Team Leader、代码走查员都会说:这样不好,这样不好!
4. 中规中矩的工厂模式
4.1. 场景简介
从模式的角度来看,工厂模式自然是这里最适合的模式:
咱们先提炼一个公共的接口,定义一个调用的工厂,再不断实现这个接口,并将接口注册到工厂。
未来如果要增加一种业务,就单独增加一个实现类,并注册到工厂就行了。
4.2. 代码示例
以下是一套简单的实现代码:
publicclass Example3 { publicstaticvoid main(String[] args) { String specialParam = args[0];// 这是一个特定的参数
Object[] param1 = new Object[] {}; Object[] param2 = new Object[] {}; Object[] param3 = new Object[] {}; // ………… 以上是一堆常见、有规则的其他参数 Example3Service service = Example3Factory.getService(specialParam); service.run(param1, param2, param3);
} } |
调用其实是很简单的。
package com.test; /** * 提炼出工厂和接口 */ publicclass Example3Factory { publicstatic Example3Service getService(String specialParam) { if ("CanShu1".equals(specialParam)) { returnnew Example3ServiceCanShu1Impl(); } elseif ("CanShu2".equals(specialParam)) { returnnew Example3ServiceCanShu2Impl(); } elseif ("CanShu3".equals(specialParam)) { returnnew Example3ServiceCanShu3Impl(); } else { returnnew Example3ServiceDefaultImpl(); } } } |
工厂类可以简单的如例子中写死,也可以写成collection形式,然后进行注册。
package com.test; /** * 提炼出工厂和接口 */ publicinterface Example3Service { publicvoid run(Object[] param1, Object[] param2, Object[] param3); }
|
接口神马的最简单了,以下就是接口实现:
package com.test;
publicclass Example3ServiceCanShu1Impl implements Example3Service { publicvoid run(Object[] param1, Object[] param2, Object[] param3) { // ………… 一堆冗长的程序 } } |
package com.test;
publicclass Example3ServiceCanShu2Impl implements Example3Service { publicvoid run(Object[] param1, Object[] param2, Object[] param3) { // ………… 又一堆冗长的程序 } } |
package com.test;
publicclass Example3ServiceCanShu3Impl implements Example3Service { publicvoid run(Object[] param1, Object[] param2, Object[] param3) { // ………… 再一堆冗长的程序 } } |
package com.test;
publicclass Example3ServiceDefaultImpl implements Example3Service { publicvoid run(Object[] param1, Object[] param2, Object[] param3) { // ………… 其他默认的冗长的程序 } } |
4.3. 优点分析
形成工厂模式的优点很明显:
l 提供创建对象的接口. 为系统结构提供了非常灵活强大的动态扩展机制,只要我们更换一下具体的工厂方法,系统其他地方无需一点变换,就有可能将系统功能进行改头换面的变化。
l 除了工厂类以外的程序都不需要去了解具体的实现情况,所以给程序实现带来了很多方便。
l 将程序的一部分复杂度集中在接口的实现上,一部分程序员可以专心于如何通过实现接口来实现业务逻辑,另一部分程序员可以专心于通过更新工厂注册方式来将新的实现对接到整个程序中。
4.4. 缺点分析
形成工厂模式的缺点也很明显:
l 工厂类依旧需要去了解具体的实现类以及其参数,当程序复杂度到一定程度时,工厂类依旧可能很复杂。
l 还是必须要有源码才能更新工厂类的代码,才能重新编译。
5. 开始引入Spring
5.1. 场景简介
既然工厂模式的缺点集中在工厂上,那么就优化工厂好了。我们可以把工厂优化为抽象厂,也可拆掉这个工厂,用Spring来替代这个工厂。
可以这样想,工厂类就是提供了一个Map,根据一个特定的key值,找一个特定的Bean。如果仅仅是这样,Spring自身是不是就能作为这个工厂了?
5.2. 代码示例
调用方的代码依旧很简单:
package com.test; import java.util.Map; import javax.annotation.Resource; publicclass Example4 { @Resource private Map example4ServiceMap; @Resource private Example4Service example4ServiceDefaultImpl;
publicvoid runMain(String specialParam) { Object[] param1 = new Object[] {}; Object[] param2 = new Object[] {}; Object[] param3 = new Object[] {}; // ………… 以上是一堆常见、有规则的其他参数
Example4Service service = example4ServiceMap.get(specialParam); if (service == null) { service = example4ServiceDefaultImpl; } service.run(param1, param2, param3); } } |
工厂的内容直接用Spring配置完成:
相关推荐
Spring设计模式简介:主要是讲述Spring源码中运用到的一些设计模式 Ibatis设计模式简介:主要是讲述Ibatis源码中运用到的一些设计模式 设计模式简介 1 单例模式 2 责任链模式 3 策略模式 4 模板方法模式 5 工厂方法...
——Lasse Koskela.JavaRanch版主,Test Driven作者“《深入解析Spring MVCgn Web Flow》是非常急缺的深入讲解Spring MVCf~~Spring Web Flow的图书堪与Pro Spring相媲美。” ——Steve Anglin,资深Java技术专家
全书分3篇共21章,具体内容包括:Spring环境的安装与使用、JSP与JSTL简介、 Spring基础概念与工具、用SpringJdbcTemplate访问数据库、使用Mayen工程、Spring MVC编程、基于 MVC的资源共享网站设计、Spring的AOP编程...
为了更系统的学习设计模式,特地开了这样一个基于Java...Spring设计模式简介:主要是讲述Spring源码中运用到的一些设计模式(将来增加) Ibatis设计模式简介:主要是讲述Ibatis源码中运用到的一些设计模式(将来增加)
为了更系统的学习设计模式,特地开了这样一个基于Java的设计模式【集中营...3. Spring设计模式简介:主要是讲述Spring源码中运用到的一些设计模式 4. Ibatis设计模式简介:主要是讲述Ibatis源码中运用到的一些设计模式
最终通过一个综合案例,实现灵活运用Spring框架中的各个部分。 2、适应人群 学习spring,要有一定的Java基础,同时应用过spring基于xml的配置。(或者学习过官网的Spring课程) 学习springmvc,要有一定java web...
为了更系统的学习设计模式,特地开辟了这样一个基于Java...Spring设计模式简介:主要讲述Spring源码中运用到的一些设计模式(未来增加) Ibatis设计模式简介:主要是讲述Ibatis源码中运用到的一些设计模式(未来增加)
善于运用SpringCloud,解脱传统的开发模式的苦恼2、让开发者能够学习更多的开发使用技巧,成为微服务开发大牛〖课程目录〗:1-101什么是微服务.mp41-1010创建父级工程.mp41-1111创建子工程API.mp41-1213创建微服务...
xml注入注解注入简单MVC功能注入支持递归注入属性注入引用注入(但未解决循环依赖)注解配置单例以及原型模式切换运用的设计模式工厂设计模式:Spring使用工厂模式通过BeanFactory,ApplicationContext创建bean对象...
Spring 设计的核心是 org.springframework.beans 包,它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 BeanFactory 接口...
spring-jdbc-orm基于...技术实现此小工具运用了注解和反射,其中在设计上运用了一些设计模式,例如工厂模式,策略模式,组合模式。参考资料封装sql语句的的代码参考了 hibernate 中Criteria接口和实现对应的部分,
设计模式简介:主要介绍各种设计模式的概念和运用场景等设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼Spring设计模式简介:主要是讲述Spring源码中运用到的一些设计模式(将来...
◇ 熟练运用struts2、hibernate、spring、springmvc、mybatis、jquery、Ajax、JSTL/EL、WebService、jdbc、dom4j、log4j等技术 ◇ 掌握常用的JAVA设计模式,熟悉软件设计开发流程 ◇ 了解MySql、Oracle等数据库。 ◇ ...
2、可以灵活运用设计模式,如:单例、工厂、策略、责任链、模板方法等设计模式进行项目开发 3、熟悉Spring、 SpringMVC、SpringBoot、SpringCloud、Mybaits、Mybaits-Plus等开发技术。 4、熟悉分布式常见解决方案:...
与DotNet数据对象结合的自定义数据对象设计 (二) 数据集合与DataTable 与DotNet数据对象结合的自定义数据对象设计 (一) 数据对象与DataRow ASP.NET中大结果集的分页[翻译] .net 2.0 访问Oracle --与Sql Server的...
●运用工厂模式设计程序●理解JavaBean和POJO对象●理解控制反转思想●理解IOC容器在一个乡村小学校,一天只上三节课,有三名老师和一个校长。张老师负责教学生语文,王老师教学生数学,李老师教音乐,校长负责安排...
Web MVC和Spring Web提供了Java Web应用的框架或与其他流行的Web框架进行集成。 就是说可将两者一起使用,达到将两者自身的特点进行互补。 spring 框架介绍 : 它关注的领域是其他许多流行的Framework未曾关注的...