Replace Parameter with Explicit Methods (以明确函数取代参数

Summary 你有一个函数,其中完全取决于参数值而采取不同行为。针对该参数的每一个可能值,建立一个独立函数。

        100735_SIAv_134516.png                                       

动机:

 Replace Parameter with Explicit Methods 恰恰相反于Parameterize Method。如果某个参数有很多种可能的值,而函数内又以条件表达式检查这些参数值,并根据不同参数值做出不同的行为,那么就应该使用本项重构。调用者原本必须赋予参数适当的值,以决定该函数做出何种响应。现在既然你提供了不同的函数给调用者私用,就可以避免出现条件表达式。此外你还可以获得编译期检查的好处,而且接口也更清楚。如果以参数值决定函数行为,那么函数用户不但需要观察该函数,而且还要判断参数值是否合法,而“合法的参数值”往往很少在文档中被清楚地提出。

就算不考虑编译器检查的好处,只是为了 获得一个清晰的接口,也值得你执行本项重构。哪怕只是给一个内部的布尔变量赋值,相较之下,Witch.beOn()也比Switch.setState(true)要清晰得多。

但是,如果参数值不会对函数行为有太多影响,你就不应该使用Replace Parameter with Explicit Methods。如果情况真这样,而你也只需要通过参数为一个字段赋值,那么直接使用设值函数就行了。如果的确需要条件判断的行为,可考虑使用Replace Conditional with Polymorphism

做法:

1. 针对参数的每一种可能值,新建一个明确函数。

2.修改条件表达式的每个分支,使其条用合适的新函数。

3.修改每个分之后,编译并测试。

4.修改原函数的每一个被调用点,改而调用上述的某个合适的新函数。

5.编译,测试。

6.所有调用端都修改完毕后,删除原函数。


范例:

下列代码中,我们根据不同的参数值,建立Employee之下不同的子类。以下代码往往是Replace Constructor with Factory Method的施行成果:

static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;

static Employee create(int type){
    switch(type){
        case ENGINEER:
            return new Engineer();
        case SALESMAN:
            return new Salesman();
        case MANAGER:
            return new Manager();  
        defaule:
             throw new IllegalArgumentException("Incorrect type code value");   
    }
}

由于这是一个工厂函数,我们不能实施Replace Conditional with Polymorphism,因为使用该函数时对象根本还没创建出来。由于可以预见到Employee不会有太多新的子类,所以我们可以放心地为每个子类建立一个工厂函数,而不必担心工厂函数的数量会剧增。首先,根据参数值建立相应的新函数:

static Employee createEngineer(){
    return new Engineer();
}

static Employee createSalesman(){
    return new Salesman();
}

static Employee createManager(){
    return new Manager();
}

然后把switch语句的各个分支替换为对新函数的调用,每修改一个分支,都需要编译并测试,直到所有分支修改完毕为止:

static Employee create(int type){
    switch(type){
        case ENGINEER:
            return Employee.createEngineer();
        case SALESMAN:
            return Employee.createSalesman();
        case MANAGER:
            return Employee.createManager();  
        defaule:
             throw new IllegalArgumentException("Incorrect type code value");   
    }
}

接下来,我们把注意力转移到旧函数的调用端。我们把诸如下面这样的代码:

Employee kent = Employee.create(ENGINEER);

替换为:

Employee kent = Employee.createEngineer();

修改完create()函数的所有调用者之后,就可以把create()函数删掉了。同时也可以把所有常量都删掉。

  

转载于:https://my.oschina.net/u/134516/blog/219888

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值