如何针对两个近乎相同的函数遵循DRY原则消除代码重复?
这思路太对了!提取重复逻辑并通过通用方法来复用确实是消除代码重复的绝佳方案,针对你这两个哈希表操作函数,我给你整理了具体的实现方式:
第一步:提取重复的核心逻辑
你的GetValue和SetValue都重复做了计算哈希索引和遍历链表查找对应key节点的操作,我们可以把这部分封装成一个辅助方法,返回查找过程中需要的所有关键信息(找到的节点、哈希索引、链表中的前一个节点——毕竟SetValue可能需要插入新节点):
// 假设你的节点类是这样的,根据实际情况调整 private class Node { public object Key { get; set; } public object Value { get; set; } public Node Next { get; set; } } // 提取的辅助方法,返回查找相关的元组信息 private (Node FoundNode, int Index, Node PreviousNode) FindNodeByKey(object key) { var index = GetHash(key); var currentNode = _table[index]; Node previousNode = null; while (currentNode != null) { if (Equals(currentNode.Key, key)) { // 找到匹配节点,返回相关信息 return (currentNode, index, previousNode); } previousNode = currentNode; currentNode = currentNode.Next; } // 没找到匹配节点,返回null和对应的索引、最后一个节点 return (null, index, previousNode); }
第二步:改写原有函数,复用辅助方法
现在GetValue和SetValue只需要专注于各自的业务逻辑即可:
改写后的GetValue
private object GetValue(object key) { var (foundNode, _, _) = FindNodeByKey(key); if (foundNode != null) { return foundNode.Value; } throw new KeyNotFoundException("Such key doesn't exist"); }
改写后的SetValue(假设原逻辑是找到则更新,未找到则插入)
private void SetValue(object key, object value) { var (foundNode, index, previousNode) = FindNodeByKey(key); if (foundNode != null) { // 找到匹配节点,直接更新值 foundNode.Value = value; return; } // 未找到节点,创建新节点并插入链表 var newNode = new Node { Key = key, Value = value }; if (previousNode == null) { // 该哈希桶为空,直接作为表头 _table[index] = newNode; } else { // 插入到链表末尾 previousNode.Next = newNode; } }
为什么这样做?
- 完全消除了重复代码,后续如果要修改哈希计算或链表遍历逻辑,只需要改
FindNodeByKey这一个地方即可,维护性大大提升; - 原有函数的职责更单一,
GetValue只负责获取值,SetValue只负责设置值,代码可读性更好; - 返回元组的方式比传入回调更直观,也更灵活——如果后续有其他操作哈希表的函数(比如删除),也可以直接复用这个辅助方法。
内容的提问来源于stack exchange,提问作者Tomorrow's Explorer
相关产品推荐
相关产品推荐

