JavaRush /Blog Java /Random-PL /Strategia szablonowa (strategia)

Strategia szablonowa (strategia)

Opublikowano w grupie Random-PL
Wzorzec Strategii definiuje rodzinę algorytmów, hermetyzuje każdy z nich i zapewnia ich wymienność. Pozwala na modyfikację algorytmów niezależnie od ich wykorzystania po stronie klienta (definicja ta została zaczerpnięta z książki „Head First. Design Patterns” autorstwa Erica Freemana i Elizabeth Robson). Definicja ta wygląda na nieco zagmatwaną, dlatego musimy wyjaśnić ją bardziej szczegółowo w normalnym języku . Zacznijmy od religii :) Na świecie istnieje wiele religii (wyznania, ruchy, wierzenia itp.). Jak moglibyśmy opisać to w kodzie. Cóż, na przykład moglibyśmy wziąć lekcję Religii i odziedziczyć po niej inne religie. Wyodrębnijmy niepotrzebne rzeczy i użyjmy jednej metody Believe() w klasie Religion.
public abstract class Religion {
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
Wszystkie inne religie mogą być dziedziczone po tej klasie. Gdybyśmy ograniczyli się do chrześcijaństwa, a nawet islamu i judaizmu, nie byłoby problemów.
public class Judaism extends Religion {
}
public class Islam extends Religion {
}
public class Christianity extends Religion {
}
Ale jeśli pomyślisz o innych religiach, które istnieją obecnie (lub istniały wcześniej, ale zniknęły), pojawią się problemy, przynajmniej w przypadku buddystów. Będziesz musiał zastąpić ich metodę wiary.
public class Buddhism extends Religion {
    @Override
    public void believe() {
        System.out.println("Есть Бог Lub боги Lub нет, это не важно, главное достичь нирваны :)");
    };
}
A ponieważ istnieje wiele religii, a one nawet wierzą w potwora z makaronu (pastafarianizm), to we wszystkich tych religiach trzeba będzie na nowo zdefiniować metodę wiary. Ale czy możemy zrobić to inaczej, przenieść tę metodę do interfejsu Faith i zaimplementować w niej metodę Believe i zaimplementować tę metodę w każdej klasie (i odpowiednio zaimplementować ją w każdej klasie, jak sobie życzymy)? Ale wtedy otrzymamy powielanie kodu, cóż, przynajmniej wśród Żydów i chrześcijan. Muzułmanie Boga potrafią pisać po arabsku.
public interface Faith {
    public void believe();
}
public class Christianity implements Faith {
    @Override
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
public class Judaism implements Faith {
    @Override
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
Implementacja metody domyślnej tutaj niewiele pomoże; religii jest tak wiele, że nawet jeśli domyślnie zdefiniujesz tę metodę w interfejsie Faith, będziesz musiał zaimplementować tę metodę po swojemu we wszystkich religiach niemonoteistycznych i powtarzać ją gdzieś. Co w tym przypadku oferuje nam wzorzec Strategy: oferuje utworzenie gotowych klas szablonowych dla bieżącego interfejsu, które następnie zostaną podstawione w konstruktorze konkretnej religii. Te. zdefiniuj i utwórz tę samą rodzinę algorytmów, o której mowa na początku definicji.
public interface Faith {
    public void believe();
}
public class AbrahamicReligion implements Faith {
    @Override
    public void believe() {
        System.out.println("Я верю в Бога-творца этого мира");
    }
}
public class BuddismReligion implements Faith {
    @Override
    public void believe() {
        System.out.println("Есть Бог Lub боги Lub нет, это не важно, главное достичь нирваны :)");
    }
}
public class JediismReligion implements Faith {
    @Override
    public void believe() {
        System.out.println("Да пребудет с вами Сила!");
    }
}
I w każdej klasie konstruktora zastąp je.
public abstract class Religion {
    Faith faith;
}
public class Judaism extends Religion{

    public Judaism() {
        this.faith = new AbrahamicReligion();
    }
}
public class Christianity extends Religion{

    public Christianity() {
        this.faith = new AbrahamicReligion();
    }
}
public class Buddhism extends Religion {

    public Buddhism() {
        this.faith = new BuddismReligion();
    }
}
Zatem, jeśli zajdzie potrzeba włączenia do projektu innej religii, nie będzie konieczności ponownego definiowania metody wiary dla wszystkich klas lub części klas. Będziesz musiał jedynie zaimplementować brakującą klasę (jeśli już jej nie ma), która implementuje interfejs Faith i dodać tę klasę w konstruktorze nowej religii.
public class PastafarianismReligion implements Faith{

    @Override
    public void believe() {
        System.out.println("Кто съел мои макароны???");
    }
}
public class Pastafarianism extends Religion {

    public Pastafarianism() {
        this.faith = new PastafarianismReligion();
    }
}
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION