JAVA中的策略模式

现在我们有一个虚基类-鸭子(abstract Duck). 有真鸭子,野鸭子,橡皮鸭子继承了该类。虚基类有swing方法,毕竟游泳是所有的鸭子都应有的功能。还有一个虚方法display,这个方法在子类中复写,毕竟每种鸭子的信息不一样。

现在我们有新的需求,需要让我们的鸭子会飞。那么我们可以轻松的想到,在Duck虚基类中增加一个fly方法就行了。但实际上,如果真这么做的话,会让所有的鸭子都有该功能。而实际上,橡皮鸭是不能飞的!那么,干脆我们不把fly方法写到基类,而是把fly方法抽象成接口,让需要该功能的类都实现这个接口。这样也会有问题,假如我们有更多种类的鸭子怎么办?我们是不是要为每一个新增的鸭子子类都实现这个接口呢?这样无疑给我们代码增加了很多维护成本,也降低了扩展性。

好的,是时候揭晓答案了。我们抽象出一个FlyBehavior接口,然后将各种飞行的方法抽象成不同的类,让不同的类都实现FlyBehavior借口。然后在我们的Duck虚基类中设置一个FlyBehavior属性,让鸭子具有这种功能。当我们在写子类的时候我们可以动态的决定该子类需要什么样的Fly方法。

代码如下:

FlyBehavior接口:

public interface FlyBehavior 
{
    void fly();
}

FlyWithWing子类实现FlyBehavior接口。该类代表正常的飞行能力。

public class FlyWithWing implements FlyBehavior 
{

    public void fly() 
    {
        // TODO Auto-generated method stub
        System.out.println("Fly with wing....");
    }

}

FlyNoWay子类实现FlyBehavior接口。该类代表没有飞行能力。

public class FlyNoWay implements FlyBehavior
{

    public void fly()
    {
        // TODO Auto-generated method stub
        System.out.println("Cannot fly.");
        //throw new Exception("can not fly");
    }
}

FlyWithRocketPower实现FlyBehavior接口。该类代表鸭子装上了火箭引擎的飞行能力。

public class FlyWithRocketPower implements FlyBehavior {

    public void fly() 
    {
        // TODO Auto-generated method stub
        System.out.println("Fly with a rocket power on");
    }

}

Duck虚基类:

public abstract class Duck 
{
    private FlyBehavior flyBehavior; 
    
    public Duck()
    {}
    
    public void fly()
    {
        this.flyBehavior.fly();
    }
 
    
    public void setFlyBehavior(FlyBehavior flyBehavior)
    {
        this.flyBehavior = flyBehavior;
    } 
    
    public void swing()
    {
        System.out.println("duck is swinging");
    }
    
    public abstract void display();
}

RealDuck类,继承了Duck类。真实的鸭子用翅膀飞。

public class RealDuck extends Duck 
{
    public RealDuck()
    {
        super.setFlyBehavior(new FlyWithWing()); 
    }
    
    
    @Override
    public void display() {
        // TODO Auto-generated method stub
        System.out.println("This is a real duck");
    }

}

RubberDuck类,继承了Duck类。橡皮鸭不能飞。

public class RubberDuck extends Duck 
{
    public RubberDuck()
    {
        super.setFlyBehavior(new FlyNoWay()); 
    }
    
    
    @Override
    public void display() 
    {
        // TODO Auto-generated method stub
        System.out.println("This is a rubber duck. it cannot fly nor quack.");
    }

}

SupperDuck类,继承了Duck类。超级鸭子能用火箭做动力。

public class SuperDuck extends Duck 
{
    public SuperDuck()
    {
        super.setFlyBehavior(new FlyWithRocketPower()); 
    }
    @Override
    public void display() 
    {
        // TODO Auto-generated method stub
        System.out.println("This is a super duck. It can fly with rocket power to the moon.");
    }
}

main函数,测试方法。实例化各种子类,然后还可以动态设置各个鸭子具有的功能。本例中,橡皮鸭一开始不能飞,但后来将其升级为用火箭做动力的鸭子。

public class DuckSimulator 
{
    public static void main(String[] args)
    {
        Duck realDuck = new RealDuck();
        realDuck.fly(); 
        realDuck.display();
        System.out.println("============================");
        
        
        RubberDuck rubberDuck = new RubberDuck();
        rubberDuck.fly(); 
        rubberDuck.display();
        System.out.println("============================");
        
        
        SuperDuck superDuck = new SuperDuck();
        superDuck.fly(); 
        superDuck.display();
        System.out.println("============================");
        
        //upgrade rubber duck to rocket power
        rubberDuck.setFlyBehavior(new FlyWithRocketPower());
        rubberDuck.fly();
    }
}

输出结果如下:
Fly with wing....
This is a real duck
============================
Cannot fly.
This is a rubber duck. it cannot fly nor quack.
============================
Fly with a rocket power on
This is a super duck. It can fly with rocket power to the moon.
============================
Fly with a rocket power on

原文地址:https://www.cnblogs.com/kuillldan/p/5616832.html