设计模式之----策略模式
程序员文章站
2022-06-13 13:09:02
...
设计模式之策略模式
- 策略模式定义
- 策略模式关键以及优缺点
- 策略模式使用场景以及注意事项
- 策略模式案例一
- 策略模式案例二
策略模式定义
- 分别分装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象,原则就是: 分离变化部分,封装接口,基于接口编程各种功能。 此模式让行为算法的变化独立于算法的使用者。
- 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。主要解决的是在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
策略模式关键以及优缺点
- 关键在于多个不同的行为实现同一个接口;
- 优点: 1、算法可以*切换。 2、避免使用多重条件判断。 3、扩展性良好。
- 缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
策略模式使用场景以及注意事项
使用场景
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为;
- 一个系统需要动态地在几种算法中选择一种;
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项
如果一个系统的策略有多个,就需要考虑使用混合模式,解决策略类膨胀的问题。
策略模式案例一
这个案例模拟的是各种鸭子以及他们的行为,比如有红头鸭,绿头鸭,他们各自都有不同的行为,比如红头鸭飞的不好,会”GeGe”叫,而绿头鸭飞的好,会”GaGa”叫,使用策略模式实现下面的功能;
看下面的设计类图
其中Duck类是超类,下面有子类红头鸭和绿头鸭,而每个行为都成为一个接口,并且相应的有实现类,这些实现类就是算法族。看类结构
首先鸭子包:
Duck类
package strategy.duck;
import strategy.fly.FlyBehavior;
import strategy.quack.QuackBehavior;
/**
* 鸭子的超类
*/
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public void fly(){
flyBehavior.fly();
}
public void quack(){
quackBehavior.quack();
}
public abstract void display(); //抽象方法,子类必须实现
public void swim(){//父类的方法 公用
System.out.println("I'm Swim");
}
//动态的改变 setter方法
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
红头鸭的类:
package strategy.duck;
import strategy.fly.BadFlyBehavior;
import strategy.quack.GeGeQuackBehavior;
public class RedHeadDuck extends Duck{
public RedHeadDuck() {
flyBehavior = new BadFlyBehavior(); //飞的不好
quackBehavior = new GeGeQuackBehavior(); //会GeGe叫
}
@Override
public void display() {
System.out.println("-----------I'm a Red Duck--------");
}
}
绿头鸭的类:
package strategy.duck;
import strategy.fly.GoodFlyBehavior;
import strategy.quack.GaGaQuackBehavior;
public class GreenHeadDuck extends Duck{
public GreenHeadDuck() {
flyBehavior = new GoodFlyBehavior(); //飞的好
quackBehavior = new GaGaQuackBehavior(); //会GaGa叫
}
//抽象方法
@Override
public void display() {
System.out.println("----------I'm a Green Duck------");
}
}
然后再看fly包:
首先有一个fly接口
package strategy.fly;
public interface FlyBehavior {
void fly();
}
具体的三个实现类:
package strategy.fly;
public class BadFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("Bad Fly");
}
}
package strategy.fly;
public class GoodFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("Good Fly");
}
}
package strategy.fly;
public class NoFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("No Fly");
}
}
再看quack包:
首先一个接口:
package strategy.quack;
public interface QuackBehavior {
void quack();
}
然后看三个具体的实现类:
package strategy.quack;
public class GaGaQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("GaGa");
}
}
package strategy.quack;
public class GeGeQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("GeGe");
}
}
package strategy.quack;
public class NoQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("No Quack");
}
}
再看具体的测试类:
package strategy.test;
import strategy.duck.Duck;
import strategy.duck.GreenHeadDuck;
import strategy.duck.RedHeadDuck;
import strategy.fly.NoFlyBehavior;
import strategy.quack.NoQuackBehavior;
public class MyTest {
public static void main(String[] args) {
Duck green = new GreenHeadDuck();
Duck red = new RedHeadDuck();
green.display() ;//必须实现的
green.fly();
green.quack();
green.swim(); //都会的
red.display();
red.fly();
red.quack();
red.swim();
//动态设置红头鸭
red.setFlyBehavior(new NoFlyBehavior()); //不会飞
red.setQuackBehavior(new NoQuackBehavior());//不会叫
red.display();
red.fly();
red.quack();
red.swim();
}
}
输出:
策略模式案例二
再看一个更简单的例子:实现加减乘一系列操作;
先看一个定义活动的 Strategy 接口
package strategy.partice;
/**
* 接口
*/
public interface Strategy {
public int doOperation(int num1, int num2);
}
以及实现它的三个实现类:
package strategy.partice;
/**
* 算法1: 实现加法
*/
public class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
package strategy.partice;
/**
* 算法2:实现减法
*/
public class OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
package strategy.partice;
/**
* 算法3: 实现乘法
*/
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
然后再看实现了 Strategy 接口的实体策略类,Context 是一个使用了某种策略的类。
package strategy.partice;
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
测试:
package strategy.partice;
public class MyTest {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
运行结果
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50
上一篇: ThinkPHP3.1.3版本新特性概述