【发布时间】:2017-05-10 18:53:33
【问题描述】:
我想知道在某些情况下是否有更好的方法来“摆脱”方法。让我用代码更好地解释一下:
function execute($context)
{
// some init actions
$event = new BeforeOperationOne();
$this->dispatch($event);
if ($event->accessGranted()) {
$context->setUser($this->user);
// other repeated code
return;
}
$result = $this->operationOne();
// some other code
$event = new BeforeOperationTwo();
$this->dispatch($event);
if ($event->accessGranted()) {
$context->setUser($this->user);
// other repeated code
return;
}
// this is not important what is access checker,
// this is just to show that all following code uses data
// computed in previous steps
$accessChecker = new AccessChecker($result);
$this->operationTwo(accessChecker);
// some other code
$event = new BeforeOperationThree();
$this->dispatch($event);
if ($event->accessGranted()) {
$context->setUser($this->user);
// other repeated code
return;
}
$this->operationThree();
// some other code
}
我们在这里重复了这个条件,当用户可以从事件访问时,在上下文中设置用户。我能想到的选择是:
- 丑陋的 do-while(false) 或 goto(我最好保持现在这样)
- 将此提取到方法并将条件更改为
if (!$this->handleEvent($event, $context)) { return; }- 这没有多大帮助,并且无法认为更好的名称句柄不会说它正在返回一些东西 - 为操作构建闭包数组并循环检查。我们可以假设所有事件类都派生自具有 accessGranted 方法的公共类。这可能很难看,因为某些操作需要来自先前“步骤”的数据,我必须将它们保留在外面并传递它们。
- 抛出并捕获用户有权访问的异常 - 另一个糟糕的解决方案。
你有什么想法可以写得更好吗?
【问题讨论】:
-
您的问题将收到很多基于意见的答案。但是,请查看 Object Calisthenics、SOLID 和 Clean Code book - 第 3 章 - Functions。
-
最后,正确的词是“early return”
-
也许“责任链”模式会有用?
-
我真正想做的是提供使用事件系统挂钩方法的可能性,以及是否可以提前完成方法以避免对用户访问进行不必要的繁重计算。