Java设计模式-策略模式-基于Spring实现

这篇具有很好参考价值的文章主要介绍了Java设计模式-策略模式-基于Spring实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、策略模式

1.1、概述

策略模式是一种行为设计模式,它允许在运行时选择算法的行为。它将算法封装在独立的策略类中,使得它们可以相互替换,而不影响客户端代码。这种模式通过将算法的选择从客户端代码中分离出来,提供了更大的灵活性和可维护性。

在Java中,策略模式的设计理念可以通过以下步骤实现:

  1. 定义一个策略接口(或抽象类),该接口定义了所有具体策略类都必须实现的方法。
  2. 创建具体的策略类,实现策略接口,并提供具体的算法实现。
  3. 在客户端代码中,创建一个策略对象,并将其传递给需要使用算法的对象。
  4. 客户端对象使用策略对象来执行特定的算法。

在你提供的代码片段中,我无法确定与策略模式相关的代码。如果你有更多的上下文或示例代码,我可以更好地帮助你理解和应用策略模式。

1.2、优缺点

策略模式具有以下优点:

  • 可以代替if-else
  1. 算法的独立性:策略模式将算法封装在独立的策略类中,使得算法可以独立于客户端代码进行修改和扩展。这样可以提高代码的灵活性和可维护性。

  2. 可替换性:由于策略模式将算法封装在不同的策略类中,因此可以在运行时动态地切换和替换算法。这样可以根据不同的需求选择最合适的算法,而无需修改客户端代码。

  3. 单一职责原则:策略模式将不同的算法封装在不同的策略类中,使得每个策略类只负责一个具体的算法。这样符合单一职责原则,提高了代码的可读性和可维护性。

  4. 扩展性:由于策略模式将算法封装在独立的策略类中,因此可以很容易地添加新的策略类来扩展系统的功能。

策略模式也有一些缺点:

  1. 增加了类的数量:使用策略模式会增加系统中的类的数量,因为每个具体的算法都需要一个对应的策略类。这可能会增加代码的复杂性和理解难度。

  2. 客户端必须了解所有的策略类:客户端必须了解所有可用的策略类,并在运行时选择合适的策略。这可能会增加客户端代码的复杂性。

  3. 策略切换的开销:在运行时切换策略可能会带来一定的开销,特别是在需要频繁切换策略的情况下。这可能会影响系统的性能。

综上所述,策略模式在提供灵活性、可维护性和可扩展性方面具有很多优点,但也需要权衡其增加的类数量和策略切换的开销。在设计和使用策略模式时,需要根据具体的需求和情况进行权衡和选择。

2、SpringBean方式实现

  • bean的名字(默认):实现策略类的名字首字母小写

2.1、实现步奏

  • 可以看到,去获取bean是需要用户自己去做的。

Java设计模式-策略模式-基于Spring实现

2.2、实现

①定义策略接口

package com.cc.eed.strategy;

/**
 * <p>基于SpringBean的策略模式</p>
 *
 * @author CC
 * @since 2023/10/13
 */
public interface ISpringBeanStrategy {

    /**
     * 吃饭
     */
    String eating();

    /**
     * 玩
     */
    String play();
}

②定义实现类1

package com.cc.eed.strategy.impl;

import com.cc.eed.strategy.ISpringBeanStrategy;
import org.springframework.stereotype.Component;

/**
 * <p>小美</p>
 *
 * @author CC
 * @since 2023/10/13
 */
@Component
public class MeiSpringBeanImpl implements ISpringBeanStrategy {

    /**
     * 吃饭
     */
    @Override
    public String eating() {
        return "小美,吃饭!";
    }

    /**
     * 玩
     */
    @Override
    public String play() {
        return "小美,玩!";
    }
}

定义实现类2

package com.cc.eed.strategy.impl;

import com.cc.eed.strategy.ISpringBeanStrategy;
import org.springframework.stereotype.Component;

/**
 * <p>小明</p>
 *
 * @author CC
 * @since 2023/10/13
 */
@Component
public class MingSpringBeanImpl implements ISpringBeanStrategy {

    /**
     * 吃饭
     */
    @Override
    public String eating() {
        return "小明,吃饭!";
    }

    /**
     * 玩
     */
    @Override
    public String play() {
        return "小明,玩!";
    }
}

③定义beanName的枚举

  • 用于使用类型int获取对应的beanName
package com.cc.eed.enums;

import lombok.Getter;
import org.springframework.util.Assert;

import java.util.Arrays;

/**
 * <p></p>
 *
 * @author CC
 * @since 2023/10/13
 */
@Getter
public enum PeopleEnum {

    MING(1, "小明", "mingSpringBeanImpl"),
    MEI(2, "小美", "meiSpringBeanImpl")
    ;

    public Integer type;

    public String name;

    public String beanName;

    /** <p>根据类型获取beanName<p>
     * @param type type
     * @return {@link String}
     * @since 2023/10/13
     * @author CC
     **/
    public static String getBeanName(Integer type) {
        PeopleEnum peopleEnum = Arrays.stream(values())
                .filter(p -> p.getType().equals(type))
                .findAny().orElse(null);
        Assert.notNull(peopleEnum, "暂不支持的策略模式!");
        return peopleEnum.getBeanName();
    }


    PeopleEnum(Integer type, String name, String beanName) {
        this.type = type;
        this.name = name;
        this.beanName = beanName;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }
}

④使用springBean工具类获取beanName

  • 略,见:https://www.cnblogs.com/kakarotto-chen/p/17760069.html

⑤使用

  • 传入不同的类型,获取不同的策略
@Test
public void test02()throws Exception{
    //根据BeanName获取具体的bean,实现策略模式
    //根据人员ID(或者类型)获取不同的bean
    String beanName = PeopleEnum.getBeanName(1);
    ISpringBeanStrategy bean = (ISpringBeanStrategy) SpringBeanUtil.getBean(beanName);

    String eating = bean.eating();
    System.out.println(eating);

    String play = bean.play();
    System.out.println(play);
}
  • 结果:
    传入1
    Java设计模式-策略模式-基于Spring实现
    传入2
    Java设计模式-策略模式-基于Spring实现
    传入除了1/2的
    Java设计模式-策略模式-基于Spring实现

3、简单工厂模式实现(推荐)

  • 加自定义Bean的名字

3.1、实现步奏

  • 可以看到,去获取bean是交给工厂去做的,用户只需要传入类型即可。

Java设计模式-策略模式-基于Spring实现

3.2、实现

①定义策略接口

package com.cc.eed.strategy;

/**
 * <p>简单工厂模式 - 实现的策略模式</p>
 *
 * @author CC
 * @since 2023/10/13
 */
public interface IFactoryStrategy {

    /**
     * 吃饭
     */
    String eating();

    /**
     * 玩
     */
    String play();
}

②生产策略bean的工厂

  • 由于使用的@Resource注解,BUSINESS_FACTORY会自动注入所有实现了IFactoryStrategy接口的Bean。@Resource注解是Spring提供的一种依赖注入的方式,它会根据类型进行自动装配。在这个例子中,BUSINESS_FACTORY是一个Map类型的成员变量,它的键是字符串类型,值是IFactoryStrategy类型。当Spring容器启动时,会扫描并找到所有实现了IFactoryStrategy接口的Bean,并将它们自动注入到BUSINESS_FACTORY中。
  • 由于BUSINESS_FACTORY使用了ConcurrentHashMap作为实现,它会根据PirateEnum.values().length的大小来初始化容量。这样可以确保BUSINESS_FACTORY的大小与实际注入的Bean数量一致,提高性能和效率。
package com.cc.eed.strategy;

import com.cc.eed.enums.PirateEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>简单工厂</p>
 * <li>可以生产多个策略</li>
 *
 * @author CC
 * @since 2023/10/13
 */
@Component
public class StrategyByFactory {

    /**
     * 1、批量注入实现了 IFactoryStrategy 的Bean。
     * 2、用bean的数量当做map的大小
     */
    @Resource
    private final Map<String, IFactoryStrategy> BUSINESS_FACTORY = new ConcurrentHashMap<>(PirateEnum.values().length);

    //生成的策略...
    /** <p>根据类获取不同的Bean<p>
     * @param type type
     * @return {@link IFactoryStrategy}
     * @since 2023/10/13
     * @author CC
     **/
    public IFactoryStrategy getBusinessMap(Integer type){
        Assert.notNull(type, "类型不能为空!");
        String beanName = PirateEnum.getBeanName(type);
        return BUSINESS_FACTORY.get(beanName);
    }

    //生成的其他策略...

}

③策略实现类1

package com.cc.eed.strategy.impl;

import com.cc.eed.enums.PirateEnum;
import com.cc.eed.strategy.IFactoryStrategy;
import org.springframework.stereotype.Component;

/**
 * <p>路飞</p>
 *
 * @author CC
 * @since 2023/10/13
 */
@Component(PirateEnum.LF_BEAN_NAME)
public class LuFeiFactoryStrategy implements IFactoryStrategy {
    /**
     * 吃饭
     */
    @Override
    public String eating() {
        return "路飞,吃饭!";
    }

    /**
     * 玩
     */
    @Override
    public String play() {
        return "路飞,玩!";
    }
}

③策略实现类2

package com.cc.eed.strategy.impl;

import com.cc.eed.enums.PirateEnum;
import com.cc.eed.strategy.IFactoryStrategy;
import org.springframework.stereotype.Component;

/**
 * <p>明哥</p>
 *
 * @author CC
 * @since 2023/10/13
 */
@Component(PirateEnum.MG_BEAN_NAME)
public class MingGgFactoryStrategy implements IFactoryStrategy {
    /**
     * 吃饭
     */
    @Override
    public String eating() {
        return "明哥,吃饭!";
    }

    /**
     * 玩
     */
    @Override
    public String play() {
        return "明哥,玩!";
    }
}

④定义beanName的枚举

package com.cc.eed.enums;

import org.springframework.util.Assert;

import java.util.Arrays;

/**
 * <p></p>
 *
 * @author CC
 * @since 2023/10/13
 */
public enum PirateEnum {

    MG(11, "明哥", PirateEnum.MG_BEAN_NAME),

    LF(22, "路飞", PirateEnum.LF_BEAN_NAME)

    ;

    public Integer type;

    public String name;

    public String beanName;

    /**
     * 自定义的beanName
     */
    public static final String MG_BEAN_NAME = "mingGg_11";
    public static final String LF_BEAN_NAME = "luFei_22";

    /** <p>根据类型获取beanName<p>
     * @param type type
     * @return {@link String}
     * @since 2023/10/13
     * @author CC
     **/
    public static String getBeanName(Integer type) {
        PirateEnum pirateEnum = Arrays.stream(values())
                .filter(p -> p.getType().equals(type))
                .findAny().orElse(null);
        Assert.notNull(pirateEnum, "暂不支持的策略模式!");
        return pirateEnum.getBeanName();
    }

    PirateEnum(Integer type, String name, String beanName) {
        this.type = type;
        this.name = name;
        this.beanName = beanName;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }
}

⑤使用springBean工具类获取beanName

  • 略,见:https://www.cnblogs.com/kakarotto-chen/p/17760069.html

⑥使用

  • 需要注入工厂来调用方法即可
    @Resource
    private StrategyByFactory strategyByFactory;

    @Test
    public void test03()throws Exception{
        //使用简单工厂生产的策略模式 —— 明显发现使用起来更简单,把创建bean的权利交给了简单工厂
        IFactoryStrategy businessMap = strategyByFactory.getBusinessMap(33);

        System.out.println(businessMap.eating());
        System.out.println(businessMap.play());

    }

结果:

  • 传入:11
    Java设计模式-策略模式-基于Spring实现

  • 传入:22
    Java设计模式-策略模式-基于Spring实现

  • 传入:33
    Java设计模式-策略模式-基于Spring实现文章来源地址https://www.toymoban.com/news/detail-711650.html

4、总结-工具类

  • 实现的重点在于获取Spring的bean
  • 工具类:使用springBean工具类获取beanName:
    见:https://www.cnblogs.com/kakarotto-chen/p/17760069.html
  • 项目:https://gitee.com/KakarottoChen/blog-code.git
    的:DesignDemo

到了这里,关于Java设计模式-策略模式-基于Spring实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java特性之设计模式【策略模式】

    概述 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法 主要解决 :在有多种

    2024年02月08日
    浏览(37)
  • Java设计模式之策略模式详解

    大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,让我们一同踏入Java设计模式之策略模式的世界,探讨代码中的智慧抉择。 策略模式的核心思想 策略模式是一种行为型设计模式,它定义了算法家族

    2024年01月20日
    浏览(31)
  • Java设计模式——策略

    前言 策略模式是平时Java开发中常用的一种,虽然已有很多讲解设计模式的文章,但是这里还是写篇文章来从自己理解的角度讲解一下。 我们不妨进行场景假设,要对我们的软件进行授权管理:在启动我们的软件之前先要校验是否存在合法的授权,如果授权不合法则要求用户

    2024年02月20日
    浏览(28)
  • Java设计模式之策略(Strategy)模式

    策略(Strategy)设计模式定义了一系列算法,将它们封装起来,并且可以相互替换使用,从而使得算法可以独立于使用它的客户而变化。 策略(Strategy)设计模式是一种行为型设计模式,它允许在运行时动态地选择算法。策略模式将算法封装为算法族,从而可以在运行时根据

    2024年02月15日
    浏览(32)
  • Java设计模式—策略模式(Strategy Mode)

    目录 前言 一、策略模式的简介 二、策略模式的概念 三、策略模式的作用 四、策略模式的优、缺点 策略模式的优点: 策略模式的缺点: 五、策略模式应用场景 六、代码案例 1)抽象接口类 2)具体的策略类:减 3)具体策略类:打折 4)上下文类 5)客户端Main代码测试 总结

    2024年02月08日
    浏览(31)
  • 【设计模式】Head First 设计模式——策略模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 将行为想象为一族算法,定义算法族,分别封装起来,让他们之间可以互相替换,使得算

    2024年02月11日
    浏览(27)
  • Java 大厂八股文面试专题-设计模式 工厂方法模式、策略模式、责任链模式

            在平时的开发中,涉及到设计模式的有两块内容,第一个是我们 平时使用的框架 (比如spring、mybatis等),第二个是我们自己开发业务使用的设计模式。         面试官一般比较关心的是你在开发过程中, 有没有使用过设计模式,或者你在简历上写了关于设计

    2024年02月10日
    浏览(39)
  • 用Rust实现23种设计模式之 策略模式

    灵活性:策略模式允许你在运行时动态地选择不同的算法或行为,而无需修改已有的代码。 可扩展性:通过添加新的策略类,你可以轻松地扩展策略模式的功能。 可维护性:策略模式将不同的算法或行为封装在各自的策略类中,使代码更易于理解、维护和测试。 当有多个相

    2024年02月14日
    浏览(32)
  • 设计模式 -- 策略模式(传统面向对象与JavaScript 的对比实现)

    规则:根据员工的工资基数和年底绩效情况计算年终奖 初级实现 缺点 多重 if else 违反开发-封闭原则,可维护性差 复用性差 使用组合函数重构代码 使用组合函数来重构代码,把各种算法封装到一个个的小函数里面,这些小函数有着良好的命名,可以一目了然地知道它对应着

    2024年02月11日
    浏览(32)
  • 设计模式之【策略模式】,去掉繁琐的if-else,实现算法的动态替换

    全网最全最细的【设计模式】总目录,收藏起来慢慢啃,看完不懂砍我 策略模式(Strategy Pattern)又叫政策模式(Policy Pattern),它是将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。属于行为型模式。 策略模式使用

    2024年02月09日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包