设计模式1 策略模式

定义

策略模式(Strategy Pattern)定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
AKA:政策模式(Policy Pattern)

使用场景

  • 当许多相关的类只在行为上有所不同。策略提供了一种为一个类配置很多行为的方法;
  • 实现相关算法系列。例如,可以定义不同空间/时间复杂度的算法;
  • 当算法使用了客户不需要知道的数据时。使用策略模式避免暴露复杂的特定于算法的数据结构;
  • 消除了一些if else条件语句。当一个类定义了很多条件语句时,应该将相关分支移动到策略中;

主要角色

  1. 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口。
  2. 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
  3. 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
    策略模式

举例

源自《Head FIRST设计模式》实现鸭子类,让这个能够飞和叫,注意会存在橡皮鸭等不会飞的鸭子,诱饵鸭等不会叫的鸭子。
请添加图片描述

Duck -FlyBehavior flyBehavior -QuackBehavior quackBehavior +swim() +display() +performQuack() +performFly() +setFlyBehavior() +setQuackBehavior() ModelDuck //绿头鸭 RedHeadDuck //红头鸭 RubberDuck //橡皮鸭 DecoyDuck //诱饵鸭子 FlyWithWings /实现fly() «interface» FlyBehavior +fly() FlyNoWay /实现fly() Quack //实现普通鸭子叫 «interface» QuackBehavior +quack() Squeak //实现橡皮鸭子叫 ModelQuack //不会叫

代码实现
1.Duck类

public abstract class Duck
{
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	public Duck(){
		//构造函数,也在这里可以设置默认的FlyBehavior和QuackBehavior
	}
	//每个鸭子的外观不同, 在子类中实现
	public abstract void display();
	//执行叫的方法
	public void performQuack(){
        quackBehavior.quack();
    }
    //执行飞行的方法
    public void performFly(){
        flyBehavior.fly();
    }
    //选择飞行的方法
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }
	//选择叫的方法
    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
}

2.QuackBehavior和FlyBehavior接口

public interface QuackBehavior {
    void quack();
}
public interface FlyBehavior {
    void fly();
}

3.具体实现Quack(呱呱叫)、Squeak(吱吱叫)、ModelQuack(不会叫)、FlyWithWings(翅膀飞)、FlyNoWay(不会飞)

public class Quack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("呱呱叫");
    }
}
public class Squeak implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("吱吱叫");
    }
}
public class ModelQuack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("什么都不做, 不会叫");
    }
}
public class FlyWithWings implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("用翅膀飞行");
    }
}
public class FlyNoWay implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("什么都不做, 不能飞");
    }
}

4.具体实现一个普通鸭子和橡皮鸭子

//橡皮鸭子
public class RubberDuck extends Duck {
    @Override
    public void display() {
        System.out.println("可爱的黄色橡皮鸭");
    }
    
    @Test
    public void test1() throws Exception {
        Duck rubberDuck = new RubberDuck();
        //运行时动态改变行为
        rubberDuck.setFlyBehavior(new FlyNoWay());
        rubberDuck.setQuackBehavior(new Squeak());
        rubberDuck.performFly();
        rubberDuck.performQuack();
        rubberDuck.display();
    }
}
//普通绿头鸭子
public class MallardDuck extends Duck {
    
    @Override
    public void display() {
        System.out.println("绿头鸭");
    }
    
    @Test
    public void test1() throws Exception {
        MallardDuck mallardDuck = new MallardDuck();
        rubberDuck.setFlyBehavior(new FlyWithWings());
        rubberDuck.setQuackBehavior(new Quack());
        mallardDuck.performQuack();
        mallardDuck.performFly();
        mallardDuck.display();
    }
}

优缺点分析

优点

  1. 实现了相关算法系列。Strategy类以后也可以用在别的地方。
  2. 提供了可以替换继承关系的办法。 无需逻辑中硬编码实现算法。易于切换、易于理解、易于扩展。
  3. 消除了一些if else条件语句 。将行为封装在一个个独立的Strategy类中消除了一些条件语句。
  4. 实现的选择 Strategy模式可以提供相同行为的不同实现。客户可以选择不同的时间及空间复杂度。

缺点

  1. 客户需要了解能够使用哪些算法并手动指定。不能像之前一样,我就管调用其他啥也不用管。
  2. Strategy和Context之间的通信开销。
  3. 策略模式将造成产生很多策略类。

参考

《Head FIRST设计模式》
设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
读headFirst设计模式 - 策略模式
策略模式
简说设计模式——策略模式

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值