(一)整体过程
1) 原代码重构成逻辑块清晰的过程化代码
2) 对不同逻辑块进行抽取成服务类
3) 从领域对象的角度分析服务类,通过单一职责来梳理服务类
(二)原代码重构成逻辑块清晰的过程化代码
每个逻辑块要有明确的输入输出,不同逻辑块最好能做到无序,如果一定有有序,要对有序有地方有所注释。每下个逻辑块都很分明,想抽成方法就可以随时抽取,不想抽取也可以保持现状,当重复代码出现时要进行抽取。如下是个合格的过程化代码示例。
返回值 方法1(参数1,参数2){
返回值变量1; //声明方法返回值
//逻辑块A
跨块变量AB1;//被多个逻辑块使用
块变量声明A1;
块变量声明A1=块代码A0(参数1);
跨块变量AB1=块代码A1( 块变量声明A1 ,参数2);
局部结果1=XXXX;
返回值变量1 =XXXXX( 局部结果1 );
//逻辑块BCD....
//方法返回值
}
逻辑块的输入和输出:
输入:方法返回值,方法参数,跨块变量,类变量
输出:逻辑块变量,方法返回值,方法参数(很少),跨块变量,类变量
逻辑块变量:只在一个逻辑块中新建和使用的变量,在逻辑块抽取成新方法时,随逻辑块迁徙走就好,属于逻辑块的内在逻辑。不是逻辑块的输入,但可以是逻辑块的输出。
方法返回值:在方法的第一句中进行声明,在最后一句返回。不同逻辑块和返回值可以有两种形式联系,1.返回值即不是逻辑块的输入也不是逻辑声的输出最好,逻辑块有自己的输入和输出。逻辑块的输出再去反映到方法返回值上(比如,如果是计数,每个逻辑块返回自己的计数,再累加到返回值上)。2.有时为了简便,方法返回值直接传入不同的逻辑块中,逻辑块直接对返回值对象进行改变,这样会形成返回值同时是不同逻辑块的输入和输出参数,抽取逻辑块时会使用方法参数来做为返回值。
方法参数:一般做为整个方法的输入,耦合程度仅限于方法,耦合小。线程未必安全。在方法需要不只一个返回值时,也会用于输出。也可能会同时是输入和输出。但逻辑块很少以方法参数做为输出。
跨块变量:可以在多个逻辑块内使用的变量。可以做为逻辑块的输入和输出。一般做为上一个逻辑块的输出和下一个逻辑块的输入,是不同逻辑块的桥梁。跨块变量的引入会形成不同逻辑块的顺序依赖,跨块变量能取消就取消。
类变量:可以做为不同逻辑块的输入和输出,可以承担上述任何变量的责任。
(三)对不同逻辑块进行抽取成服务类:
输入成为方法参数,如果输入比较多,可以把输入对象化(即用一个类结构来包含多个输入)。
输出成为方法返回值或者输出参数。如果输出比较多,可以把输出对象化。
根据逻辑块的业务复杂度来决定是把逻辑块抽取的方法是放入已经的类,还是新建立的类中。心中知道了程序有多个逻辑要处理,才能去思考有多少逻辑实体。本质上还是要分析程序做了几件事。
class 返回值A{
跨块变量AB1;//被多个逻辑块使用
局部结果1=XXXX;
}
AImpl{ //省去了接口
返回值A 方法(参数1,参数2){
//逻辑块A
返回值A;
块变量声明A1;
块变量声明A1=块代码A0(参数1);
返回值A.跨块变量AB1=块代码A1( 块变量声明A1 ,参数2);
返回值A. 局部结果1=XXXX;
return 返回值A;
}
}
原方法演变成
AImpl aservice;
返回值 方法1(参数1,参数2){
返回值变量1; //声明方法返回值
//逻辑块A
返回值A =aservice.方法(参数1,参数2);
返回值变量1 =XXXXX(返回值A .局部结果1);
//逻辑块BCD....
返回值变量1. 跨块变量AB1可以被引用
//方法返回值
}
(四)从领域对象的角度分析服务类,通过单一职责来梳理服务类
软件的构成
首先对软件的认识上,软件是要解决问题的,要建立软件是做了很重要事情的认识,这个很重要的事情才是软件的核心,而不是这中间涉及的技术。
构建一个软件时,想好了软件是解决了哪个重大的问题,解决这个重大问题时,需要一些第三方的协助,需要把结果反馈给别人。故软件从结构上有三部分组成,1.解决问题的逻辑。2.需要协助的第三方。3.需要使用问题答案的第三方。第2和第3都是通过技术手段取得一些东西。重点就在于要解决问题的逻辑这一部分。
重视业务-从业务角度松耦合
解决问题的逻辑部分的设计,就成了软件的核心设计,这个设计其实就是一个执行方案,所谓设计的好坏更多的是对我们人来说,当问题变化时,怎么样能更容易的让原有的设计支持到新的需求。如果能把原问题分割成比较小的逻辑块,不同逻辑块之间松耦合,就能在变化时只变动其中的某些逻辑块。
领域对象梳理-抽象
有了松耦合的逻辑块,大体意思是对了,也可以按这个进行编程了。
要想做到更好的维护,就需要把这些逻辑块梳理成职责分明的协作工人,每个逻辑块都有着明确而单一的职责,每个人做好自己的事,并信任的使用其它人提供的服务。这时就需要对逻辑块按单一职责进行命名,并分析他们间的关系。每个工人都有一个职责列表,也就是接口。