策略模式
定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立与使用算法的客户。
简单的来说策略模式把抽象基类的方法给独立出来,让使用者用的时候可以再去使用,而不是强制性要求实现。
我们设计一个鸭子类,我们都知道鸭子可以飞,也可以叫。所以我们定义一个Duck类,里面有三个方法
public abstract class Duck {
public abstract void display();
public abstract void fly();
public abstract void quack();
}
设计的这个Duck类是鸭子的基类,所有的鸭子都继承这个类,但是现在有个问题,就是鸭子有很多品种,有的鸭子会飞但是不会叫,有的鸭子会叫但是不会飞。而我们设计的这个基类再被继承的时候不管这些特性,都要求去实现,但是方法内部可以不做逻辑代码的编写。但是这样一来就增加了很多的空白方法,因为不会飞的鸭子就用不到fly,不会叫的鸭子就用不到quack方法。
我们需要找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。所以我们在这里需要用到策略者模式,不针对实现去编程,而是针对接口/超类去编程。首先设计鸭子这两个动作的接口FlyBehavior和QuackBehavior
public interface FlyBehavior {
void fly();
}
public interface QuackBehavior {
void quack();
}
设计好接口之后我们在针对接口去做具体的鸭子实现。实现出会飞、不会飞的鸭子类,会叫以及不会叫的鸭子类
public class FlyNoWay implements FlyBehavior {
@Override
public void fly(){
//什么都不做,不会飞
System.out.println("我不会飞");
}
}
public class FlyWithWings implements FlyBehavior {
@Override
public void fly(){
//实现鸭子飞行
System.out.println("我会飞");
}
}
public class MuteQuack implements QuackBehavior {
@Override
public void quack() {
//什么都不做,不会叫
System.out.println("我不会叫");
}
}
public class Quack implements QuackBehavior {
@Override
public void quack() {
//实现鸭子呱呱叫
System.out.println("鸭子呱呱叫");
}
}
public class Squeak implements QuackBehavior {
@Override
public void quack() {
//实现鸭子吱吱叫
System.out.println("鸭子吱吱叫");
}
}
然后再去设计Duck基类。首先定义两个动作的接口
public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior;
定义两个接口的调用方法
void performFly(){
flyBehavior.fly();
}
void performQuack() {
quackBehavior.quack();
}
以及定义一个显示的抽象方法
public abstract void display();
Duck类全部代码
public abstract class Duck {
public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior;
void performFly(){
flyBehavior.fly();
}
void performQuack() {
quackBehavior.quack();
}
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
public abstract void display();
}
接着,我们需要定义一个具体的鸭子类------MallardDuck,它是继承Duck类的。不过我们需要在这个类的构造函数中进行接口初始化赋值,我们需要确定这是一个什么样的鸭子,会不会叫以及会不会飞
public MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
然后复写基类中的display方法,在方法里面调用接口中的方法
public static void main(String args[]){
Duck mallardDuck = new MallardDuck();
mallardDuck.display();
}
MallardDuck类全部代码
public class MallardDuck extends Duck {
public MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
@Override
public void display(){
System.out.println("我是一只真鸭子");
quackBehavior.quack();
flyBehavior.fly();
}
public static void main(String args[]){
Duck mallardDuck = new MallardDuck();
mallardDuck.display();
}
}
到此,策略者模式已经结束。策略者模式提倡的是多用组合,少用继承。因为使用组合建立系统具有很大的弹性,不仅可以讲算法族封装成类,更可以“在运行时动态地改变行嘞”,只要组合的行为对象符合正确的接口标准即可