设计模式——策略模式

1. 什么是策略模式

策略模式(Strategy)属于对象行为型设计模式。主要是定义一系列的算法,把这些算
法一个个封装成拥有共同接口的单独的类,并且使它们之间可以互换
。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化

例:甲乙两人在不同的地点,去同一个电影院看电影,他们有共同的属性(包括姓名、性别、到影院的时间等),此时到影院的时间计算方式(甲步行,乙驾车),即为策略模式所描述的算法。

2. 策略模式角色

策略使用环境角色(Context):策略被引用到这里和一些其它的与环境有关的操作一起来完成任务。
抽象策略角色(Strategy):规定了所有具体策略角色所需的接口。通常由接口或者抽象类来实现。
具体策略角色(Concrete Strategy):实现抽象策略角色定义的接口的具体策略。

三者关系图

3. 什么时候使用

  • 系统需要能够在几种算法中快速的切换。
  • 系统中有一些类它们仅行为不同时,可以考虑采用策略模式来进行重构
  • 系统中存在多重条件选择语句时,可以考虑采用策略模式来重构。

4. 策略模式优缺点

优点:

  • 策略模式符合开闭原则。
  • 避免使用多重条件转移语句,如if...else...语句、switch 语句
  • 使用策略模式可以提高算法的保密性和安全性。

缺点:

  • 客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
  • 代码中会产生非常多策略类,增加维护难度。

5. 策略模式举例代码

策略使用环境角色(Context)

package design.model;

import design.behavior.CallBehavior;
import design.behavior.MoveBehavior;

public class Animal {

    /**
     * 名字
     */
    private String name;

    /**
     * 身高
     */
    private Double height;

    /**
     * 体重
     */
    private Double weight;

    /**
     * 颜色
     */
    private String color;

    /**
     * 移动方式
     */
    private MoveBehavior moveBehavior;

    /**
     * 叫声
     */
    private CallBehavior callBehavior;

    public Animal() {

    }

    public Animal(String name, Double height, Double weight, String color, MoveBehavior moveBehavior, CallBehavior callBehavior) {
        this.name = name;
        this.height = height;
        this.weight = weight;
        this.color = color;
        this.moveBehavior = moveBehavior;
        this.callBehavior = callBehavior;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    public Double getWeight() {
        return weight;
    }

    public void setWeight(Double weight) {
        this.weight = weight;
    }

    public String getColorEnum() {
        return color;
    }

    public void setColorEnum(String colorEnum) {
        this.color = colorEnum;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name=" + name  +
                ", height=" + height +
                ", weight=" + weight +
                ", color=" + color +
                ", moveWay=" + moveBehavior.moveWay() +
                ", callWay=" + callBehavior.callWay() +
                '}';
    }

}

抽象策略角色(Strategy)

package design.behavior;

public interface CallBehavior {
    String callWay();
}
package design.behavior;

public interface MoveBehavior {
    String moveWay();
}

具体策略角色(Concrete Strategy):

package design.behavior.impl;

import design.behavior.CallBehavior;

public class JiJiCall implements CallBehavior {
    @Override
    public String callWay() {
        // 业务逻辑
        return "叫声为叽叽";
    }
}
package design.behavior.impl;

import design.behavior.CallBehavior;

public class WoWoCall implements CallBehavior {
    @Override
    public String callWay() {
        // 业务逻辑
        return "叫声为喔喔";
    }
}
package design.behavior.impl;

import design.behavior.MoveBehavior;

public class CreepWay implements MoveBehavior {
    @Override
    public String moveWay() {
        // 业务逻辑
       return "移动方式为爬行";
    }
}
package design.behavior.impl;

import design.behavior.MoveBehavior;

public class FlyWay implements MoveBehavior {
    @Override
    public String moveWay() {
        // 业务逻辑
        return "移动方式为飞行";
    }
}
package design.behavior.impl;

import design.behavior.MoveBehavior;

public class WalkWay implements MoveBehavior {
    @Override
    public String moveWay() {
        // 业务逻辑
        return "移动方式为行走";
    }
}

测试代码

package design.model;

import design.behavior.CallBehavior;
import design.behavior.MoveBehavior;

public class Bird extends Animal {

    public Bird() { }

    public Bird(String name, Double height, Double weight, String colorEnum, MoveBehavior moveBehavior, CallBehavior callBehavior) {
        super(name, height, weight, colorEnum, moveBehavior, callBehavior);
    }

}
package design.model;

import design.behavior.CallBehavior;
import design.behavior.MoveBehavior;

public class Monkey extends Animal{

    public Monkey() { }

    public Monkey(String name, Double height, Double weight, String color, MoveBehavior moveBehavior, CallBehavior callBehavior) {
        super(name, height, weight, color, moveBehavior, callBehavior);
    }
}
package design.test;

import design.behavior.impl.FlyWay;
import design.behavior.impl.JiJiCall;
import design.behavior.impl.WalkWay;
import design.behavior.impl.WoWoCall;
import design.model.Animal;
import design.model.Bird;
import design.model.Monkey;

public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1 = new Monkey("金丝猴", 120d, 5d, "金色", new WalkWay(), new WoWoCall());
        System.out.println(animal1);
        System.out.println("----------------");
        Animal animal2 = new Bird("燕子", 10d, 0.3d, "白色", new FlyWay(), new JiJiCall());
        System.out.println(animal2);
    }
}
// 控制台打印:

Animal{name=金丝猴, height=120.0, weight=5.0, color=金色, moveWay=移动方式为行走, callWay=叫声为喔喔}
----------------
Animal{name=燕子, height=10.0, weight=0.3, color=白色, moveWay=移动方式为飞行, callWay=叫声为叽叽}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容