如果两个功能几乎相同,如何遵守 DRY 原则?

How to comply DRY principle if two functions are almost the same?

我有两个几乎相同的功能。有没有好的去重方法?

我考虑将重复的代码移到单独的函数中并传递一个函数作为参数。

private object GetValue(object key)
    {
        var index = GetHash(key);
        var node = _table[index];

        while (node != null)
        {
            if (Equals(node.Key, key)) return node.Value;

            node = node.Next;
        }

        throw new KeyNotFoundException("Such key doesn't exist");
    }

private void SetValue(object key, object value)
    {
        var index = GetHash(key);
        var node = _table[index];

        if(value == null) RemoveValue(key);

        while (node != null)
        {
            if (Equals(node.Key, key)) 
            {
               node.Value = value;
               return;
            }

            node = node.Next;
        }

        throw new KeyNotFoundException("Such key doesn't exist");           
    }

将您的每个方法分成两部分:

  • 寻找目标节点(private helper),
  • 如果目标节点存在则对其进行处理

寻找目标节点应该有这个签名:

private Node FindNodeByKey(object key) {
    ...
}

这个方法负责抛出KeyNotFoundException,所以getter和setter都可以假定当FindNodeByKeyreturns一个值时,它不是 null。此假设使您可以将 getter 缩减为一行:

private object GetValue(object key) {
    return FindNodeByKey(key).Value;
}

private void SetValue(object key, object value) {
    if (value == null) {
        RemoveValue(key);
    } else {
        FindNodeByKey(key).Value = value;
    }
}

当然,看起来很合理。

private Node GetNode(object key) 
{
  var index = GetHash(key);
  var node = _table[index];
  while (true)
  {
    if (node == null)
      throw ...
    if (Equals(node.Key, key))
      return node;
    node = node.Next;
  }
}
private object GetValue(object key) => GetNode(key).Value;
private void SetValue(object key, object value)
{
  if (value == null)
    RemoveValue(key);
  else 
    GetNode(key).Value = value;
}

现在,经常问自己"how can I improve this further?"一些想法:

  • 为什么这些方法是私有的?它们是带有适当索引器的漂亮 public API 的实现细节吗?
  • 对象,2018年?使用泛型!
  • 以此类推