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

发布于 2024-12-17 03:53:14 字数 3576 浏览 0 评论 0原文

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

    }

}

?>

I'm writing a wrapper for online translation services. Currently the OnlineTranslator class looks really ugly to me, like spaghetti code. It's because exception generation for many errors that can occur in the underline service (Bing, actually).

I'm not so good in understanding how dealing with exceptions and errors. Any change to refactor my code (who said patterns?)? How to get rid of so many if in the code?

<?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;

    }

}

?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

难忘№最初的完美 2024-12-24 03:53:14

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

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

Like others said, it's not really spaghetti code here. The problem is there is somewhat verbose validation and exception throwing in every function. Validation is a cross-cutting concern so it can end up scattered all over and hinder readability.

One way to handle this is to wrap up the validation code into separate functions and try to reduce some of the verbosity and duplication. You could also look into PHP AOP if this is a systemic issue. Although I have no experience with AOP, logging/error handling is often given as an example of its use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文