我有一个带有methodA的类,它的现有结构如下
function methodA() {
$providers = $this->getFirstSetOfProviders();
foreach ($providers as $provider) {
try {
$this->method1($provider);
} catch ( Exception $e ) {
// exception handling
}
}
$providers = $this->getSecondSetOfProviders();
foreach ($providers as $provider) {
try {
$this->method2($provider);
} catch ( Exception $e ) {
// exception handling
}
}
}catch子句的内容是相同的。有没有办法组织代码,以避免重复嵌套在foreach循环中的try/catch结构?从概念上讲,我试图做的是
function methodA() {
foreach ($providers as $provider) {
$method1 = function($provider) {
$this->method1($provider);
}
$this->withTryCatch($method1);
}
...
}
function withTryCatch($method) {
try {
$method; // invoke this method somehow
} catch (Exception $e) {
// exception handling
}
}这看起来很像Code sandwich,但我不确定如何在php中进行。
更新: try/catch嵌套在foreach循环中,因此当抛出异常时,它将被处理,并且执行将继续到循环中的下一次迭代,而不是终止循环。
发布于 2013-01-22 22:35:30
异常的好处是它们是可以像其他对象一样传递的对象。因此,您可以删除重复的代码(基本样板除外),而无需做太多更改:
foreach ($providers as $provider) {
try {
$this->method1($provider);
} catch ( Exception $e ) {
$this->handleException($e);
}
}注意:如果你在异常处理中也需要一些上下文(例如$provider),只需要给handleException()更多的参数。
第2部分:重构整个方法
您想知道如何进一步删除重复项。我不知道这在您的实际代码中是否有意义,它也可能是过度工程。你必须自己决定这件事。下面是模板方法模式的一个实现。请原谅我粗鲁的命名,但我试图效仿您的做法,但我不知道您在做什么。
abstract class ClassThatDoesThingsWithProviders
{
public function methodA($providers)
{
foreach($provicers as $provider) {
try {
$this->methodThatActuallyDoesSomethingWithProvider($provider);
} catch(Exception $e) {
$this->handleException($e);
}
}
}
protected function handleException(Exception $e)
{
// handle exception
}
abstract protected function methodThatActuallyDoesSomethingWithProvider($provider);
}
class ClassThatDoesThing1WithProviders extends ClassThatDoesThingsWithProviders
{
protected function methodThatActuallyDoesSomethingWithProvider($provider)
{
// this is your method1()
}
}
class ClassThatDoesThing2WithProviders extends ClassThatDoesThingsWithProviders
{
protected function methodThatActuallyDoesSomethingWithProvider($provider)
{
// this is your method2()
}
}
class YourOriginalClass
{
protected $thingsdoer1;
protected $thingsdoer2;
public function __construct()
{
$this->thingsdoer1 = new ClassThatDoesThing1WithProviders;
$this->thingsdoer2 = new ClassThatDoesThing2WithProviders;
}
public function methodA()
{
$this->thingsdoer1->methodA($this->getFirstSetOfProviders());
$this->thingsdoer2->methodA($this->getSecondSetOfProviders());
}
}你可以很容易地用thingsdoer1和thingsdoer2组成一个数组,也许还可以同时抽象出getFirstSetOfProviders和getSecondSetOfProviders。此外,我不知道实际的method1和method2实现依赖于什么,也许你不能在不破坏内聚的情况下像这样提取它们。
但由于我不知道你的真实代码和你在做什么,我不能推荐一个具体的策略,把我上面的例子作为一个起点。
发布于 2013-01-22 14:35:25
function methodA() {
try {
$providers = $this->getFirstSetOfProviders();
foreach ($providers as $provider) {
$this->method1($provider);
}
$providers = $this->getSecondSetOfProviders();
foreach ($providers as $provider) {
$this->method2($provider);
}
} catch ( Exception $e ) {
// exception handling
}
}https://stackoverflow.com/questions/14452853
复制相似问题