策略模式详解(Java 版)

定义

策略模式定义了一系列的算法,将每个算法封装在独立的类中,并使他们可以相互替换。这样,算法的选择或者变更就可以独立于使用算法的客户端进行,从而使系统更灵活、提高可扩展性和可维护性。

策略模式通常包括以下角色:

  1. 上下文(Context):客户端代码和策略模式之间的接口。它持有一个策略对象的引用,并在运行时将调用委托给策略对象。
  2. 策略(Strategy):策略是定义一系列算法的接口,通常以接口或者抽象类的形式实现。具体的策略类实现了这个接口
  3. 具体策略(Concrete Strategy):具体策略类是策略的具体实现。每个具体策略类实现了策略接口或者继承了抽象策略类,并实现了自己的算法逻辑

使用策略模式,客户端可以在运行时选择不同的策略,并且可以轻松地添加新的策略或修改现有的策略(或算法),而不需要修改客户端代码。这使得策略模式成为一种非常有用的设计模式,特别是在需要灵活处理算法变化的情况下。

场景

举个栗子,传闻梅西如天神下凡,回首过往梅开二度、帽子戏法、五子登科的好戏仍然历历在目。

以下是梅西常用的一些技术:

蝎子摆尾

大力抽射

圆月弯刀

油炸丸子

抽象策略
/**
 * @deprecated 给出策略的接口
 */
public interface IStrategy {
    void warMethod();
}
具体策略
/**
 * @description 蝎子摆尾
 */
public class ScorpionTailPendulumStrategy implements IStrategy{
    @Override
    public void footballSkills() {
        System.out.println("【蝎子摆尾】");
    }
}
/**
 * @Description 大力抽射
 */
public class VolleyStrategy implements IStrategy{
    @Override
    public void footballSkills() {
        System.out.println("【大力抽射】");
    }
}
/**
 * @Description 圆月弯刀
 */
public class TulwarStrategy implements IStrategy{
    @Override
    public void footballSkills() {
        System.out.println("【圆月弯刀】");
    }
}
/**
 * @Description 油炸丸子
 */
public class BallStrategy implements IStrategy{
    @Override
    public void footballSkills() {
        System.out.println("【油炸丸子】");
    }
}

封装类

梅西将的所有神技贡献给FIFA,我们在FIFA的世界,任何球员可以都可以使用这些神技。球员持有策略的引用,他可以使用梅西所有的技能,也不会影响其他功能,经过球员自身的加工,可以将这些技能表现出不同的效果。

public class General {
    private IStrategy mStrategy;

    public General(IStrategy strategy) {
        this.mStrategy = strategy;
    }

    public void useAbility() {
        System.out.println("准备使用技能");
        mStrategy.footballSkills();
    }
}

实战结果

我们一口气来new4个技能给这位幸运的球员:

General general;
general = new General(new ScorpionTailPendulumStrategy());
general.useAbility();
System.out.println("\n------------------------------------\n");

general = new General(new VolleyStrategy());
general.useAbility();
System.out.println("\n------------------------------------\n");

general = new General(new TulwarStrategy());
general.useAbility();
System.out.println("\n------------------------------------\n");

general = new General(new BallStrategy());
general.useAbility();
System.out.println("\n------------------------------------\n");

输出:

准备使用技能
【蝎子摆尾】

------------------------------------

准备使用技能
【大力抽射】

------------------------------------

准备使用技能
【圆月弯刀】

------------------------------------

准备使用技能
【油炸丸子】

------------------------------------
总结

策略模式优点

  • 灵活性: 各种策略切换自如,使得算法可以独立于客户端而变化。客户端可以根据需要在运行时选择不同的算法,而不需要修改原有的代码。
  • 可扩展性:新的策略可以很方便的添加,也不会影响到已有的代码结构。维护也比较方便,可扩展性和可维护性较强。
  • 复用性: 策略模式将算法封装在独立的策略类中,这些策略类可以被不同的客户端重复使用,提高了代码的复用性。
  • 降低耦合度: 策略模式将策略或者算法的实现与客户端的调用解耦,使得系统各部分之间的依赖关系更加松散,降低了模块之间的耦合度。

策略模式缺点

  • 类数量增加: 使用策略模式会增加系统中类的数量,因为每个具体策略都需要一个独立的类来实现,这可能会增加代码的复杂度。
  • 客户端必须知道所有策略: 客户端需要了解所有的策略,并且在运行时选择合适的策略,这可能增加了客户端的复杂度。因为你必须了解各种策略【球技】的用法
  • 增加了对象间的调用关系: 策略模式将算法封装成独立的对象,增加了对象间的调用关系,可能会增加系统的运行开销。
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值