代码重构——简化条件表达式

之前verilog写多了,老是想着if else要完整,否则会产生锁存器。发现现在写代码潜意识里也有这种想法,好逗。。。最近正好看到公司大牛重构代码,优化for循环和if语句,还看到《阿里巴巴Java开发手册》里控制语句里的部分内容,搜了一下发现了《重构 改善既有代码的设计》这本书,发现挺有意思。

卫语句

《阿里巴巴Java开发手册》讲到了卫语句。

《重构 改善既有代码的设计》也讲到了这一点。

Replace Nested Conditional with Guard Clauses 

以卫语句取代嵌套条件表达式

对于特殊的不常见的行为或者异常行为,如果将其写入if else的语句中,逻辑就会显得特别复杂。将判断这些情况的条件单独列出来进行检查,如果为真就返回或者抛出异常。这样的单独检查被称为“卫语句”。

这样的代码强调出来某些异常情况,并且和正常的情况进行了分离,更易于理解。如果上面的语句不使用卫语句,就要写成下面的形式,显得不够清晰。

public void today() {
    if (isBusy()) {
        System.out.println(“change time.”);
    }
    else if (isFree()) {
        System.out.println(“go to travel.”);
    }
    else {
        System.out.println(“stay at home to learn Alibaba Java Coding Guidelines.”);
    }

    return;
}

以多态取代表达式

如果一个类的行为受类型码控制,即出现switch语句或if eles语句,根据不同的值来执行不同的动作。针对这种情况,可以使用以子类取代类型码的方法,以类型码的宿主类为基类,针对每一种类型码建立一个子类,使用具有多态行为的继承体系。

以一个Power Manager类为例,其根据不同的mode,来设置A、B、C 三种模式,在set方法中判断了mode,并调用了相应的方法setA、setB、setC。

代码如下: 

public class PowerManager {
		public enum  MODE {
			A, B, C
		}

		private MODE mode;

		PowerManager(MODE mode) {
			this.mode = mode;
		}

		public void set() {
			if (mode == MODE.A)
				setA();
			else if (mode == MODE.B)
				setB();
			else if (mode == MODE.C)
				setC();
			else {
				System.out.printf("no such mode: %s", mode.toString());
				throw new RuntimeException();
			}
		}

		public void setA() {
			System.out.printf("setA");
		}
		
		public void setB() {
			System.out.printf("setB");
		}	
		public void setC() {
			System.out.printf("setC");
		}	
	}

为类型码的每个数值建立相应的类,将基类中的set变为抽象方法,并在各子类中实现。

class PowerManagerNewA extends PowerManagerNew{
    
    PowerManagerNewA() {    
    }

    public void set() {
        System.out.printf("setA");      
    }
}

基类构造函数接受了类型码作为参数,需要将其换为工厂函数,令其返回合适的对象。

public abstract class PowerManagerNew {
		public static enum  MODE {
			A, B, C
		}
		
	    PowerManagerNew() {    
	    }
		abstract void set();
			
		static public PowerManagerNew create(MODE mode) {
			switch(mode) {
			case A: return new PowerManagerNewA();
			case B: return new PowerManagerNewB();
			case C: return new PowerManagerNewC();	
			default: throw new IllegalArgumentException();
			}
		}
		
	}

类图如下:

 

在这个例子中并未体现出好处,但是如果基类有很多方法,都是根据类型码来执行相应的动作,就可以体现出来多态的优势。如果增加了新的类型,使用条件表达式,需要查找所有的条件表达式并更新。使用多态,只需要新建一个子类,实现抽象方法,修改基类的create方法即可。

这种方式其实类似于简单工厂,PowerManagerNew是一个工厂接口,工厂根据参数mode来生产A、B、C三种产品。

create是一个静态工厂方法,返回类型是PowerManagerNew,所以可以返回PowerManagerNew类的子类。此外还可以说明一点,抽象类虽然不可以实例化,但是如果具有静态方法,也是可以直接调用的。

以策略模式/状态模式取代类型码

发现代码重构中好多地方用到了设计模式,先留着以后再来填坑。

参考

《阿里巴巴Java开发手册》

《重构 改善既有代码的设计》

静态工厂方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值