typescript - 干净的方式来尊重 DRY 的条件

标签 typescript algorithm coding-style dry

我在 typescript 中得到了这段代码(尽管语言并不重要):

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,作为一个原则,就是摆脱不必要的重复,但并不限制你在必要时不能重复自己的情况。因此,将 self 重复保持在合理的最低限度应该是一种妥协。我建议如下:

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);
    }
}

你可以通过实现一个基类/接口(interface)来进一步增强它,确保 obj 是这样一个实例并为它实现 generateUUID 以及所有类扩展它,因此您将不需要在使用级别的内部条件。

关于typescript - 干净的方式来尊重 DRY 的条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61252641/

相关文章:

javascript - vertexAttribPointer 的目的是什么?

algorithm - 获取二叉搜索树的平均高度

ruby - 有向无环图中的循环检测更快?

node.js - 我可以使用自定义模块解析函数(如 "proxyquire")代替 TypeScript 的 require() 吗?

html - Angular2 将来自服务器的 html 包含到一个 div 中

javascript - 如何使用带有链接支持的 lodash 和 typescript 的 mixins

C++ header - 接口(interface)和实现细节之间的分离

algorithm - 在基数排序中选择的 bin 的最佳大小是多少?

ruby-on-rails - 如何使用Yard记录Rails枚举类型

scala - 支撑或不支撑 : case statement block