→ Пошук по сайту       Увійти / Зареєструватися
Знання Патерни Патерни поведінки — Behavioral patterns

21. Стратегія — Strategy

21.	Стратегія — Strategy

Просто, як двері — якщо на дворі дощ, то ви берете парасольку і куртку, а якщо палить сонце, то ви берете футболку і сонцезахисні окуляри. Що вдягати є вашою стратегією, яку ви змінюєте залежно від обставин. Але замість того, щоб дивитися за вікно яка погода, а потім мандрувати до шафки із одягом і вибирати що одягнути, а далі, пам’ятаючи яка погода, йти до іншої шафки і брати парасольку або окуляри, ви просто піднімаєтеся із ліжка протираєте очі і вам у руки жінка (чоловік, що малоімовірно) подає потрібний одяг і аксесуари. Іншими словами, стратегія на сьогоднішній день просто була подана і ви нею скористалися.

Стратегія зберігає сім’ю алгоритмів і дозволяє змінювати їх незалежно та переключатися між ними.

Розглянемо два підходи до вирішення цієї проблеми. Припустимо, що в класі Myself ми маємо метод для походу на вулицю GoOutside() в якому ми вибираємо собі одяг і «шуруємо» на вулицю.

 
 
 

Уривок коду 21.1. Спосіб 1. Клас Myself із «мудрим» методом GoOutside

 class Myself
{
    public void GoOutside()
    {
        var weather = Weather.GetWeather();
        string clothes = GetClothes(weather);
        string accessories = GetAccessories(weather);
        Console.WriteLine("Today I wore {0} and took {1}", clothes, accessories);
    }
    private string GetAccessories(string weather)
    {
        string accessories;
        switch (weather)
        {
            case "sun":
                accessories = "sunglasses";
                break;
            case "rain":
                accessories = "umbrella";
                break;
            default:
                accessories = "nothing";
                break;
        }
        return accessories;
    }


    private string GetClothes(string weather)
    {
        string clothes;
        switch (weather)
        {
            case "sun":
                clothes = "T-Shirt";
                break;
            case "rain":
                clothes = "Coat";
                break;
            default:
                clothes = "Shirt";
                break;
        }
        return clothes;
    }
}

Воно звичайно добре, але як тільки вам треба буде підлаштовуватися до снігу, що несподівано випав, вам прийдеться додати ще один case в трьохстах місцях. З однієї сторони це не складно, але з іншої, з часом це може вас «дістати». Також з часом код із методом GoOutside() вже не можна буде змінювати із-за певних причин. Що тоді?
Вище наводився приклад із switch для того, щоб показати, що Стратегія — це елегантний спосіб позбутися цього «чудіща».

Уривок коду 21.2. Спосіб 2. Вирішення проблеми за допомогою Стратегії

 class Myself
{
    private IWearingStrategy _wearingStrategy = new DefaultWearingStrategy();

    public void ChangeStrategy(IWearingStrategy wearingStrategy)
    {
        _wearingStrategy = wearingStrategy;
    }
    public void GoOutside()
    {
        var clothes = _wearingStrategy.GetClothes();
        var accessories = _wearingStrategy.GetAccessories();
        Console.WriteLine("Today I wore {0} and took {1}", clothes, accessories);
    }
}

Як бачимо, ми маємо інтерфейс стратегії із двома методами. Глянемо, як виглядає стратегія на сонячний день:

Уривок коду 21.3. Сонячна стратегія

 interface IWearingStrategy
{
    string GetClothes();
    string GetAccessories();
}




class SunshineWearingStrategy : IWearingStrategy
{
    public string GetClothes()
    {
        return "T-Shirt";
    }

    public string GetAccessories()
    {
        return "sunglasses";
    }
}

Все, що нам залишилося, то це правильно проставити стратегію. Ага! Все одно хтось буде змушений поставити правильну стратегію (жінка, яка встала ранше і глянула у вікно, це вона може зробити ще одним свічом, про який ви нічого не знаєте).

Уривок коду 21.4. Елегантне надання об’єкту класу Myself стратегії

 var me = new Myself();
me.ChangeStrategy(new RainWearingStrategy());
me.GoOutside();

Вивід простий:

 Today I wore Coat and took umbrella

Ще одним (але не моїм) гарним прикладом є зміна стратегії сортування списку в залежності від його розміру. Всі ми знаємо що для малої кількості даних достатньо сортування вставками або якийсь інший простий спосіб. Для відносно великих списків найоптимальніше використовувати швидке сортування, а для дуже великої кількості даних — пірамідальне. Так от, алгоритм зберігається у своєму класі і в залежності від кількості елементів ми просто міняємо реалізацію алгоритму.

По матеріалам книги Андрія Будая "Дизайн патерни – просто, як двері". Матеріал розміщується за домовленістю з автором.
Робота представлена за умовами ліцензії Creative Commons Attribution-NonCommercial 3.0 Unported License.

загрузка...
Сторінки, близькі за змістом