设计模式(11):策略模式及其典型应用 您所在的位置:网站首页 cipp模式优缺点及案例 设计模式(11):策略模式及其典型应用

设计模式(11):策略模式及其典型应用

2024-07-17 05:07| 来源: 网络整理| 查看: 265

策略模式及其在Java中的典型应用

1、什么是策略模式

2、策略模式的特性

3、策略模式的优缺点及应用场景

4、策略模式的应用实例

4.1、原始方法实现示例

4.2 使用策略模式实现示例:

5、策略模式在JDK/Spring框架中的经典应用

1、什么是策略模式

策略模式的定义:定义算法族,分别封装起来,让他们之间可以互相替换,此模式的变化独立于算法的使用者。在策略模式中,一个类的行为或其算法可以在运行时更改,这种类型的设计模式属于行为型模式。策略模式的类图示例如下:

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变context对象的执行算法。

2、策略模式的特性

(1)意图:

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

(2)主要解决:

在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。

(3)何时使用:

一个系统有许多许多类,而区分它们的只是他们直接的行为。

(4)如何解决:

将这些算法封装成一个一个的类,任意地替换。

(4)关键代码:

实现同一个接口。

3、策略模式的优缺点及应用场景

(1)优点: 

1)算法可以自由切换。

2)避免使用多重条件判断。

3)扩展性良好。

(2)缺点: 

1)策略类会增多。

2)所有策略类都需要对外暴露。

(3)使用场景: 

1)如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

2)一个系统需要动态地在几种算法中选择一种。

3)如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

(4)注意事项:

如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

4、策略模式的应用实例

假设场景:假设在开发一款僵尸大战的游戏,有两种僵尸:普通僵尸和旗手僵尸,初始时他们的方法都一样:一步一步走,咬。但是后续随着僵尸种类的增加,会有多种僵尸,而且他们的方法实现也不一样,考虑如下:

4.1、原始方法实现示例

以下为传统直接实现的方式实现上述场景,我们每次要增加一个僵尸类时,都需要继承或重写一个类,类与类之间相互耦合,代码也逐渐变得难以理解,维护起来很麻烦。

package designpatterns.strategy.v1; /** * 〈一句话功能简述〉 * 〈僵尸大战〉 * * @author Jianf * @create 2020/8/18 * @since 1.0.0 */ public class ZombieTest { public static void main(String[] args) { AbstractZombie normalZombie = new NormalZombie(); AbstractZombie flagZombie = new FlagZombie(); normalZombie.display(); normalZombie.move(); normalZombie.attack(); System.out.println("-----------------------------"); flagZombie.display(); flagZombie.move(); flagZombie.attack(); } } //僵尸抽象类 abstract class AbstractZombie{ public abstract void display(); public void attack(){ System.out.println("咬。"); } public void move(){ System.out.println("一步一步移动。。"); } } //普通僵尸类 class NormalZombie extends AbstractZombie{ @Override public void display() { System.out.println("我是普通僵尸"); } } class FlagZombie extends AbstractZombie{ @Override public void display() { System.out.println("我是旗手僵尸。。"); } } //假设后来又多了一些种类的僵尸,他们的这些行为不全部一样 //大头僵尸 class BigHeadZombie extends AbstractZombie{ @Override public void display() { System.out.println("我是大头僵尸。"); } @Override public void attack() { //... System.out.println("头撞。"); } } class XxxZombie extends BigHeadZombie{ @Override public void move() { System.out.println("xxx..."); } } //按照上面的逻辑,假设增加很多种类的僵尸,每次都需要继承或重写另一个僵尸类以实现其功能,代码将变得复杂难读

 

4.2 使用策略模式实现示例:

下面示例为使用策略模式来实现:我们每次新增一个僵尸类时,重写方法定义它的表现和行为,也可以在运行时通过动态修改其行为对象来实现对其行为的修改。各个僵尸类之间不耦合,具体实现算法可以相互替换。

package designpatterns.strategy.v2; /** * 〈一句话功能简述〉 * 〈策略模式〉 * * @author Jianf * @create 2020/8/18 * @since 1.0.0 */ public class StrategyTest { public static void main(String[] args) { //测试示例 Zombie zombie = new NormalZombie(); zombie.display(); zombie.attack(); zombie.move(); //更换攻击方式:传递算法,使用算法。。 zombie.setAttackable(new HitAttack()); zombie.attack(); } } //将共同特征进行抽象 interface Moveable{ void move(); } interface Attackable{ void attack(); } //抽象僵尸 abstract class Zombie{ abstract public void display(); Moveable moveable; Attackable attackable; abstract void move(); abstract void attack(); public Zombie() { } public Zombie(Moveable moveable, Attackable attackable) { this.moveable = moveable; this.attackable = attackable; } public Moveable getMoveable() { return moveable; } public void setMoveable(Moveable moveable) { this.moveable = moveable; } public Attackable getAttackable() { return attackable; } public void setAttackable(Attackable attackable) { this.attackable = attackable; } } //普通僵尸 class NormalZombie extends Zombie{ public NormalZombie() { super(new StepByStepMove(),new BiteAttack()); } public NormalZombie(Moveable moveable, Attackable attackable) { super(moveable, attackable); } @Override public void display() { System.out.println("我是普通僵尸。。"); } @Override void move() { moveable.move(); } @Override void attack() { attackable.attack(); } } //普通僵尸的行为 class StepByStepMove implements Moveable{ @Override public void move() { System.out.println("一步一步移动..."); } } class BiteAttack implements Attackable{ @Override public void attack() { System.out.println("咬"); } } //其他的攻击行为 class HitAttack implements Attackable{ @Override public void attack() { System.out.println("打。。"); } } //旗手僵尸 class FlageZombie extends Zombie{ public FlageZombie() { super(new StepByStepMove(),new BiteAttack()); } public FlageZombie(Moveable moveable, Attackable attackable) { super(moveable, attackable); } @Override public void display() { System.out.println("我是旗手僵尸。。"); } @Override void move() { moveable.move(); } @Override void attack() { attackable.attack(); } 5、策略模式在JDK/Spring框架中的经典应用

(1) JDK中的Arrays类的sort()方法可以动态地传入比较器,不同的比较器可以有不同的实现算法,通过传入不同的比较器实现算法的替换,而该变化独立于算法的使用者,该方法源码如下:

@Override public void sort(Comparator


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有