29.5. Проект Strategy
Типовой проект Strategy применим в случае, когда одну проблему можно решить с помощью двух или нескольких алгоритмов. Выбор решения в данном случае полностью зависит от пользователя. Например, графическая программа предполагает сохранение изображения в нескольких форматах, и для записи каждого из них предусмотрен специальный код. Причем ввод во все программы является идентичным.
Этот типовой проект также позволяет представлять Web-приложение на различных языках или различными стилями. Простейшие схемы позволяют справиться с массивами слов, представленными на различных языках или разными цветами, но для сложной настройки и получения динамических результатов может потребоваться динамический код. С такой ситуацией можно столкнуться при попытке реализации международных версий на коммерческом Web-узле.
Кроме сложностей с языком, форматы представления чисел в различных странах также различаются. Конечно, функции number_format еще очень далеко до реального решения проблемы. Она не работает с денежными величинами. Американцы используют символ $ слева от чисел для предоставления фискальных данных, а европейцы - обозначение EUR (символ общеевропейской валюты Евро). В зависимости от ситуации японские потребители будут ожидать обозначения иены справа от числа.
Для того чтобы реализовать этот типовой проект, для каждого алгоритма необходимо определить отдельный интерфейс. А затем можно разработать различные вариации этого интерфейса. В PHP это реализуется с помощью определения общего класса и расширения его действия на подклассы. Для создания постоянного интерфейса этой функциональной возможности необходимо воспользоваться преимуществом полиморфизма.
В листинге 29.4 показан основной класс localization, который определяет два метода, formatMoney и translate. Первый метод возвращает форматизированную версию денежной суммы, второй делает попытку перевести английскую фразу на местный язык. Основной класс задает стандартные функциональные возможности. В подклассах принимается решение использовать стандартные значения или проигнорировать их.

| Листинг 29.4. Типовой проект Strategy
<?php
//Суперкласс Strategy class Localization
{
function formatMoney($sum)
{
number_format($sum);
}
function translate($phrase)
{
return($phrase);
}

}
?> 
В листинге 29.5 содержится английский подкласс localization, специально предназначенный для того, чтобы разместить слева от числа знак доллара или отрицательное значение. Он не перекрывает установки метода translate, так как считается, что данные вводятся на английском языке.

| Листинг 29.5. Английский подкласс_
<?php
// локализация
include_once('2 9-4.php');
class English extends Localization
{
function formatMoney($sum)
{
$text = "";
//минус предшествует символу доллара
if($sum < 0)
{
$text .=
$sum = aba($sum);
}
$text .= "tiny_mce_markerquot; . number_format($sum, 2, ','); return($text);
}
}

В листинге 29.6 содержится немецкий подкласс localization, который использует в качестве разделителя тысяч точки, а для отделения дробной части - запятые. Он также включает грубый метод translate, который обрабатывает только слова yes и no. В реальном применении для перевода этот метод должен использовать какую-либо базу данных или внешний интерфейс.
Наконец, листинг 29.7 представляет собой пример подкласса localization. Сценарий может выбрать между имеющимися подклассами, исходя из предпочтений пользователей или какого-либо ключа, такого как HTTP-заголовки, или имени домена. Эта реализация зависит от классов, хранящихся в файлах с аналогичным именем. После инициализации все использования для любого другого языка классов будут аналогичными.

| Листинг 29.6. Немецкий подкласс_
<?php
include_once('2 9-4.php');
class German extends Localization
{
public function formatMoney($sum)
{
$text = "EUR " . number_format($sum, 2, '.'); return($text);
}
public function translate($phrase)

{

 if($phrase == 'yes') 
{
return('ja');
}
if($phrase == 'no')
{
return('nein');
}
return($phrase);
}
}

Одним из преимуществ этого типового проекта является отсутствие сложных условных конструкций. Один сценарий содержит все функциональные возможности, необходимые для форматирования отображения чисел во всех локальных системах. В противном случае потребовался бы оператор switch или дерево if-else. При этом также бы потребовалось проводить синтаксический анализ значительно большего кода, чем это может потребоваться для реальной работы какой-либо страницы.