有些我正在审查团队代码库中的一些代码,我们遍历一个分层数据结构并从中构建新的数据结构。没有嵌套循环 - 层次结构的每个级别都有自己的专用函数。
所以我们有这样的代码:
public void DoA(A a, Transform transform)
{
foreach(B b in a)
DoB(b, transform);
}
public void DoB(B b, Transform transform)
{
if (b != null && b.IsAvailable)
return;
foreach(C c in b)
DoC(c, transform)
}
public void DoC(C c, Transform transform)
{
var cAndAHalf = DoCAndAHalf(c.FindAll(x => x.Children > 0);
foreach(D d in cAndAHalf)
DoD(d, transform);
}
. . .
public void DoX(X x, Transform transform)
{
Res res = new Res();
if (x.Selected)
{
res.Selected = true;
res.ResourceCount = 1;
}
transform.Add(res);
}
有很多这样的方法,其中每个方法的长度为3到5行,类似命名,通常包含一个简单的空检查或过滤器,粗略的代码检查显示没有多次方法真正被调用。方法是公开的,用于单元测试目的。
我个人觉得代码很难导航,因为有很多公共方法= =几十个潜在的入口点进入类内部。
这种编码模式有名字吗?这是反模式吗?这种风格比简单地将循环嵌套在单个函数中更有优势吗?
看起来像我的责任链。您只需处理部分传入请求,然后转移到链中的下一个项目。
在你的情况下,它应该是这样的:
Action action = new Action;
action = action.SetNext(DoA);
action = action.SetNext(DoB);
action = action.SetNext(DoC);
A a = new A();
action.Process(a);
让人惊讶。这应该绝对是合格的东西。不确定它是反模式。我会选择反递归。
它也可能是Programming by Permutation的标志(开发人员每次结构变得更深时都会在层次结构中添加一个级别)。
我认为这是一种很好的编码风格 - 一种单一责任的小方法。如果这些方法名称很好,那么应该使代码易于理解和维护。
当然,如果许多方法非常相似,那么可以寻找一个共同的模式,并通过使用委托或类似的东西来解决这个问题 - 但这实际上取决于实际的代码。
这看起来有点像Composite pattern,除了你可以利用层次结构中父母和孩子的相似性来最小化你的编码。
您可以通过让结构中的每个元素实现一个知道如何处理其子代的接口来利用这一点,例如:
public interface ChildProcessor {
public void process()
}
public A implements ChildProcessor {
public void process() { foreach (B b )... }
}
public B implements ChildProcessor {
public void process() { foreach (C c )... }
}
public void DoA(A a, Transform transform)
{
A.process()...
}