Strategia

Wzorzec strategi
Mały opis i trochę przykładowego kodu na temat wzorca strategii.
Mając klasę abstrakcyjną pojazdów z bardzo sprytną funkcją "go" implementujemy sobie różne pojazdy, dziedziczące po Vehicle.
    public abstract class Vehicle
    {
        public Vehicle() { }
        public virtual string go()
        { return "Jadę"; }
    }

    public class Car: Vehicle
    {
        public Car() { }
    }

    public class Helicopter : Vehicle
    {
        public Helicopter() { }
    }

    public class Jet: Vehicle
    {
        public Jet() { }
    }
Pojawia się problem że tak naprawdę funkcyjka go jest oderwana od rzeczywistości bo helikoptery nie jeżdżą tylko latają.
To co możemy zrobić to przeciążenie funkcji go:
public class Helicopter : Vehicle
    {
        public Helicopter() { }
        public override string go()
        {
            return "Lecę";
        } 
    }

Pojawia się problem który wymusił powstanie wzorca strategi.
Jeśli będziemy przeciążać każdą potrzebną funkcję oczywiście uzyskamy pożądany efekt, jednak po pewnym czasie stworzy się bardzo dużo generacji dziedziczenia i wersji obiektów - co w linii prostej prowadzi do trudnego i żmudnego utrzymania kodu.
Wzorzec strategi sugeruje aby używać obiektu ze zmienna algorytmu. Pomysł opiera się na wyizolowaniu 'drażliwego' kodu do obiektów algorytmów. Wewnątrz klasy poprzez zmienna algorytmu możliwe jest używanie różnych obiektów algorytmów.

To inne spojrzenie na programowanie obiektowe. Używając strategi mamy do czynienia ze związkiem 'has a' czyli 'posiada' obiekt, a nie 'is a' czyli 'jest' danego typu (w hierarchii dziedziczenia).

Teraz przepiszmy ten prosty przykład z pojazdami zgodnie z wytycznymi strategii.
    public interface GoAlgorith
    {
        public string go();
    }

    public class GoByDrivingAlgorithm : GoAlgorith
    {
        public string go()
        { return "Jadę"; }
    }

    public class GoByFlying : GoAlgorith
    {
        public string go()
        { return "Lecę"; }
    }
    public class GoByFlyingFast : GoAlgorith
    {
        public string go()
        { return "Lecę szybciutko"; }
    }
//-------------------------------------
    public abstract class Vehicle
    {
        public Vehicle() { }
        private GoAlgorith goAlgorithm;
        public void setGoAlgorithm(GoAlgorith algorithm)
        { goAlgorithm = algorithm; }

        public virtual string go()
        { return goAlgorithm.go(); }
    }

    public class Car : Vehicle
    {
        public Car() { setGoAlgorithm(new GoByDrivingAlgorithm()); }
    }

    public class Helicopter : Vehicle
    {
        public Helicopter() { setGoAlgorithm(new GoByFlying();}
    }

    public class Jet : Vehicle
    {
        public Jet() {setGoAlgorithm(new GoByFlyingFast(); }
    }

Klasy Car, Helicopter i Jet przechowują konkretny algorytm będący kontekstem do strategii. Ze względu na wybór algorytmu wykonywane mogą być różne czynności.

Komentarze

Popularne posty