《重构 改善既有代码的设计 3》代码的可理解性应该是我们虔诚追求的目标

2、合并条件表达式

如果你有一系列条件测试,都得到相同的结果,你就可以将这些测试合并为一个条件表达式,并将这个条件表达式提炼出成为一个独立函数。

3、合并重复的条件片段

在条件表达式的每个分支上有着相同的一段代码,将这段重复代码转移到条件表达式之外。

4、移除控制标记

以break语句或return语句取代控制标记。

5、使用卫语句取代嵌套条件表达式

使用卫语句表现所有特殊情况。

如果某个条件极为罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回,这样的单独检查常常被称为“卫语句”。

6、以多态取代条件表达式

你手上有个条件表达式,它根据对象类型的不同而选择不同的行为,将这个条件表达式的每个分支放进一个子类中的覆写函数中,然后将原始函数声明为抽象函数。

正因为有了多态,所以你会发现:“类型码的switch语句”以及“基于类型名称的ifelse语句”在面向对象程序中很少出现。

7、引入null对象

将null值替换为null对象。

8、

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

开源分享完整内容戳这里

引入断言

以断言明确表现某种假设。

第十章 简化函数调用


1、函数改名

最简单也是最重要的一件事情就是修改函数名称,名称是程序员与阅读者交流的关键工具。只要你能理解一段程序的功能,就应该大胆地使用Rename Method将你所知道的东西传达给其它人。

2、添加参数

某个函数需要从调用端得到更多信息,为此函数添加一个对象参数,让该对象带进函数所需信息。

3、移除参数

4、将查询函数和修改函数分离

某个函数既返回对象状态值,又修改对象状态。

建立两个不同的函数,其中一个负责查询,另一个负责修改。

5、令函数携带参数

若干函数做了类似的工作,但在函数本体中却包含了不同的值。

建立单一函数,以参数表达哪些不同的值。

6、以明确函数取代参数

你有一个函数,其中完全取决于参数值而采取不同行为。

针对该参数的每一个可能值,建立一个独立函数。

7、保持对象完整

你从某个对象中取出若干值,将它们作为某一次函数调用时的参数。

改为传递整个对象。

「动机」

有时候,你会将来自同一对象的若干项数据作为参数,传递给某个函数。这样做的问题在于:万一将来将被调用函数需要新的数据项,你就必须查找并修改对此函数的所有调用。如果你把这些数据所属的整个对象传给函数,可以避免这种尴尬的处境,因为被调用函数可以向那个参数对象请求任何它想要的信息。

除了可以使参数列表更加稳定之外,还能提高代码的可读性。过长的参数列表很难使用,因为调用者和被调用者都必须记住这些参数的用途。

8、以函数取代参数

让参数接受者去除该项参数,并直接调用前一个函数。

「动机」

如果函数可以通过其他途径获取参数值,那么它就不应该通过参数取得该值。过长的参数列表会增加阅读者的理解难度,因此我们应该尽可能缩短参数列的长度。

9、引入参数对象

某些参数总是很自然的同时出现,以一个对象取代这些参数。

10、移除设值函数

类中的某个字段应该在对象创建时就被设值,然后就不再改变。

去掉该字段的所有设值函数。

11、隐藏函数

有一个函数,从来没有被其他任何类用到。

将这个函数修改为private。

12、以工厂函数取代构造函数

你希望在创建对象时不仅仅是做简单的建构动作。

将构造函数替换为工厂函数。

Employee(int type){

_type = type;

}

static Employee create(int type){

return new Employee(type);

}

13、封装向下转型

某个函数返回的对象,需要由函数调用者向下转型,将向下转型的操作转移到函数中。

Object lastReading(){

return readings.lastElement();

}

Reading lastReading(){

return (Reading)readings.lastElement();

}

14、以异常取代错误码

某个函数返回一个特定的代码,用以表示某种错误情况,改用异常。

代码的可理解性应该是我们虔诚追求的目标。

非受控异常

class Account{

void withdraw(){

Assert.isTrue(“sufficient funds”,amount <= _balance);

_balance-= amount;

}

}

class Assert{

static void isTrue(String comment, boolean test){

if(!test){

throw new RuntimeException(“Assertion failed:”+comment);

}

}

}

15、以测试取代异常

面对一个调用者可以预先检查的条件,你抛出一个异常。

修改调用者,使它在调用函数之前先做检查。

「动机」

异常只应该被用于异常的、罕见的行为,也就是哪些产生意料之外的错误的行为,而不应该成为条件检查的替代品。如果你可以合理期望调用者在调用函数之前先先插某个条件,那么就应该提供一个测试,而调用者应该使用它。

第十一章 处理继承关系


1、字段上移

两个子类拥有相同的字段,将该字段移至超类。

2、函数上移

有些函数,在各个子类中产生完全相同的结果,将该函数移至超类。

3、构造函数本体上移

你在各个子类中拥有一些构造函数,它们的本体几乎完全一致。

在超类中新建一个构造函数,并在子类构造函数中调用它。

class Manager extends Employee{

public Manager(String name, String id, int grade){

_name = name;

_id = id;

_grade = grade;

}

}

//改变为

class Manager extends Employee{

public Manager(String name, String id, int grade){

super(name, id);

_grade = grade;

}

}

4、函数下移

超类中的某个函数只与部分子类有关,将这个函数移到相关的那些子类中去。

5、字段下移

超类中的某个字段只被部分子类用到,将这个字段移到需要它的那些子类中去。

6、提炼子类

类中的某些特性只被某些实例用到。

新建一个子类,将上面所说的那一部分特性移到子类中。

7、提炼超类

两个类有相似的特性,为这两个类建立一个超类,将相同特性移至超类。

「动机」

重复代码时系统中最糟糕的东西之一。如果你在不同地方做同一件事情,一旦需要修改那些动作,你就得平白做更多的修改。

重复代码的某种形式就是:两个类以相同的方式做类似的事情,或者以不同的方式做类似的事情。对象提供了一种简化这种情况的机制,那就是继承。但是,在建立这些具有共通性的类之前,你往往无法发现这样的共通性,因此经常会在具有共通性的类出现之后,再开始建立其间的继承关系。

另一种选择就是提炼类,这两种方法之间的选择其实就是继承和委托之间的选择。如果两个类可以共享行为,也可以共享接口。

8、提炼接口

若干个客户使用类接口中的同一子集,或者两个类的接口有部分相同。

将相同的子集提炼到一个独立接口中。

9、折叠继承体系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值