0

我一直在使用教程来研究策略模式。我收到了他谈到的输出,但似乎没有使用 digHole() 方法的选项。当我在 Dog() 构造函数中调用该方法时,它可以工作。

我的猜测是发生这种情况是因为我需要实现一种方法来保存在 Animal 类中挖掘的能力(如飞行能力),我在这方面是否正确?这是否也意味着对于我想让动物采取的每一个动作,我都应该在 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";
    }

}
4

3 回答 3

2

我在制定策略模式背后的主要思想时也遇到了一些麻烦

或许了解Strategy 模式的最佳方法是将其与Template 方法进行比较。单击维基百科文章的链接。

两者都涉及基类中的某些设计决策,但是当最终确定为各种子类指定不同的行为时,模板模式依赖于继承——覆盖基类/超类中定义的抽象方法。

策略模式依赖于组合——行为(飞行、挖掘)本身就是一个对象,可以独立创建然后注入到感兴趣的对象中。

在像 Java 这样的语言中,一旦覆盖基类中的方法,然后创建对象的实例,该行为就永远不会改变。如果这就是你希望你的对象工作的方式 - 很好地使用继承。但是,如果您直到运行时才知道需要哪种行为,那么使用策略模式进行设计是值得的。

意味着该能力已实施或未实施?

尽管您参考的教程相当聪明,但它并不是使用策略模式的好模型。添加飞行到狗的能力是如此违反直觉,以至于分散了课程的注意力。使用策略模式,感兴趣的算法的可能实现的数量没有限制。

如果您真的想坚持使用 Animal 模型,您可以尝试更通用的概念,例如findFood, escapeFromPredator, findMate, raiseYoung- 这些概念对所有动物都有意义,但不会对每个动物实例都完全相同。随着时间的推移,两只不同的狗可能会raiseYoung完全不同,或者这样做会有所不同,因此随着动物模拟的继续,可能需要更换策略。

我是否必须在我的主类中编写每个方法

你可以,但如果它变得太乏味你不必这样做 - 为了简化你的类的使用,你可以让每个对象在它自己的构造函数中实例化一个适当的策略。然后您可以选择 - 创建对象并使用默认行为或根据应用程序将默认行为替换为另一个。

于 2012-12-10T22:44:54.453 回答
0

只需在Animal中创建抽象方法,Animal类也变得抽象,但我们不在乎,因为一般来说什么是动物,那是没有意义的。并且在每个继承 Animal 的类中定义该方法的实现。

这不是模式策略,但我认为这是做你想做的事的好方法之一(就像我理解的那样)

于 2012-12-10T22:03:07.320 回答
0

据我了解,模式策略的想法是子类以不同的方式定义相同行为。

所以如果你有一百种动物,有些只能飞,有些只能挖,有些可以两者兼得,那么你就有了这两者,fly并且digHole作为超类的方法。

digHole但是,这并不是将所有行为都组合到超类中-如果只有狗可以挖掘,而且对于一般动物来说甚至没有意义,那么Animal当你想要一个dog to dig,你可能应该知道它是否是 a Dog,或者如果你想从 to 移动AnimalDog例如从列表中取出所有的狗Animal)以便你可以使用该digHole方法,你可以使用显式演员表

于 2012-12-10T22:12:45.190 回答