Рефакторинг «извлечение функции» при рендеринге почтового сообщения


Исходный код

function convert_code_tag_for_email($text = "", $lang=false)
{
	global $MESS;
	if (strlen($text)<=0) return;
	if($lang===false) $lang = LANGUAGE_ID;
	$text = stripslashes($text);
	$text = preg_replace("#<#", "<", $text);
	$text = preg_replace("#>#", ">", $text);
	$text = preg_replace("#^(.*?)$#", "   \\1", $text);
	$OLD_MESS = $MESS;
	$MESS = array();
	include($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/lang/".$lang."/tools.php");
	$s1 = "--------------- ".$MESS["MAIN_CODE_S"]." -------------------";
	$MESS = $OLD_MESS;
	$s2 = str_repeat("-",strlen($s1));
	$text = "\n\n>".$s1."\n".$text."\n>".$s2."\n\n";
	return $text;
}

Что не так в исходном коде

Функция знает, как делать три не связанные между собой вещи:

  1. как получить нужный локализованный текст;
  2. как убрать лишние символы из текста сообщения;
  3. как отформатировать сообщение.

Причём, что особенно плохо, реализации этих знаний перемешаны между собой: третья строка функции касается локализации, потом алгоритм переключается на очистку спецсимволов, потом опять локализация, потом форматирование плюс локализация, потом локализация, и в конце форматирование.

Для чего внутри функции подключена глобальная переменная $MESS, если фактически её содержимое не читается и не записывается — не ясно.

Для проверки пустоты текста мне больше нравится другая функция, с говорящим названием empty.

Вариант рефакторинга исходного кода

function convert_code_tag_for_email($text = '', $lang = false)
{
	$text = escape_email_text($text);
	$message = get_localized_message('MAIN_CODE_S', $lang);
	return format_email_message($message, $text);
}

function escape_email_text($text)
{
	$text = stripslashes($text);
	$text = preg_replace("#<#", "<", $text);
	$text = preg_replace("#>#", ">", $text);
	$text = preg_replace("#^(.*?)$#", "   \\1", $text);
	return $text;
}

function get_localized_message($message_code, $lang = false)
{
	$messages = get_locale($lang);
	return $messages[$message_code];
}

function get_locale($lang)
{
	global $LOCALE_MESSAGES;
	if ($lang === false) $lang = LANGUAGE_ID;
	if (empty($LOCALE_MESSAGES[$lang])) {
		$MESS = array();
		include($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/lang/".$lang."/tools.php");
		$LOCALE_MESSAGES[$lang] = $MESS;
	}
	return $LOCALE_MESSAGES[$lang];
}

function format_email_message($message, $text)
{
	$s1 = "--------------- ".$message." -------------------";
	$s2 = str_repeat("-",strlen($s1));
	$text = "\n\n>".$s1."\n".$text."\n>".$s2."\n\n";
	return $text;
}

При реализации функции получения локализованного сообщения пришлось извлечь из неё подробности хранения и кеширования локализованных текстов — это очень полезно, потому что даёт полную свободу менять способы хранения и кеширования дополнительных ресурсов.

Теперь каждая функция «знает» только что-то одно, и очень простое.

Теория