策略模式定义:分别封装行为接口,实现算法族,超类里放行为接口的对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者。
好处:新增行为简单,行为类更好的复用,组合更方便。既有继承带来的复用好处,没有挖坑
闲话少说上代码:
定义一个飞行接口,里面有一个没有方法体的飞行动作:
- public interface Fly {
- void fly();
- }
定义一个叫接口,里面有一个没有方法体的叫动作:
- public interface Call {
- void call();
- }
因为飞行和叫声是变化的,会有各种各样的飞行和叫声,所以我们要把不同的飞行和叫声都实现
- public class GoodFly implements Fly {
- @Override
- public void fly() {
- System.out.println("飞的好");
- }
- }
- public class BadFly implements Fly {
- @Override
- public void fly() {
- System.out.println("飞的坏");
- }
- }
- public class GuaCall implements Call {
- @Override
- public void call() {
- System.out.println("呱呱叫");
- }
- }
- public class GaCall implements Call {
- @Override
- public void call() {
- System.out.println("嘎嘎叫");
- }
- }
这样我们就有了各种各样的飞行和叫声。
然后我们要创建鸭子的超类,超类会持有动作的接口但是没有声明具体的动作
- public abstract class Duck {
- Fly dfly;
- Call dcall;
- public Duck(){}
- public void fly(){
- dfly.fly();
- }
- public void call(){
- dcall.call();
- }
- }
在超类的子类中会具体设置是哪一种动作
- class GreenHeadDuck extends Duck{
- public GreenHeadDuck(){
- dcall=new GaCall();
- dfly=new GoodFly();
- }
- }
- public class RedHeadDuck extends Duck {
- public RedHeadDuck(){
- dfly=new BadFly();
- dcall=new GuaCall();
- }
- public static void main(String[] args) {
- Duck rduck=new RedHeadDuck();
- rduck.fly();
- rduck.call();
- Duck gduck=new GreenHeadDuck();
- gduck.fly();
- gduck.call();
- }
- }
策略模式的注意点:
- 分析项目中变化部分与不变部分
- 多用组合少用继承;用行为类组合,而不是行为的继承。更有弹性