策略模式
案例:我们需要创建一个duck抽象类代表鸭子类,抽象类中含有一个抽象方法,如fly()/swim()/eat()等方法。然后我们有几种类型的鸭子:北京鸭、玩具鸭、野鸭子,分别继承Duck类并实现几种方法。
存在的问题:每种鸭子都有自己的特色,有的鸭子不能飞翔,有的不能游泳…而继承父类就是继承所有方法。此时可以使用策略模式实现。
假设所有鸭子都能游泳,而有的不能飞翔,eat吃的食物也不同。
我们可以将游泳方法写在抽象类中,因为所有鸭子都有的功能。而飞翔和eat可以使用两个接口,每个接口可以有不同的实现,在抽象类中,有这些接口的成员变量。我们创建不同的鸭子时,传入不同的接口就可以任意的组合这些鸭子特点。
1)创建一个fly行为接口FlyBehavior
。
public interface FlyBehavior {
void fly();
}
2)创建一个eat行为的接口EatBehavior
。
public interface EatBehavior {
void eat();
}
3)对FlyBehavior
和EatBehavior
两个接口做一个实现类。如NoFlyBehavior、BadFlyBehavior、RiceEatBehavior。
public class GoodFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("擅长飞翔");
}
}
4)创建Duck鸭子抽象类。包含两个行为接口属性,用于在定义具体鸭子类时传参。
import strategy.eat.EatBehavior;
import strategy.fly.FlyBehavior;
public abstract class Duck {
//属性,策略接口
FlyBehavior flyBehavior;
EatBehavior eatBehavior;
public void swim(){
System.out.println("鸭子都会游泳");
}
public void fly(){
if(flyBehavior != null)
flyBehavior.fly();
}
public void eat(){
if(eatBehavior != null)
eatBehavior.eat();
}
public abstract void display();
}
5)具体子类具体鸭子类的编写
public class WildDuck extends Duck {
public WildDuck(){
flyBehavior = new GoodFlyBehavior(); //为WildDuck类型的鸭子赋予GoodFlyBehavior属性
eatBehavior = new RiceEatBehavior();
}
@Override
public void display() {
System.out.println("这是野鸭");
}
}
6)测试
public static void main(String[] args) {
WildDuck wildDuck = new WildDuck();
wildDuck.display();
wildDuck.fly();
wildDuck.eat();
}
策略模式在JDK中的应用
Arrays工具类中的sort() 方法就用到了策略模式,sort方法有一个Comparator接口作为参数,表示排序的方式。
Comparator
就是策略接口。