比较巧,自己在接触设计模式的时候,也刚开始学习spring,但可惜的是,真的仅仅在学习“用”spring,每天都沉浸在会痛快的完成spring各种配置的快乐之中,但对成长无用。其实当初就清楚,spring框架中有大量设计模式,于是也下了代码来看,设计模式其实没那么简单,当初的学习也很皮毛,所以就没有发现spring中的金矿。现在动手,里面依然还是金矿,但不要偷懒,让它完全腐烂。[这是对自己的告诫]

开头上来就说到了spring跟设计模式,实际上,spring中的核心原则就是基于设计模式来构建的。这个时候继续祭出《敏捷软件开发》这本神书,结合里面比较全面的和具体的设计模式来大体讨论一下各种设计模式。(在此也建议将《敏捷》多看几遍,虽然里面用了c++示例,但极易理解)

在学习和讨论每种设计模式之前,都应该明确这样几个问题:

1)这个模式是什么?

2)这个模式适应的场景是什么,有何限制?

3)《敏捷》里面是如何推出来用这个模式的?针对《敏捷》中的场景,如若不考虑这个模式,会如何出手?这种类似于范伟大师傅的神功,为何降服不了“黑帮”?铁定被打趴在地上的原因,有考虑过么?[范伟是俺的偶像]

Command模式

这个模式表面上看是个比较简单的模式,这个是Bob的看法。他强调Command模式具有“功能分解的味道”。实际上在《design patterns》里面command也是被归类在行为类的。一般的command接口定义:

public interface Command {

public void do();

}

从这个接口的角度讲,我们根本不知道它的主要意图是什么,所以在一个类实现这个接口之后,这个类的动作意图,也同样被这个接口给封装起来了。Bob认为从面向对象角度,这是违犯天条的行为。但从上层抽象来说,这又是很好的屏蔽了上层(caller)对具体实现的依赖。所以说,命令模式是一种面向动作的独立抽象,它可以很好地处理输入和动作调用方之间的隔离关系。

考虑到《敏捷》中的两个例子,例1复印机程序,传感器可以在不需要知道当前的事件具体是什么的前提下,直接调用绑定到事件上的command 接口方法。例2验证雇员信息合法性的实现。在增加每个雇员信息到数据库之前都有对其所有信息的合法性进行验证。雇佣方式不同的雇员,其相关信息也是不一样的。如按小时工作的员工需要有相关的时间信息,而按业绩支付的也需要有相应的时间和数量,按月支付的员工则没有额外的信息。但在做增加一个雇员信息的事务时,能隔离掉对具体信息的依赖,可以减少这个事务代码实现的复杂性。《敏捷》在网上有电子书,各位可以对照着看看具体的架构实现。

针对《敏捷》中雇员事务的实现,来说明一种可能比较常见的方法,首先声明,这里说明的方法,从一定意义上讲,是没有考虑面向对象这些设计的,而是我们经常随手拈来写代码凑出来的习惯,写在这里,是想提醒自己,以后碰到这样的场景,应该考虑一下设计模式。看到这个需求,我们的第一印象,应该是给雇员分类:

public enum EmployeeType {

HOUR(1),

MONTH(2),

COMMISSION(3);

private EmployeeType(int type){

this.type = type;

}

private int type;

public int getValue(){

return this.type;

}

}

然后在实现AddEmployeeTransaction时,判断加入的Employee的type. 跟Bob的实现相比,我们少了什么,又多了什么?我的答案肯定不是唯一的,不仅是对这个需求的实现,还有前面这个问题。我来说一下自己的看法:

1.过程性的思维定势,使得AddEmployeeTransaction需要了解全部的可能情况,在种类繁多的情况下,可能会出现一个极其庞大,充满了if-else的大方法;

2.因为第一点,我们肯定创建了一个极其简单POJO 对象,很多人都会直接命名成VO(ValueObject)。

于是,各种所谓的smell就会出现。那么这个时候,我们可能通过重构来抽取出一些小方法,来格式化一个庞大的方法。如此之多的方法是否在说明一个问题,一些行为是否可以形成抽象。因为我们知道if-else比较多的情况下,要考虑command,strategy之类的设计模式,为什么?因为这些模式都是面向行为的,而我们就是在针对行为进行重构。

想到这里,突然对《重构》这本人人喜爱的书有点惋惜,要是它里面能关联上设计模式方面的内容,可能会更具震撼力,因为行动加上理论依据更有说服力,也可以在总是学重构方法方式的时候能思考一下,什么样的重构推出来什么样的模式。

以上是我的个人见解,是做了7,8年的一个对自己编码方式的总结,后面的一些设计模式,也会带上个人色彩的自我剖析。

那么为什么要讲command模式,当然接这个机会都学一遍,但在《设计模式》中关于Command模式的应用部分,其中的一种方式就是采用callback的方式来提供action perform,从而在时间上和引用上都隔离request和调用者。spring里面在阐述IoC的时候,尤其是关于jdbc的封装,它将具体业务相关的动作放到一个callback对象中,而JdbcTemplate可以在毫不关心具体业务动作的状况下,进行调用。

希望这个关联,有助于加深对spring设计的理解。

在part2,再讨论其他几个相关的设计模式,或许多少都会提一下。《设计模式》,《敏捷》,《Expert》这三本书再次捧在手上还是引人入胜,只是现在不会再像以前那么急躁,那么不顾实际场景的使用。由于spring这个框架本身就是个集大成的模板,这是一个极好的机会能切实看到大师级的架构思路,所以后面看情况,如有必要,就一下子把设计模式都过一遍。

Dive into Spring framework -- 了解基本原理(二)--设计模式-part1的更多相关文章

  1. Dive into Spring framework -- 了解基本原理(一)

    在继续我们的分析之前,推荐各位静心来读一下<<Expert_OneOne_J2EE_Design_and_Development>> 第四章, 正如spring BeanFac ...

  2. Dive into Spring framework -- 了解基本原理(二)--设计模式-part2

    Template模式 Template模式顾名思义是提供了一种模板,也就是针对某种业务提供了模范框架.这个在spring中是属于核心模式的,因为其ApplicationContext抽象类就是模板模式 ...

  3. Dive into Spring framework -- 搭建spring 源码的开发环境

    spring是一个类之间依赖的管理容器,大家都知道,但我们中很多人都仅仅停留在使用的层面,但spring本身具有极大的研究价值,所以在使用了几年spring之后,还是想深入的探究一下其根源.记录于此, ...

  4. Spring Boot 启动(二) 配置详解

    Spring Boot 启动(二) 配置详解 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Boot 配置 ...

  5. Spring Framework简介

    作者关于此主题早期文章 Spring框架快速入门 起源 要谈Spring的历史,就要先谈J2EE.J2EE应用程序的广泛实现是在1999年和2000年开始的,它的出现带来了诸如事务管理之类的核心中间层 ...

  6. 设计模式学习(二十四):Spring 中使用到的设计模式

    设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...

  7. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)

    接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...

  8. 框架应用:Spring framework (一) - IoC技术

    IoC概念以及目标 IoC就是让原本你自己管理的对象交由容器来进行管理,其主要的目的是松耦合. IoC发展史 既然IoC的目标是为了松耦合,那它怎么做到的? 最后目标:降低对象之间的耦合度,IoC技术 ...

  9. Spring Framework(框架)整体架构 变迁

    Spring Framework(框架)整体架构 2018年04月24日 11:16:41 阅读数:1444 标签: Spring框架架构 更多 个人分类: Spring框架   版权声明:本文为博主 ...

随机推荐

  1. MobileNet

    MobileNet (Efficient Convolutional Neural Networks for Mobile Vision Applications)--Google CVPR-2017 ...

  2. 饭卡---hdu2546(01背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546 这是一个变形的01背包问题,首先如果金额小于5元,剩余金额不变,为已有金额.如果大于等于5元 我 ...

  3. Jacl 是 TCL 的一个备用实现

    Jacl 是 TCL 的一个备用实现,它是完全使用 Java 代码编写的. wsadmin 工具使用 Jacl V1.3.2. 建议不要在 wsadmin 工具中使用 Jacl 语法 建议不要使用一个 ...

  4. Elasticsearch.js 发布 —— 在Node.js和浏览器中调用Elasticsearch(1)

    继PHP.Ruby.Python和Perl之后,Elasticsearch最近发布了Elasticsearch.js,Elasticsearch的JavaScript客户端库.可以在Node.js和浏 ...

  5. UILocalNotification 的使用

    @IBAction func sendNotification(sender: AnyObject) { var userInfo = Dictionary<String,String>( ...

  6. cookie和session的自我介绍

    Cookie是什么? cookie说的直白点就是保存在用户浏览器端的一个键值对,举个例子,你现在登录了京东商城,你把浏览器关闭之后,你再打开京东,你还是可以对你的账户继续操作,已经购买的商品,订单都是 ...

  7. python学习笔记(九)函数返回多个值,列表生成式,循环多个变量,入参格式声明

    一.函数返回多个值 1.函数如果返回多个值的话,它会把这几个值放到一个元组里面2.函数如果返回多个值的话,也可以用多个变量来接收 def say(): num1 = num2 = num3 = ret ...

  8. Java io流详解四

    转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...

  9. 更新表中数据可以使用join

    1.在修改数据库的时候,每写完一条SQL语句都要加上一个分号,这样每句之间是有依赖关系的,上面执行不成功不会执行下面的语句. 2.在更新数据库中数据时可以使用join. 例如: update res ...

  10. IOS开发如何入门

    说到 iOS 开发,自己学得也很浅.不过至少独立一人完成了一个应用的开发到项目上线整个过程.分享一下自己的建议和想法. 首先建议阅读 Start Developing iOS Apps Today,你 ...