【重构】六、简化条件逻辑

1、分解条件表达式

变量有变量的用途,如果变量承担多个责任,它应该被分解为多个变量

// bad
if(!aDate.isBefore(plan.summerStart) && !aDate.isAfter(plan.summerEnd)){
	charge = quantity * plan.summerRate
} else {
	charge = quantity * plan.regularRate + plan.regularSericeCharge	
}

// good
function summer() {
	return !aDate.isBefore(plan.summerStart) && !aDate.isAfter(plan.summerEnd)
}

functionm summerCharge() {
	return quantity * plan.summerRate
}

functionm regularCharge() {
	return quantity * plan.regularRate + plan.regularSericeCharge	
}
charge = summer() ? summerCharge() : regularCharge()

2、合并条件表达式

// bad -- 当一连串的条件检查都返回同一个的结果时,可以合并条件
function disabilityAmount(anEmployee) {
	if(anEmployee.seniority < 2) return 0
	if(anEmployee.monthsDisabled > 12) return 0
	if(anEmployee.isPartTime) return 0
	
	// doSomething
}

// good
function isNotEligibleFordisability(anEmployee) {
	 return (anEmployee.seniority < 2)
					|| (anEmployee.monthsDisabled > 12)
					|| (anEmployee.isPartTime)
}

function disabilityAmount(anEmployee) {
	if(isNotEligibleFordisability()) return 0
	// doSomething
}
// bad
if(anEmployee.onVaction){
	if(anEmployee.seniority > 10) {
		return 1
	}
	return 0.5
}

// good
if(anEmployee.onVaction 
	 && (anEmployee.seniority > 10)) return 1
return 0.5

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

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

function payAmount(employee) {
	let result
	if(employee.isSeperated) {
		result = {amount: 0, reasonCode: 'SEP'}
	}
	else {
		if(employee.isRetired) {
			result = { amount: 0, reasonCode: 'RET' }
		}
		else {
			// doSomething
		}
	}
	return result
}


// good
function payAmount(employee) {
	let result
	if(employee.isSeperated) return {amount: 0, reasonCode: 'SEP'}
	if(employee.isRetired) result = { amount: 0, reasonCode: 'RET' }

	// doSomething
	return result
}

将条件反转

function adjustedCapital(anInstrument) {
	let result = 0
	if(anInstrument.capital > 0) {
		if(anInstrument.interesRate > 0 && anInstrument.duration > 0) {
			result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor
		}
	}
	return result
}
function adjustedCapital(anInstrument) {
	if(anInstrument.capital <= 0
		|| anInstrument.interesRate <=0 
		|| anInstrument.duration <= 0) return 0
	return (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor
}

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

// bad
// 判断鸟儿的羽毛是什么颜色,以及速度有多快
// 鸟儿羽毛的颜色
function plumages(birds) {
	return new Map(birds.map{b => b.name, plumage(b)})
}
// 鸟儿的速度
function speeds(birds) {
	return new Map(birds.map{b => b.name, airSpeedVelocity(b)})
}
function plumage(bird) {
	switch(bird.type) {
		case 'EuropeanSwallow'
			 return 'average'
		case 'AfricanSwallow'
			 return (bird.numberOfCocounts > 2) ? 'tired' : 'average'
		case 'NorwegianBlueParrot'
			return (bird.voltage > 100) ? 'scorched' : 'beautiful'
		default: 
			return 'unknown'
	}
}
function airSpeedVelocity(bird) {
	switch(bird.type) {
		case 'EuropeanSwallow'
			 return 35
		case 'AfricanSwallow'
			 return 40 - 2 * bird.numberOfCocounts
		case 'NorwegianBlueParrot'
			return (bird.isNailed) ? 0 : 10 + bird.voltage / 10
		default: 
			return null
	}
}

// good -- 建立超类,由子类具体返回各自的羽毛和速度,switch 方法只需判断创建对应的子类
function plumages(birds) {
	return new Map(birds
								 .map(b => createBird(bird))
								 .map(bird => [bird.name, bird.plumage]))
}
function speeds(birds) {
	return new Map(birds
								 .map(b => createBird(bird))
								 .map(bird => [bird.name, bird.airSpeedVelocity]))
}
function createBird(bird) {
	switch(bird.type) {
		case 'EuropeanSwallow'
			return new EuropeanSwallow(bird)
		case 'AfricanSwallow'
			return new AfricanSwallow(bird)
		case 'NorwegianBlueParrot'
			return new NorwegianBlueParrot(bird)
		default: 
			return new Bird(bird)
	}
}
class Bird {
	constructor(birdObject) {
		Object.assign(this, birdObject)
	}
	get plumage() {
		return 'unknown'
	}
	get airSpeedVelocity() {
		return null
	}
}

class EuropeanSwallow extends Bird {
	get plumage() {
		return 'average'
	}
	get airSpeedVelocity() {
		return 35
	}
}
class AfricanSwallow extends Bird {
	get plumage() {
		return (this.numberOfCocounts > 2) ? 'tired' : 'average'
	}
	get airSpeedVelocity() {
		return 40 - 2 * this.numberOfCocounts
	}
}
class NorwegianBlueParrot extends Bird {
	get plumage() {
			return (this.voltage > 100) ? 'scorched' : 'beautiful'
	}
	get airSpeedVelocity() {
		return (this.isNailed) ? 0 : 10 + this.voltage / 10
	}
}
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值