这是策略模式(JAVA,鸭子的飞行方法)的正确实现吗?

Is this a correct implementation of the strategy pattern (JAVA, Fly method of ducks)?

我只想快速浏览一下我是否正确实施了不同的飞行策略。

该程序仅由一个 duck class 组成,它使用 接口 作为其 fly 方法。该接口有不同的实现(即 SimpleFlyNoFly),switch 语句根据特定枚举选择正确的方法。

据我了解,策略模式旨在避免同一级别的子 class 之间重复代码,从而降低可维护性和可扩展性。因此,我们改为将相关算法抽象为接口并根据需要选择它们。

代码:

package DesignPatterns;

//Here we will separate the fly method of ducks into implementations of an internface and then instantiate ducks with those attributes

interface IFly {
    
    public void fly();
    
}

//These are called strategies
class SimpleFly implements IFly {

    @Override
    public void fly() {
        System.out.println("Quack Quack i am flying in the air");
    }
    
}

class NoFly implements IFly {
    
    @Override
    public void fly() {
        System.out.println("I cannot fly.");
    }
    
}

//Now the base class just has to implement one of these strategies
class Duck {
    
    private IFly flyType;
    
    public enum SPECIE {
        WILD, CITY, RUBBER
    }
    
    public Duck(SPECIE specie) {
        switch(specie) {
            
            //Here just select the algorithms you want to assign to each type of DUCK. More flexible than horizontal code between species.
            case WILD:
            case CITY:
                this.flyType = new SimpleFly();
                break;
            case RUBBER:
                this.flyType = new NoFly();
                break;
            default:
                //If a new enum is defined but no definition yet, this stops code from breaking
                this.flyType = new SimpleFly();
        }
    }
    
    public void fly() {
        flyType.fly();
    }
    
}

本例中的输出是正确的:

        Duck rubberDuck = new Duck(Duck.SPECIE.RUBBER);
        Duck normalDuck = new Duck(Duck.SPECIE.WILD);
        
        rubberDuck.fly();
        normalDuck.fly();

产量:

I cannot fly.
Quack Quack i am flying in the air

在此先感谢您,如果我的知识有任何不足,请告诉我, 沙瓦玛

我要指出几个语义和术语问题。

  • 令人困惑的是有一个名为 fly 的方法可以实现为 not 飞行。将方法命名为 tryToFly 或仅将方法记录为尝试是解决这种混淆的两种方法。这里参考的软件原理是Liskov Substitution
  • 基础 class 没有 实施 其中一项策略;相反,它 构成了 一种策略。策略模式的目的是避免通过组合进行子classing。
  • 重申其中一条评论,Duck 应该在其构造函数(或 setter 方法)中直接接受 IFly 的实例,而不是打开枚举。策略模式的另一个目标是避免分支逻辑。

该模式的本质是您通过创建 IFly 的多个实现来避免创建 Duck 的多个子 classes。这样做的好处是那些 IFly 实现可以在没有复杂继承层次结构的情况下被重用,例如WILDCITY 可以共享一个策略。

如评论中所述,策略还有一个优点,即 Duck 可以在运行时更改其策略。例如,IFly 可能由 SoarGlide 实施,因此 Duck 会根据风在这些不同的策略之间切换。