Режим стратегии
источник
Режим СТРАТЕГИЯ в Delphi расширен на основе СТРАТЕГИИ. Дополнительную информацию о режиме СТРАТЕГИЯ см. на странице 208 «Шаблон проектирования».
Цель
Определите серию алгоритмов, инкапсулируйте их один за другим и сделайте взаимозаменяемыми. Этот шаблон делает алгоритм независимым от изменений в использующем его клиенте.
мотивация
? Различные стратегии могут быть динамически преобразованы по мере необходимости. ? Лучше инкапсулировать несколько структур поведения и алгоритмов, не позволяя клиентским программам напрямую вмешиваться? Выберите правильный метод поведения с помощью соответствующих условных операторов. Метод
Template использует наследование для преобразования частей алгоритма. Стратегии используют прокси и комбинации для преобразования всех алгоритмов и поддержки динамических преобразований. В будущем объект контекста будет использоваться для динамического выделения определенных алгоритмов во время выполнения. Аналогичным образом, при использовании объекта контекста клиентский класс будет отделен от интерфейса зависимого алгоритма, и через объект контекста могут быть предоставлены более обобщенные интерфейсы. В том же смысле, посредством
контекстных и
стратегических интерфейсов, в будущем могут быть разработаны и предоставлены общесистемные алгоритмы для реализации конкретных приложений без изменения интерфейсов.
Стратегии также позволяют создавать единую, простую и поддерживаемую структуру классов. Фреймворки классов полагаются на наследование.
приложение
Выполнение
В следующем примере рассчитывается ежемесячная процентная ставка по кредитной карте.
Режим стратегии инкапсулирует интерфейсы и обеспечивает доступ к ним через уникальный абстрактный класс TfinanzeCharge и предоставляет различные алгоритмы для расчета ежемесячных процентных ставок. TregularCharge и TPReferredCharge инкапсулируют различные конкретные алгоритмы расчета ежемесячной процентной ставки по кредитным картам. TmonthlyCharge реализует интерфейс TcontextCharge и настраивает различные объекты политики. TconntextCharge становится промежуточным механизмом клиентских объектов и объектов стратегии, что помогает уменьшить зависимость клиентских объектов и стратегий/объектов.
// Интерфейс стратегии ( абстрактный класс) TFinanzeCharge = class public // Возвращаем рассчитанный результат
function getCharge(const Balance: double end) ;
// Конкретная стратегия TRegularCharge = class(TFinanzeCharge) public
function getCharge(const; Balance: double): double; override ; end;
// Конкретная стратегия TPreferredCharge = class(TFinanzeCharge) public
function getCharge(const Balance: double): override; end;Клиентская программа использует контекстный интерфейс для планирования указанной стратегии. Однако, поскольку для клиентской программы создается контекстный интерфейс, клиентская программа должна знать доступные политики/объекты. Если контекст не может вернуть действительный экземпляр, вы можете выбрать реализацию метода со стратегией по умолчанию.
// Контекстный интерфейс TChargeContext = class public
function ComputeCharges(const Balance: double): double end // Конкретный класс контекста TmonthlyCharges служит механизмом промежуточного поля для объекта клиента и объекта стратегии и передается в него
; его конструктор. Устанавливается конкретный экземпляр расчета процентной ставки.
Этот класс действует как посредник между клиентом и классами стратегии и настраивается с помощью композиции и передачи экземпляра конкретного финансового платежа в его конструктор.
TMonthlyCharges = class(TChargeContext) Private FFinanzeCharge: TFinanzeCharge; public//
Функция интерфейса, к которой обращается клиентская программа ComputeCharges(const Balance: double): double; override; // конструктор настраивает конструктор объекта контекста Create(aFinanzeCharge: TFinanzeCharge virtual); Уничтожить; переопределить; --- реализация
// Функция TRegularCharge TRegularCharge.getCharge(const Balance: double): double;begin result := Balance * (REG_RATE / 12);end;
// функция TPreferredCharge TPreferredCharge.getCharge(const Balance: double): double;begin // это может быть комплекс. алгоритм, который учитывает // модели покупок владельца кредитной карты и накопленные бонусные баллы := Balance * (PREFERRED_RATE / 12);end;
// Concrete; Контекст // Конструктор TMonthlyCharges TMonthlyCharges.Create(aFinanzeCharge: TFinanzeCharge);begin inherited Create; // aFinanzeCharge настраивает объект контекста // этот класс становится владельцем aFinanzeCharge (уничтожит его) FFinanzeCharge := aFinanzeCharge;end;destructor TMonthlyCharges.Destroy; начать FFinanzeCharge.Free унаследовано; Уничтожить;конец;функция TMonthlyCharges.ComputeCharges(const Balance: double): double;begin result:= FFinanzeCharge.getCharge(Balance);end;
Пример Дельфи