Нужно ли составлять каждый метод в моем основном классе, чтобы использовать его (шаблон стратегии)?

Я использовал этот учебник, чтобы изучить шаблон Стратегии. Я получаю вывод, о котором он говорит, но, похоже, нет возможности использовать метод digHole(). Когда я вызываю метод в конструкторе Dog(), он работает.

Я предполагаю, что это происходит потому, что мне нужно реализовать способ сохранить способность копать в классе животных (например, способность летать), я прав в этом? Означает ли это также, что для каждого действия, которое я хочу выполнить с животным, я должен составить его в классе Animal, создать интерфейс со способностью, а затем создать два класса, которые реализуют эту способность, то есть способность либо реализована, либо нет? т?

У меня также есть некоторые проблемы с формулировкой основной идеи, лежащей в основе стратегии. В настоящее время я рассматриваю это как "Инкапсулировать все действия и объединить их в один основной класс". Насколько это точно / подходит?

public class Animal {

    public Flies flyingType;

    public String tryToFly() {
        return flyingType.fly();
    }

    public void setFlyingAbility(Flies newFlyType) {
        flyingType = newFlyType;
    }
}


public class Dog extends Animal {

    public Dog() {
        super();
        setSound("Bark");
        flyingType = new CantFly();
    }

    public void digHole() {
        System.out.println("Dug a hole");
    }
}


public interface Flies {

    String fly();

}

class ItFlies implements Flies {

    public String fly() {
        return "Flying high";
    }

}
class CantFly implements Flies {

    public String fly() {
        return "I can't fly";
    }

}

3 ответа

Решение

У меня также есть некоторые проблемы с формулировкой основной идеи, лежащей в основе стратегии.

Возможно, лучший способ обернуть голову вокруг шаблона "Стратегия" - сравнить его с методом "Шаблон". Нажмите на ссылки для статей википедии.

Оба предусматривают определенные конструктивные решения на начальном этапе в базовом классе, но когда, наконец, приступают к определению различного поведения для различных подклассов, шаблон шаблона опирается на наследование - переопределяя абстрактный метод, определенный в базовом / суперклассе.

Паттерн стратегии опирается на композицию - поведение (полет, копание) само по себе является объектом, который может быть создан независимо, а затем введен в объект интереса.

В таком языке, как Java, после переопределения метода в базовом классе и создания экземпляра объекта это поведение никогда не изменится. Если вы хотите, чтобы ваш объект работал, используйте наследование. Однако, если вы не знаете до времени выполнения, какое поведение вам понадобится, тогда стоит потратить дополнительные усилия на разработку с использованием шаблона стратегии.

имеется ввиду способность реализована или нет?

Хотя учебник, на который вы ссылаетесь, довольно умен, он не является хорошей моделью для использования паттерна стратегии. Добавление способности летать с собакой настолько нелогично, что отвлекает от урока. В паттерне стратегии нет ограничений на количество возможных реализаций интересующего алгоритма.

Если вы действительно хотите придерживаться модели Animal, вы можете попробовать более универсальные концепции, такие как findFood, escapeFromPredator, findMate, raiseYoung - вещи, которые имеют значение для всех животных, но не будут одинаковыми для каждого животного. Два разных собачьего могущества raiseYoung совсем по-другому или делайте это по-разному с течением времени, поэтому стратегию, возможно, придется поменять местами по мере продолжения симуляции животных.

Должен ли я составить каждый метод в моем основном классе

Вы можете, но не обязаны, если это становится слишком утомительным - чтобы упростить использование ваших классов, вы можете заставить каждый объект создавать соответствующую стратегию в своем собственном конструкторе. Тогда у вас есть выбор - создать объект и использовать поведение по умолчанию или заменить поведение по умолчанию другим в зависимости от приложения.

Идея шаблонной стратегии, насколько я понимаю, состоит в том, что подклассы определяют один и тот же тип поведения по-разному.

Так что если у вас есть сто видов животных, и некоторые из них могут только летать, некоторые из них могут только копать, а некоторые могут делать и то и другое, у вас есть оба fly а также digHole как методы на суперклассе.

Дело не в том, чтобы объединить все поведение в суперкласс, хотя - если только собаки могут копать, и это вообще не имеет смысла для животных, тогда вам не имеет смысла ставить digHole в Animal - когда вы хотите, чтобы собака копала, вы, вероятно, должны знать, является ли она Dog в любом случае, или если вы хотите перейти от Animal в Dog (например, чтобы вытащить всех собак из Animal список), так что вы можете использовать digHole метод, вы можете использовать явное приведение

Просто создайте абстрактный метод в Animal, чтобы класс Animal тоже стал абстрактным, но нам все равно, потому что это вообще животное, в этом нет никакого смысла. И в каждом классе, который наследует Animal, определяют реализацию этого метода.

Это не шаблонная стратегия, но я думаю, что это один из хороших способов сделать то, что вы хотите (как я понял)

Другие вопросы по тегам