【问题标题】:Spaghetti code, dealing with exception handling and errors? [closed]意大利面条代码,处理异常处理和错误? [关闭]
【发布时间】:2011-11-20 20:24:28
【问题描述】:

我正在为在线翻译服务编写一个包装器。目前,OnlineTranslator 类在我看来真的很难看,就像意大利面条代码一样。这是因为下划线服务(实际上是 Bing)中可能发生的许多错误会生成异常。

我不太了解如何处理异常和错误。重构我的代码的任何更改(谁说模式?)?如何去掉代码中那么多if

<?php
namespace DL\AdminBundle\Service;

class OnlineTranslator
{

    private $_service;
    private $_languages;
    private $_from;
    private $_to;

    private $_ERRORS = array(
        'UNSUPPORTED_DETECTION' => "'%s' service doesn't support language
            detection. Manually call 'setFrom' to set the source language.",
        'UNSUPPORTED_FROM_LANGUAGE' => "Source language code '%s' unrecognized
            or not supported by this service.",
        'UNSUPPORTED_TO_LANGUAGE' => "Destination language code '%s'
            unrecognized or not supported by this service.",
        'MISSING_TO_LANGUAGE' => "Destination language code is missing.",
        'GENERIC_SERVICE_ERROR' => "'%s' service returned an error: %s."
    );

    function __construct(IOnlineTranslator $service)
    {

        // Imposta il servizio e la lingua sorgente su auto
        $this->_service = $service;
        $this->_from = 'auto';

        $response = $this->_service->getLanguages();

        if ($response->error)
            throw new Exception(sprintf(
                $this->_ERRORS['GENERIC_SERVICE_ERROR'],
                $this->_service->getName(), $response->data));

        $this->_languages = $response->data;

    }

    function setFrom($languageCode)
    {

        // Controlla se la lingua è supportata
        if (!in_array($languageCode, $this->_languages))
            throw new Exception(sprintf(
                $this->_ERRORS['UNSUPPORTED_FROM_LANGUAGE'],
                $languageCode));

        // Imposta la lingua sorgente
        $this->_from = $languageCode;

    }

    function setTo($languageCode)
    {

        // Controlla se la lingua è supportata
        if (!in_array($languageCode, $this->_languages))
            throw new Exception(sprintf(
                $this->_ERRORS['UNSUPPORTED_TO_LANGUAGE'],
                $languageCode));

        // Imposta la lingua destinazione
        $this->_to = $languageCode;

    }

    function translate($text)
    {

        // Controlla che sia impostata la lingua di destinazione
        if (!isset($this->_to))
            throw new Exception($this->_ERRORS['MISSING_TO_LANGUAGE']);

        // Se detect è auto controlla che il servizio lo supporti
        if ('auto' == $this->_from && !$this->_service->isDetectAware())
            throw new Exception(sprintf(
                $this->_ERRORS['UNSUPPORTED_DETECTION'],
                $this->_service->getName()));

        // Imposta la lingua sorgente chiamando il metodo detect
        $response = $this->_service->detect($text);

        if ($response->error)
            throw new Exception(sprintf(
                $this->_ERRORS['GENERIC_SERVICE_ERROR'],
                $this->_service->getName(), $response->data));

        $this->_from = $response->data;

        // Traduci il testo chiamando il metodo translate
        $response = $this->_service->translate($text, $this->_from,
            $this->_to);

        if ($response->error)
            throw new Exception(sprintf(
                $this->_ERRORS['GENERIC_SERVICE_ERROR'],
                $this->_service->getName(), $response->data));

        return $response->data;

    }

}

?>

【问题讨论】:

  • @KingCrunch ifififif
  • if 是否出于某种原因阻止了问题?
  • 你称之为意大利面条代码?我想你从来没有见过真正的意大利面条代码我的朋友。 :) @Jared 是对的,if 块在您正确使用它们时没有任何问题(即:当没有其他更清洁的替代方案时),在这种情况下是正确的。您可能想尝试codereview.stackexchange.com。它仍处于测试阶段,但除非您有特定的问题/问题,否则我们无能为力。
  • 如果您想重构嵌套的 if 语句,请尝试使用决策表。但是,恕我直言,你的代码还不错。
  • 正如@netcoder 所暗示的那样,spaghetti code 是非常难以追踪它正在做什么的代码,因为回溯,缺乏视觉逻辑流,goto和其他意图模糊技术。这不是这个问题的一个例子,AFAICT。其实理解它的意图并不难。

标签: php design-patterns exception-handling refactoring


【解决方案1】:

正如其他人所说,这里并不是真正的意大利面条代码。问题是每个函数都有一些冗长的验证和异常抛出。验证是 cross-cutting concern,因此它最终可能会分散在各处并妨碍可读性。

解决此问题的一种方法是将验证代码封装到单独的函数中,并尝试减少一些冗长和重复。如果这是一个系统性问题,您也可以查看 PHP AOP。虽然我没有使用 AOP 的经验,但日志/错误处理通常作为其使用示例。

【讨论】:

    猜你喜欢
    • 2020-01-04
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    相关资源
    最近更新 更多