一、模式介绍
1.1、定义
定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。策略模式属于对象行为型模式。
1.2、优点
- 条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if…else 语句,switch…case 语句
- 提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码迁移至父类,从而避免重复的代码
- 可以提供相同的行为的不同实现,客户可以根据不同时间或空间要求选择不同的策略
- 提供了对开闭原则的完美支持,可以在不修改源代码的情况下,灵活增加新算法
- 把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了两者分离
1.3、缺点
- 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类
- 策略模式造成很多的策略类,增加维护难度
二、结构与实现
2.1、结构
- 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
2.2、实现
2.2.1、类图
将每组的行为想象成一个算法族,这些算法(行为)是可以互换的,客户使用封装好的算法族。
2.2.2、Duck
package com.erlang.strategy;
/**
* @description: 鸭子抽象类
* @author: erlang
* @since: 2022-02-16 08:59
*/
public abstract class Duck {
FlyBehavior flyBehavior;
/**
* 展示
*/
public abstract void display();
/**
* 飞的行为
*/
public void performFly () {
flyBehavior.fly();
}
/**
* 游泳
*/
public void swim() {
System.out.println("All ducks float, even decoys!");
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
}
2.2.3、MallardDuck
package com.erlang.strategy;
/**
* @description: 野鸭子
* @author: erlang
* @since: 2022-02-16 09:06
*/
public class MallardDuck extends Duck {
public MallardDuck() {
flyBehavior = new FlyWithWings();
}
@Override
public void display() {
System.out.println("I'm a mallard duck!");
}
}
2.2.4、ModelDuck
package com.erlang.strategy;
/**
* @description: 模型鸭
* @author: erlang
* @since: 2022-02-16 09:08
*/
public class ModelDuck extends Duck {
public ModelDuck() {
flyBehavior = new FlyNoWay();
}
@Override
public void display() {
System.out.println("I'm a model duck");
}
}
2.2.5、FlyBehavior
package com.erlang.strategy;
/**
* @description: 鸭子飞的行为
* @author: erlang
* @since: 2022-02-16 09:01
*/
public interface FlyBehavior {
/**
* 飞的行为
*/
void fly();
}
2.2.6、FlyNoWay
package com.erlang.strategy;
/**
* @description: 不会飞的行为
* @author: erlang
* @since: 2022-02-16 09:03
*/
public class FlyNoWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("I can't fly!");
}
}
2.2.7、FlyWithWings
package com.erlang.strategy;
/**
* @description: 用翅膀飞
* @author: erlang
* @since: 2022-02-16 09:05
*/
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying with wings!");
}
}
2.2.8、MiniDuckSimulator
package com.erlang.strategy;
/**
* @description: 鸭子模拟器,客户端调用
* @author: erlang
* @since: 2022-02-16 09:08
*/
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.display();
mallard.performFly();
System.out.println("\r\r\r");
Duck model = new ModelDuck();
model.display();
model.performFly();
model.setFlyBehavior(new FlyNoWay());
model.performFly();
}
}
2.2.9、运行结果
I'm a mallard duck!
I'm flying with wings!
I'm a model duck
I can't fly!
I can't fly!