意大利面条代码,处理异常处理和错误?

时间:2011-11-20 20:24:28

标签: php design-patterns exception-handling refactoring

我正在编写在线翻译服务的包装器。目前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;

    }

}

?>

1 个答案:

答案 0 :(得分:0)

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

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