我们内部每周都有读书会,最近在读《clean code》,基本上是20分钟左右。总体原则是大家轮流来讲。 我自己也领了其中一章,第八章。这一张特别不巧,书少了3页。整个一章少了一半的内容。于是我自己发挥了一下,希望大家能有所收获。

 

从接口到类、工程、系统、框架。在做设计的时候关于边界的基本思路是一致的。就是需要在普适性和集中性中做一个权衡。权衡的结果直接就影响着边界。

边界的目的是要保证:易于理解,难以被误用。

 

边界划分的典型例子:spring

spring框架是一个分层架构,由7个定义良好的模块组成。每个模块都可以单独存在,或者与其他一个或多个模块联合实现。

  • 核心容器:核心容器提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory使用控制反转(IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring上下文:Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,例如JNDI、EJB、国际化、校验和调度功能。
  • Spring AOP:通过配置管理特性,Spring AOP模块直接将面向方面的编程功能集成到了Spring框架中。所以,可以很容易的使Spring框架管理的任何对象支持AOP。Spring AOP模块为基于Spring的应用程序中的对象提供了事务管理服务。通过使用Spring AOP,不用依赖EJB组件,就可以将声明性事务管理集成到应用程序中。
  • Spring DAO:JDBC DAO抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大的降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO的面向JDBC的异常遵从通用的DAO异常层次结构。
  • Spring ORM:Spring框架插入了若干个ORM框架,从而提供了ORM的对象关系工具,其中包括JDO、Hibernate和iBatis SQL Map。所有这些都遵从Spring的通用事务和DAO异常层次结构。
  • Spring Web模块:Web上下文模块简历在应用程序上下文模块之上,为基于Web的应用程序提供了上下文。所以,Spring框架支持与Jakarta Struts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  • Spring MVC框架:MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架便成为高度可配置的,MVC容纳了大量视图技术,其中包括JSP、Velocity、Tiles、iText和POI。

明确的职责是整洁边界的基础。拿Spring的核心容器举例。从上面图中可以看出,核心模块是spring框架中最底层核心的模块,提供了最基本的IoC思想和一些核心工具。想明确边界先要明确概念和职责。

IoC

IoC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。是1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中首先提出来的。简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度。

IoC的别名:依赖注入(DI)

2004年,Martin Fowler讨论了既然IoC是控制反转,那么到底是哪些方面的控制被反转了呢?经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IoC容器主动注入。于是他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现Ioc的方法:注入。所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。所以,依赖注入和控制反转是从不同的角度来描述同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦。

 

到现在spring core的核心边界已经可以确立了。那么再进一步从实现上来剖析边界。

IoC中最基本的技术就是反射。通俗来讲就是根据给出的类名来动态的声称对象。这种方式可以让对象在生成时才决定到底是哪一种对象。

IoC容器的工作模式可以看做升级版的工厂模式。然后利用编程语言 的反射编程,根据配置文件中给出的类名生成相应的对象。从实现来看,IoC是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立开,目的就是提高灵活性和可维护性。

 

好,现在技术实现的主要思想也清晰了。这样在代码分层上会有一个大体的思路,超出边界的设计不会太多了。下面就来具体看看代码。

spring core的工程下面,分为6个package,分别是asm,cglib,core,lang,objenesis和util。

ASM是一个全功能Java字节码操作与分析框架。可以用来修改已有的class文件或者直接以二进制形式动态生成class。它提供了通用转换与分析算法,自己组合复杂转换与代码分析工具。

CGLIB是一个强大的、高性能的代码生成库。主要通过对字节码的操作,为对象引入简介级别,以控制对象的访问。

objenesis本身也是一个强大的java库,主要是用在创建对象上面。它可以不用调用构造函数就创建对象。专门用于实例化一些特殊java对象,如私有构造方法,带参数的构造等不能通过class.newInstance()实例化的。

前三个都是反射的实现方式。

lang大家都很熟悉了,是language的缩写,定义了使用的语言,这里具体指JVM。

core包里具体实现了IoC。

util包提供了核心工具,基本上就是对象的生成工具,因为IoC的核心作用就是生成对象。

 

代码大体框架的边界也定义出来了。下一步看接口。时间关系看最简单的lang包的。

四个注解接口

 


public @interface UsesSunHttpServer {
}


public @interface UsesJava7 {
}

public @interface UsesJava8 {
}

 

public @interface UsesSunMisc {
}

从接口定义就可以看到这是非常符合这个包的职责的。

 

再往下具体实现类我就不讲了,主要给大家提供一种思路,整洁的边界是怎样定义出来的。先要从大局上想清楚,然后是一个整体的设计,虽然应用程序的代码天然封装好了设计模式,但是这种理念需要有,这会非常利于写出整洁的代码。代码层次天然表达了设计思路,有人说代码即注释,我看来代码即设计。好的代码会像好的设计文档一样让人读着舒服。

另外,我选用spring框架代码来说明代码整洁之道,主旨在于我个人觉得要写好代码,持续的去了解自己使用的框架、底层源码是一个应该形成的习惯与基本功。因为只有去不断的反思这些东西做了什么才能更好的用好它。我自己亲身感受的学习思路是先学其所长,然后再自成一派。而写好代码又和写好文章非常类似。我最喜欢举得学好之后自成一派的例子就是古龙,总在开场让人惊艳一把。

很多他的开场白让人过目不忘。比如我现在还记得《天涯明月刀》的开场白:

“天涯远不远?”

“不远!”

“人就在天涯,天涯怎么会远?”

“明月是什么颜色?”

“是蓝的,就像海一样蓝,一样深,一样忧郁。”

“明月在哪儿?”

“就在他的心,他的心就是明月。”

“刀呢?”

“刀就在他手!”

“那是一柄什么样的刀?”

“他的刀如天涯般辽阔寂寞,如明月般皎洁忧郁,有时一刀挥出,又仿佛是空的!”

“空的?”

“空空蒙蒙,缥缈虚幻,仿佛根本不存在,又仿佛到处都在。”

“可是他的刀看来并不快。”

“不快的刀,怎么能无敌于天下?”

“因为他的刀已超越了速度的极限!”

“他的人呢?”

“人犹未归,人已断肠。”

“何处是归程?”

“归程就在他眼前。”

“他看不见?”

“他没有去看。”

“所以他找不到?”

“现在虽然找不到,迟早总有一天会找到的!”

“一定会找到?”

“一定!”

 

好,就用古龙的风格总结一下我记住的前八章的《clean code》的内容:首先,要有意义的命名 。其次,格式很重要。然后,代码也有思想流派。最后,整洁代码是艺术。

 

总结与思考:

      我来现在的公司是因为意识到自己格局的问题。之前我看的视野太窄,所以我有强烈的需求想看到更全局性的东西。结果,我却忽视了一个更加显而易见的东西:角度。我所站的角度才更反映我的格局。

      长久以来,我总是觉得我代表我个人。我最得意的事情从来不是工作上的成就,而是我是一个好妻子,好妈妈,好女儿,好儿媳。我不在乎别人怎么看我,因为我相信我自己,知道一切都会好起来。但是在工作中,我代表更多的是一个集体。代表集体不是简单的从用词的我变成我们。而是我每一个决策给集体带来什么样的影响。我遇到事情,我应该找集体来商讨,而不是觉得自己可以就可以做出决定。

 

跑题时间:

无题1

  千辛万苦,

      千思万绪,

  淡然一笑,

  默默无语。

  感激并怀恨着,

  让我变得如此强大的那个人

无题2

  如果注定是擦身而过,不要回头;

  哪怕比痛更痛,以后的路都了无生趣,心如死灰;

  不回头至少记忆里是笑容;

  回头他会看到一双含泪的眼睛

 

posted on 2018-03-16 00:49  编程一生  阅读(1551)  评论(5编辑  收藏  举报