意大利面条式代码,处理异常处理和错误?
我正在为在线翻译服务编写一个包装器。目前,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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如其他人所说,这里并不是真正的意大利面条代码。问题是每个函数中都有一些冗长的验证和异常抛出。验证是一个横切关注点,因此它最终可能会分散并妨碍可读性。
处理此问题的一种方法是将验证代码包装到单独的函数中,并尝试减少一些冗长和重复。您还可以查看 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.