这绝对是主观的,但我想尽量避免它变得有争议。我认为如果人们适当地对待它,这可能是一个有趣的问题。
在我最近的几个项目中,我曾经实现过长委托链很常见的架构。
双委托链经常会遇到:
bool Exists = Env->FileSystem->FileExists( "foo.txt" );
三重委托并不罕见:
Env->Renderer->GetCanvas()->TextStr( ... );
存在更高阶的委托链,但非常稀缺。
在上面提到的示例中,没有执行 NULL 运行时检查,因为使用的对象始终存在并且对程序的运行至关重要,并且在执行开始时显式构建。基本上我曾经在这些情况下拆分委托链:
1)我重用通过委托链获得的对象:
{ // make C invisible to the parent scope
clCanvas* C = Env->Renderer->GetCanvas();
C->TextStr( ... );
C->TextStr( ... );
C->TextStr( ... );
}
2)委托链中间某处的中间对象在使用前应检查是否为 NULL。例如。
clCanvas* C = Env->Renderer->GetCanvas();
if ( C ) C->TextStr( ... );
我曾经通过提供代理对象来对抗情况 (2),以便可以在导致结果的非 NULL 对象上调用方法empty
。
我的问题是:
- 案例 (1) 或 (2) 是模式还是反模式?
- 有没有更好的方法来处理 C++ 中的长委托链?
以下是我在做出选择时考虑的一些利弊:
优点:
- 它非常具有描述性:从 1 行代码中可以清楚地看出对象来自哪里
- 长委托链看起来不错
缺点:
- 交互式调试很费力,因为很难在委托链中检查多个临时对象
我想知道长委托链的其他优点和缺点。请提出您的推理并根据有充分理由的意见进行投票,而不是您是否同意。