小谈设计模式(3)—策略模式

2023-09-17 11:46:42

专栏介绍

专栏地址

link

专栏介绍

主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
在这里插入图片描述

策略模式

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列的算法,将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端。

主要角色

当我们使用策略模式时,通常会涉及三个主要角色:环境(Context)、抽象策略(Strategy)和具体策略(Concrete Strategy)。

环境(Context)

环境类是策略模式的核心,它持有一个策略对象的引用,并在运行时根据具体需求调用策略对象的算法。环境类提供了一个接口或方法,用于设置和获取策略对象。在客户端使用策略模式时,通常需要与环境类进行交互。

抽象策略(Strategy)

抽象策略类是策略模式的接口或抽象类,定义了具体策略类所必须实现的算法。抽象策略类通常包含一个或多个抽象方法,用于描述策略的行为。客户端通过调用抽象策略类中的方法来使用具体策略。

具体策略(Concrete Strategy)

具体策略类是策略模式的实现类,实现了抽象策略类中定义的算法。具体策略类根据具体的业务需求,实现了不同的算法逻辑。在客户端使用策略模式时,可以根据需要选择合适的具体策略类。

角色总结

环境类持有一个策略对象的引用,并在运行时根据具体需求调用策略对象的算法。抽象策略类定义了具体策略类所必须实现的算法,而具体策略类实现了具体的算法逻辑。通过使用策略模式,可以将算法的定义和使用分离,提高代码的灵活性、可维护性和可扩展性。
在这里插入图片描述

核心思想

策略模式的核心思想是将算法的定义和使用分离。在策略模式中,我们将不同的算法封装成不同的策略类,并通过环境类持有一个策略对象的引用。在运行时,根据具体需求选择合适的策略对象,并调用其算法。

封装算法

策略模式将不同的算法封装成不同的策略类。每个策略类都实现了一种具体的算法逻辑。通过封装算法,我们可以将其与其他代码分离,使得算法的定义更加清晰、可读、可维护。

在这里插入图片描述

定义抽象策略

策略模式定义了一个抽象策略类,其中包含了策略类所必须实现的方法。抽象策略类可以是一个接口或者抽象类。通过定义抽象策略,我们可以统一不同策略类的接口,使得客户端可以以统一的方式使用不同的策略。

使用环境类

策略模式通过环境类持有一个策略对象的引用。在运行时,客户端可以根据具体需求选择合适的策略对象,并将其设置到环境类中。环境类在运行时根据具体需求调用策略对象的算法,实现了算法的动态切换。

思想总结

通过将算法的定义和使用分离,策略模式提高了代码的灵活性、可维护性和可扩展性。它使得算法的修改和增加变得更加简单,不需要修改原有的代码。同时,策略模式也符合开闭原则,可以方便地增加新的策略类。
在这里插入图片描述

Java代码实现——以一个游戏角色攻击方式的例子

首先,我们定义一个抽象策略类 AttackStrategy,它声明了一个 attack() 方法:

public interface AttackStrategy {
    void attack();
}

然后,我们定义两种具体的攻击策略类:MeleeAttackStrategy 和 RangedAttackStrategy,它们分别实现了 AttackStrategy 接口:

public class MeleeAttackStrategy implements AttackStrategy {
    @Override
    public void attack() {
        System.out.println("近战攻击");
    }
}

public class RangedAttackStrategy implements AttackStrategy {
    @Override
    public void attack() {
        System.out.println("远程攻击");
    }
}

接下来,我们定义一个环境类 Character,它持有一个 AttackStrategy 对象,并提供一个 setAttackStrategy() 方法用于动态设置攻击策略:

public class Character {
    private AttackStrategy attackStrategy;

    public void setAttackStrategy(AttackStrategy attackStrategy) {
        this.attackStrategy = attackStrategy;
    }

    public void attack() {
        attackStrategy.attack();
    }
}

最后,我们可以在客户端中使用策略模式:


public class Client {
    public static void main(String[] args) {
        Character character = new Character();
        
        character.setAttackStrategy(new MeleeAttackStrategy());
        character.attack(); // 输出:近战攻击
        
        character.setAttackStrategy(new RangedAttackStrategy());
        character.attack(); // 输出:远程攻击
    }
}

在这里插入图片描述

代码分析

在上述代码中,我们通过设置不同的攻击策略,使得角色可以使用不同的攻击方式。这样,当需要增加新的攻击方式时,只需要实现新的具体策略类,并在客户端中设置新的攻击策略即可,而不需要修改原有的代码。

优缺点分析

优点

算法的封装性

策略模式将不同的算法封装成不同的策略类,使得每个策略类都只关注自己的算法逻辑,提高了代码的可读性和可维护性。

策略的替换性

由于策略模式将算法的定义和使用分离,所以在运行时可以根据具体需求选择不同的策略对象,实现算法的动态切换。这样可以方便地替换和扩展算法,而不需要修改原有的代码。

算法的扩展性

策略模式符合开闭原则,可以方便地增加新的策略类。当需要增加新的算法时,只需要添加一个新的策略类,并在环境类中设置该策略对象即可,不需要修改原有的代码。

算法的复用性

策略模式将算法封装成独立的策略类,可以在不同的场景中复用相同的算法。这样可以避免代码的重复编写,提高了代码的复用性。

在这里插入图片描述

缺点

增加了类的数量

使用策略模式会增加类的数量,每个具体策略类都需要单独定义一个类。如果策略较多,可能会导致类的数量过多,增加代码的复杂性。

客户端需要了解不同的策略类

客户端在使用策略模式时,需要了解不同的策略类,并选择合适的策略对象。如果策略较多,可能会增加客户端的复杂性。

策略的选择逻辑

在使用策略模式时,需要根据具体需求选择合适的策略对象。这个选择逻辑可能会比较复杂,需要考虑多个因素,增加了代码的复杂性。

优缺点总结

总的来说,策略模式通过将算法的定义和使用分离,提高了代码的灵活性、可维护性和可扩展性。它将不同的算法封装成不同的策略类,实现了算法的动态切换和复用。然而,策略模式也会增加类的数量,增加客户端的复杂性,并且需要考虑策略的选择逻辑。在使用策略模式时,需要权衡其优点和缺点,选择合适的使用方式。

更多推荐

中秋特辑:Java事件监听实现一个猜灯谜小游戏

众所周知,JavaSwing是Java中关于窗口开发的一个工具包,可以开发一些窗口程序,然后由于工具包的一些限制,导致Java在窗口开发商并没有太多优势(当然也有一些第三方的工具包也很好用),不过,在JavaSwing中关于事件的监听机制是我们需要重点掌握的内容。何为事件监听在Java中,事件监听(EventListe

Spring之微服务架构与Spring Cloud

微服务架构与SpringCloud微服务架构与SpringCloud摘要引言词汇解释详细介绍微服务架构SpringCloud核心组件示例代码:注释:注意事项理解微服务架构的优势详细介绍什么是微服务架构?微服务架构的优势1.可扩展性(Scalability)2.灵活性和快速开发(FlexibilityandRapidDe

Spring高手之路11——BeanDefinition解密:构建和管理Spring Beans的基石

文章目录1.探索BeanDefinition1.1官方文档对BeanDefinition的解读1.2BeanDefinition关键方法剖析1.3BeanDefinition部分方法的实际运用1.4BeanDefinition深层信息结构梳理2.BeanDefinition构造体系解析2.1BeanDefinition

Java开发 - 探寻Spring的秘密

前言Spring是企业级J2EE一站式解决方案,提供了整个项目的表现层、业务层、持久层,而且,它的生态特别完善,可以和其他框架无缝对接,现在做Java的哪个项目里没有Spring的说出不去都不信。但往往我们开发者只重视项目是不是run起来了,而忽略了去了解Spring本身,所以很多开发者仅仅是停留在了使用的层次。博主也

JDK8新特性

Lembda表达式lembda表达式是一个简洁、可传递的匿名函数,实现了把代码块赋值给一个变量的功能是我认为jdk1.8中最让人眼前一亮的特性(我没用过其他函数式的语言)在了解表达式之前,我们先看两个概念函数式接口含有且仅含有一个抽象方法,Lembda表达式需要借助函数式接口实现。通常来说我们在这个接口定义上加上@Fu

Spring复杂对象的3中创建方法

复杂对象是相对于简单对象可以直接new出的对象。这种对象在Spring中不可以通过简单对象的创建方式来创建。下面我们将通过实现FactoryBean接口、实例工厂、静态工厂三种方法来创建。FactoryBean接口Spring提供FactoryBean接口并且提供了getObject方法是为了支持自定义工厂。通过实现这

【基础篇】二、parent继承、starter、引导类、内嵌tomcat

文章目录0、前言1、继承parent2、starter3、引导类4、内嵌tomcat5、SpringBoot项目快速启动0、前言SpringBoot,Boot,鞋子,其设计目的是用来简化Spring框架应用的初始搭建以及开发过程Spring程序缺点:依赖设置繁琐(各个依赖之间版本的适配、依赖排除等活儿得自己调)配置繁琐

Hive的分区和分桶

目录​编辑一、Hive分区1.1分区产生的背景1.2动态分区1.2.1hive的动态分区介绍1.2.2动态分区配置1.2.2.1动态分区开启1.2.2.2动态分区模式1.2.2.3一个mr节点上,设置动态分区的最大数量1.2.2.4所有mr节点上,设置所有动态分区的最大数量1.2.2.5设置所有mrjob允许创建的文件

软件测试未来的发展趋势以及软件测试进阶路线

【软件测试行业现状】2023年了你还敢学软件测试?未来已寄..测试人该何去何从?【自动化测试、测试开发、性能测试】全球各地的企业每天都在发展变化着,以应对市场挑战,满足日益成熟的客户需求。即使是正在进行的技术进步也会使软件测试专家在实践的过程中更加专注和精确。2021年给软件测试领域带来了新的技术解决方案,以及质量保证

【2023】Git版本控制-远程仓库详解

目录创建远程仓库向远程仓库推送数据文件从第二台主机本地拉取远程仓库数据第一台主机同步远程仓库数据tag标签git忽略文件Git远程仓库是Git版本控制系统的一个概念,它是一个存储Git代码的远程服务器。你可以将本地Git仓库上传到远程仓库,以便与其他人协作开发或备份代码。创建远程仓库远程仓库可以使用第三方平台,如(gi

AI无法提振台积电股价

来源:猛兽财经作者:猛兽财经总结:(1)台积电的股价已经从最高点下跌了18%,很多期权交易员正在押注台积电的股价会进一步下跌。(2)华尔街分析师目前也下调了台积电的收入和盈利预期。台积电(TSM)的股价最近这段时间已经跌回到了了5月份之前的水平,很多期权交易员也正在押注台积电股价将在10月中旬进一步下跌。台积电股价的溢

热文推荐