干净的方式来尊重 DRY 的条件
Clean way to respect DRY for conditions
我在打字稿中得到了这段代码(尽管语言并不重要):
let name = '', parentId = '';
if (obj instanceof Service) {
name = obj.name;
} else if (obj instanceof Method) {
name = obj.name;
parentId = this.generateUUID(obj._parentService);
} else if (obj instanceof Argument) {
name = obj.name;
parentId = this.generateUUID(obj._parentMethod);
}
我可以用 case 语句做同样的事情,但这不会改变问题:我重复了 name = obj.name;
3 次
所以我可以将代码更改为:
let name = '', parentId = '';
if(obj instanceof Service || obj instanceof Method || obj instanceof Argument)
name = obj.name;
if (obj instanceof Method) {
parentId = this.generateUUID(obj._parentService);
} else if (obj instanceof Argument) {
parentId = this.generateUUID(obj._parentMethod);
}
但是我有一个我不太喜欢的条件重复..
有没有办法做到既不重复又可读性好?
这是我的问题的一个最小可重现示例:
class A {name:string=''}
class B {name:string=''; parentA: A = new A()}
class C {name:string=''; parentB: B = new B()}
function hash(s: string): string{
return '' + s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
function generateUUID(obj: A | B | C) {
let name = '', parentId = '';
if (obj instanceof A) {
name = obj.name;
} else if (obj instanceof B) {
name = obj.name;
parentId = generateUUID(obj.parentA);
} else if (obj instanceof C) {
name = obj.name;
parentId = generateUUID(obj.parentB);
}
return hash(parentId+name);
}
const a = new A();
a.name = 'a';
const b = new B();
b.name = 'b';
b.parentA = a;
const c = new C();
c.name = 'c';
c.parentB = b;
console.log(
generateUUID(c)
);
您将无法始终避免所有重复。 DRY,作为一个原则,就是摆脱不必要的重复,但并不限制你在必要时不能重复自己的情况。因此,将自我重复保持在合理的最低限度应该是一种妥协。我建议如下:
if(obj instanceof Service || obj instanceof Method || obj instanceof Argument) {
name = obj.name;
if (obj.instanceof Method) {
parentId = this.generateUUID(obj._parentService);
} else if (obj instanceof Argument) {
parentId = this.generateUUID(obj._parentMethod);
}
}
您可以通过实施基础 class/interface 来进一步增强这一点,确保 obj
是这样一个实例并为它实施 generateUUID
以及所有 类 扩展它,因此您将不需要使用级别的内部条件。
既然您已经使用了 类,那么将 generateUUID
放入其中可能是合理的。
function hash(s: string): string {
return "" + s.split("").reduce((a, b) => {
a = ((a << 5) - a) + b.charCodeAt(0);
return a & a;
}, 0);
}
class A {
name: string = "";
generateUUID() {
return hash(this.name);
}
}
class B {
name: string = "";
parentA: A = new A();
generateUUID() {
return hash(this.parentA.generateUUID + this.name);
}
}
class C {
name: string = "";
parentB: B = new B();
generateUUID() {
return hash(this.parentB.generateUUID + this.name);
}
}
const a = new A();
a.name = "a";
const b = new B();
b.name = "b";
b.parentA = a;
const c = new C();
c.name = "c";
c.parentB = b;
console.log(
c.generateUUID()
);
我在打字稿中得到了这段代码(尽管语言并不重要):
let name = '', parentId = '';
if (obj instanceof Service) {
name = obj.name;
} else if (obj instanceof Method) {
name = obj.name;
parentId = this.generateUUID(obj._parentService);
} else if (obj instanceof Argument) {
name = obj.name;
parentId = this.generateUUID(obj._parentMethod);
}
我可以用 case 语句做同样的事情,但这不会改变问题:我重复了 name = obj.name;
3 次
所以我可以将代码更改为:
let name = '', parentId = '';
if(obj instanceof Service || obj instanceof Method || obj instanceof Argument)
name = obj.name;
if (obj instanceof Method) {
parentId = this.generateUUID(obj._parentService);
} else if (obj instanceof Argument) {
parentId = this.generateUUID(obj._parentMethod);
}
但是我有一个我不太喜欢的条件重复..
有没有办法做到既不重复又可读性好?
这是我的问题的一个最小可重现示例:
class A {name:string=''}
class B {name:string=''; parentA: A = new A()}
class C {name:string=''; parentB: B = new B()}
function hash(s: string): string{
return '' + s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
function generateUUID(obj: A | B | C) {
let name = '', parentId = '';
if (obj instanceof A) {
name = obj.name;
} else if (obj instanceof B) {
name = obj.name;
parentId = generateUUID(obj.parentA);
} else if (obj instanceof C) {
name = obj.name;
parentId = generateUUID(obj.parentB);
}
return hash(parentId+name);
}
const a = new A();
a.name = 'a';
const b = new B();
b.name = 'b';
b.parentA = a;
const c = new C();
c.name = 'c';
c.parentB = b;
console.log(
generateUUID(c)
);
您将无法始终避免所有重复。 DRY,作为一个原则,就是摆脱不必要的重复,但并不限制你在必要时不能重复自己的情况。因此,将自我重复保持在合理的最低限度应该是一种妥协。我建议如下:
if(obj instanceof Service || obj instanceof Method || obj instanceof Argument) {
name = obj.name;
if (obj.instanceof Method) {
parentId = this.generateUUID(obj._parentService);
} else if (obj instanceof Argument) {
parentId = this.generateUUID(obj._parentMethod);
}
}
您可以通过实施基础 class/interface 来进一步增强这一点,确保 obj
是这样一个实例并为它实施 generateUUID
以及所有 类 扩展它,因此您将不需要使用级别的内部条件。
既然您已经使用了 类,那么将 generateUUID
放入其中可能是合理的。
function hash(s: string): string {
return "" + s.split("").reduce((a, b) => {
a = ((a << 5) - a) + b.charCodeAt(0);
return a & a;
}, 0);
}
class A {
name: string = "";
generateUUID() {
return hash(this.name);
}
}
class B {
name: string = "";
parentA: A = new A();
generateUUID() {
return hash(this.parentA.generateUUID + this.name);
}
}
class C {
name: string = "";
parentB: B = new B();
generateUUID() {
return hash(this.parentB.generateUUID + this.name);
}
}
const a = new A();
a.name = "a";
const b = new B();
b.name = "b";
b.parentA = a;
const c = new C();
c.name = "c";
c.parentB = b;
console.log(
c.generateUUID()
);