网站 内容优化,建设单位经常去哪个网站,网站建设(中企动力),商业网站网页重构小记#xff08;重构#xff0c;改善既有代码的设计读后总结#xff09; 方法级别
提炼函数#xff1a;
将一个大方法#xff0c;拆成多个小方法#xff0c;难点在于小方法的命名。 假如有早上上学的一个大方法#xff0c; 那么就应该在里面有起床#xff0c;穿衣…重构小记重构改善既有代码的设计读后总结 方法级别
提炼函数
将一个大方法拆成多个小方法难点在于小方法的命名。 假如有早上上学的一个大方法 那么就应该在里面有起床穿衣服吃早点等小方法 而起床这个方法又可以分为穿衣服穿鞋叠被子等方法 而穿衣服又有穿内衣穿外衣等步骤。
内联函数
一个太小的方法里面只做了一个动作就可以考虑去掉了去掉会使代码更清晰。 感觉内联函数说的就是不要过度的提炼函数。
内联临时变量
就是说要尽量去掉只用一次的临时变量 注意如何判断临时变量只被赋值了一次就是在前面加flnal能编译过就是只有一次 比如有代码int age user.getAge();return age18; 那么这两句代码就完全可以合成一句return user.getAge()18;
以查询取代临时变量
如果临时变量被用了多次的话也尽量用方法去代替临时变量。 比如有代码 int sum a b; if(sum10){ return sum2; } else{ return sum3 } 这里的sum变量就要用方法封装后去掉。变成以下 int getSum(){ return a b; } if(getSum()10){ return getSum()*2; } else{ return getSum()*3 } 这种不一定就是最正确的甚至有时候会反过来改所以把握整体很关键。 这样可能会对性能产生一点影响但几乎也可以忽略不计。
引入解释型变量
用变量名来简化复杂表达式 比如有代码if(a 0 aa 0 aaa 0 b 0 bb 0 bbb 0){return true;} 这个if中的判断表达式就太复杂可改成下面这样 boolean aClassMoreThanZero a 0 aa 0 aaa 0;//a类变量大于0 boolean bClassLessThanZero b 0 bb 0 bbb 0;//b类变量小于0 if(aClassMoreThanZero bClassLessThanZero){return true;}
分解临时变量
临时变量被赋值多次并且是不同的意思就要将临时变量分解成多个变量保证一个临时变量只代表一个意思。
移除对参数的赋值
一个方法中尽量不要对入参进行赋值可以尝试将入参用final修饰
以函数对象取代函数
如果方法中局部变量太多就创建一个函数对象把所有的局部变量变成这个对象的属性然后把这个方法的实现全部移到对象中 说实话我个人觉得这种方式没什么用因为如果你有时间这样搞还不如换个思路梳理下这个方法不过也可能是我没遇到这样情况。
替换算法
替换一个方法的实现重点在于替换前后要保证执行结果一致。 比如有个方法是冒泡算法实现排序那么就可以用插入排序来替代冒泡排序。 对象级别
搬移函数
一个类中有个函数却与另一个类进行更多的交流那么就尝试将这个函数整体迁移过去。
搬移字段
一个类中有某个字段被另一个类更多的用到那么就尝试将这个字段移到另一个类中。
提炼类
如果一个类越来越大就可以考虑将其中的一部分与类名关系不大的属性抽出来做成这个类的子类。
将类内联化
与提炼类相反如果一个类没有做太多事情就可以尝试将他与另一个类合并。
隐藏委托关系
隐藏真实的调用关系将真实的调用关系封装在最外层的方法中。 比如有个A类A中有个B类属性B中又有个C类。 如果想通过A获得C的值普通的做法就是a.getB().getC();但是这样就把真实的C暴露出来了其实调用方也根本没必要知道这个这时候就可以这样做 在A类中添加一个方法叫getC(),方法的实现就是return b.getC();这样就相关与把B给隐藏了 这时如果再想通过A获得C,那么就可以直接a.getC();这就是隐藏委托关系。
移除中间人
这个是隐藏委托关系的反向重构也就是说当委托的太多的时候就应该考虑是不是应该直接点物极必反。 相当于把上个例子的a.getC()又改成a.getB().getC()
引入外加函数
对于有些引入的源码类如果你想增强它肯定不能直接修改源码那么就需要引入外加函数。 感觉这个就是对源码的增强通过新建一个函数返回增强后的内容以后使用的时候就直接用这个函数就好了。
引入本地扩展
这个是引入外加函数的增强版 如果需要对源码进行很多增强那么就可以这样做 方案一新建一个类子类继承源码类新增强的功能就可以放在子类中 方案二新建一个类包装类将源码类当成这个新类的属性那么也可以完成和方案一一样的效果 重新组织数据
自封装字段
属性私有化通过get/set方法取值/设置值而不是直接对值进行操作
以对象取代数据值
属性使用对象这是一个过程比如刚开始是String后面慢慢的感觉还要一些字段而这些字段又是一类数据那么就将这一类数据抽成一个类来代替原来分散的数据。
将值对象改为引用对象
将一个类衍生出的彼此相同的许多实例使用工厂替换成同一个实例并将原类的构造方法私有化禁止直接构造。 比如员工是个类类中有个属性是老板这个类那么多个员工的老板其实就是同一个这时候就要用这种方式先将老板类的构造方法私有化。 然后可以先在静态块中将老板类创建好然后每new一个新员工的时候老板类的赋值就用这个创建好的老板实例就行。
将引用对象改为值对象
如果引用对象太小且不可变难以管理就可以考虑将上面的方式反过来了
以对象取代数组
如果数组中有多个不同的类型复杂到不能让人很快的明白哪个是什么意思就该用对象来代替了 比如数组[“小明”,20,175,70];不是很容易就看出来这个数组中每个的意思这时就要用对象代替那么属性就分别是名字年龄身高体重。
以字面常量取代魔法值
任何一个数字都不应该凭空出现需要在类前将它设置成常量然后再去引用这样才能使代码变的清晰易懂。
以类取代类型码
1、2、3、4等类型码不能很清楚的表达意思这时候就应该用类来代替这些类型码。 Lei.A.getCode(),代替原来的1 Lei.B.getCode(),代替原来的2…
以子类取代类型码
类中多个类型码可以使用子类每个子类对应一个类型码。 使用的时候根据不同的条件原来是返回不同的类型码现在改为返回不同的子类。
以state/Strategy取代类型码
如果类由于其他原因不能被继承那么就需要新建一个状态类然后不同的子类去继承这个状态类还是一个状态对应一个子类。 然后这个状态类中建立一个查询方法返回状态码各个子类重写这个方法返回具体的状态码。
以字段代替子类
如果子类差别不大甚至只是在返回常量数据不一样那么就要考虑删掉子类了原子类的功能完全可以通过不同的方法来代替。 简化条件表达式
分解条件表达式
表达式太多就会分不清每个的意思这时候就应该把表达式按照意思区分成小块每个小块通过命名来区分具体的意思。
合并条件表达式
如果多个表达式返回同一个结果就要考虑合并成一个表达式。
合并重复的条件片段
如果每个表达式的分支上都有着相同的代码块那么这就是重复代码我们就应该把这块代码提炼出来。
移除控制标记
就是类似于if(怎么样)就停止 这样类似的控制标记可以用break,continue,return等替代多用在循环体中。
以卫语句取代嵌套的条件表达式
尽量避免嵌套的条件表达式 比如if(){}else{if(){}else{if(){}}} 尽量改成if(){};if(){};if(){};…
以多态取代条件表达式
将条件表达式的每个分支放在每个子类重写的方法中原始方法变抽象 多态就是根据对象的不同类型采取不同的行为。
引入断言
断言是一个条件表达式应该总是为真如果失败则说明程序员犯了错误。 Assert类有很多方法常用的是Assert.isTrue(XXX); 断言不会改变程序任何行为但能帮助程序员理解代码正确运行的必要条件。 简化函数的调用
函数改名
函数的名字至关重要代码首先是为人写的其次才是为机器写的
添加参数
添加参数要谨慎实在没办法的情况下才会考虑添加参数。
去除参数
如果某个参数确实没用了记得赶紧去掉不要抱着不去也不会出问题的心态否则这样只会让程序越来越复杂。 去除参数的时候还要注意多态的影响。
将查询函数和修改函数分离
一个函数只完成一个职责要么查询要么修改。
另函数携带参数
统一合并类似功能的函数 如果多个函数只是部分值不一样做的确实一类事情那么就要考虑合并成一个函数并把不同的值当成参数传进来。
以明确函数去掉参数
与上面的相反如果一个函数中根据入参不同执行的逻辑已经完全不同了那么就将他们分开成各自的函数。
保持对象完整性
如果入参是某个对象的多个属性时考虑用这个对象整体作为入参来代替多个参数。
以函数取代参数
如果函数的参数可以通过函数内部通过其他方法得到就不要使用参数来传递。 尽量的简化函数的参数因为太多的参数会让函数变的复杂。
引入参数对象
如果一些参数总是很自然的同时出现那么就要考虑是不是用一个对象来代替这些参数了
移除设值函数
如果一个字段在函数过程中需要被修改就为它提供一个修改的函数 如果这个字段在函数过程中不会被修改就删掉修改它的函数同时用final修饰。
隐藏函数
一个函数从没有被其他类用到就用private修饰它
以工厂函数取代构造函数
如果创建对象时需要根据不同的条件创建不同的对象可以考虑写个工厂方法来代替构造方法
封装向下转型
函数的返回值不要设置成Object等原始类型最好指定类型免得调用方又要强制转型。
以异常取代错误码
就是自定义异常并合理的利用它
以测试取代异常
就是方法一开始要对入参进行校验看是否是后面程序可以接受的参数 比如如果为空要怎么样如果为0要怎么样这些能想到的要提前抓到并做合理的处理。最常见的就是判空。 处理概括关系继承关系
字段上移
子类有相同作用的字段应该上移到他们的父类中。
字段下移
与上面相反如果父类的某些字段只与部分某些子类有关那么就应该将这些字段下移到对应的子类中。
函数上移
子类中有相同作用的函数应该将这个函数上移到他们的父类中。
函数下移
与上面相反如果父类的某些函数只与部分某些子类有关那么就应该将这些函数下移到对应的子类中。 ####构造函数本体上移 各个子类中的一些构造函数如果他们的本体几乎完全一致那么就在父类中建一个构造函数然后在子类中调父类类似于super(idname)
提炼子类
如果类中的某些属性只被某些实例用到那么就新建个子类将这些属性移到子类中。 这样保证不用这些属性的实例用父类new用到这些属性的实例用子类new。
提炼超类
如果两个类有相似的特性就新建一个他们的父类将相同特性移到父类上去避免代码的重复。
提炼接口
若干类中有相同的子集可以考虑新建接口让这些类继承然后统一相同的部分调用也改成接口调用
折叠继承体系
如果子类和父类没有太大区别就将他们合为一体
塑造模板函数
详见设计模式的模板模式就是在抽象父类中定义好抽象函数再写个方法A写明各个抽象函数的调用顺序。 那么子类中只需要重写父类的抽象方法用的时候子类调用方法A就能按照父类方法A中的调用顺序来调用各自的实现了。
以委托取代继承
如果父类中的很多属性和方法子类都用不到那么就可以放弃继承在子类中引入一个原父类的属性引用即可。
以继承取代委托
与上面的相反如果两个类之间的委托调用的太多甚至几乎是全部了那么就该考虑让委托的这个类作为父类了之间继承会更好。 大型重构
梳理并分解继承体系
某个继承体系同时承担两项责任或多项责任时考虑拆开。 比如原来有父类AA有两个子类B和CB还有个子类DC还有个子类E。B和C都承担同类责任而D和E却承担另外一个不同的责任。 此时就应该把BC和DE分开了。我们建立两个继承体系A和FA拥有子类BCF拥有子类DE通过委托关系A作为F的属性让其中一个F调用另外一个A。
将过程化设计转为对象设计
其实就是尽量的面向对象将面向过程变成转成面向对象编程。
将领域和表述/显示分离
与界面展示相关的逻辑的类和纯业务逻辑的类要分离。
提炼继承体系
一个类在演变过程中所承担的责任越来越多时就应该考虑分离它了可以采取抽出一部分当成子类使整体变成继承的体系。