重构之多态消除条件分支
最近翻看之前写过一个项目,其中用到了大量的 switch-case 分支语句,大致的代码结构如下
代码演示
class A {
run() {
console.log(A.name, 'run1!');
}
}
class B {
run() {
console.log(B.name, 'run2!');
}
}
class C {
run() {
console.log(C.name, 'run3!');
}
}
function fun1(type) {
let temp;
switch (type) {
case 1:
temp = new A();
break;
case 2:
temp = new B();
break;
case 3:
temp = new C();
break;
default:
throw new Error('Unsupported types');
break;
}
temp.run();
}
fun1(1);
可以发现每个分支都有个共同的特点,通过构造函数实例化对象 a,调用a.task
方法
temp = new A()
但现在有一个需求 给 A,B,C 三个类分别加上getUser
方法,用来获取传入的 user,代码如下
class A {
constructor(user) {
this.user = user;
}
getUser() {
return this.user;
}
run() {
console.log(A.name, 'run1!');
}
}
class B {
constructor(user) {
this.user = user;
}
getUser() {
return this.user;
}
run() {
console.log(B.name, 'run2!');
}
}
class C {
constructor(user) {
this.user = user;
}
getUser() {
return this.user;
}
run() {
console.log(C.name, 'run3!');
}
}
function fun2(type) {
let temp;
switch (type) {
case 1:
temp = new A({ username: 'aaa' });
break;
case 2:
temp = new B({ username: 'bbb' });
break;
case 3:
temp = new C({ username: 'ccc' });
break;
default:
throw new Error('Unsupported types');
break;
}
let user = temp.getUser();
return user;
}
let user = fun2(1);
console.log(user);
从这你也能看的出来,如果我要在添加一个需求的话,我就要分别给这三个类添加方法(当然这个是避免不了的),同时又要定义一个fun3
来指定功能,没错,需求和写着代码的都是我。于是我决定重构一些这一部分的代码,为以后方便我后续的修改操作。
重构代码
首先 我们也能到两个部分都有 switch 分支,并且都夹杂着 break 语句,说实话,看的不是很入眼。同时定义了一个 temp 临时参数用于调用,不妨封装成一个函数,专门用来获取该类的实例对象。
function getClass(type) {
switch (type) {
case 1:
return new A({ username: 'aaa' });
case 2:
return new B({ username: 'bbb' });
case 3:
return new C({ username: 'ccc' });
default:
throw new Error('Unsupported types');
}
}
function fun2(type) {
let temp = getClass(type);
let user = temp.getUser();
return user;
}
这样 就能把那个共有的switch-case
代码封装成一个工厂函数用于获取。