1

我是 try-catch 的新手,最近一直在重构大量代码以跟上DRY的原则。但是,我仍然有一些我无法完全解决的场景。例如,在我正在开发的多语言应用程序中,我想让用户通过在 URL 的查询字符串中传递两个字母的国家代码来设置界面语言,或者让应用程序使用默认语言,如果用户没有请求:

// Which language shall we use?
$language = new language();
if(isset($_GET['language_code'])){
    try {
        $language->set_by_language_code($_GET['language_code']);
    } catch(e_language_not_found $e){
        try {
            $language->set_default_language();
            // TODO - use 'e_language_not_found' to display an error in the default language
        } catch(Exception $e){
            exit('No default language found');
        }
    }
} else {
    try {
        $language->set_default_language();
    } catch(Exception $e){
        exit('No default language found');
    }
}

set_default_language()问题是当用户根本没有请求任何语言时,我已经重复了该块。如何重构代码以便在应用程序中只调用一次该方法?谢谢!

4

2 回答 2

3

在我看来,你应该在你的language类中实现这些方法:

  • language::hasLanguage()它返回一个布尔值,指示语言的存在(不抛出异常!)

  • language::getDefLang()它返回默认语言标识符。


// Which language shall we use?
$language = new language();

// fallback
$langToSet = $language->getDefLang();

// use the passed language identifier if it exists
$passedLangId = isset($_GET['language_code']) ? $_GET['language_code'] : NULL;
if ($passedLangId !== NULL && $language->hasLanguage($passedLangId)) {
  $langToSet = $passedLangId;
}

try {
  $language->set_by_language_code($langToSet);
}
catch(Exception $e){
  exit('No default language found');
}

您还应该为块指定更详细Exception的类型。catch

try...catch您还可以通过language::hasLanguage()if语句中使用来替换块。

于 2013-02-27T22:39:59.220 回答
2

您在两个地方调用该函数的事实本身并不坏。它不会影响性能,重构它可能会降低代码的可读性。

这是我为您的代码提出的:

// Which language shall we use?
$language = new language();
try {
  try {
    if(isset($_GET['language_code'])){
      $language->set_by_language_code($_GET['language_code']);
    } else {
      $language->set_default_language();     
    }
  } catch(e_language_not_found $e){    
      $language->set_default_language();    
  }
} catch (Exception $e){
  exit('No default language found');
}
于 2013-02-27T22:40:25.180 回答