ToB企服应用市场:ToB评测及商务社交产业平台

标题: Java设计模式-策略模式-基于Spring实现 [打印本页]

作者: 惊雷无声    时间: 2023-10-30 03:47
标题: Java设计模式-策略模式-基于Spring实现
1、策略模式

1.1、概述

策略模式是一种行为设计模式,它允许在运行时选择算法的行为。它将算法封装在独立的策略类中,使得它们可以相互替换,而不影响客户端代码。这种模式通过将算法的选择从客户端代码中分离出来,提供了更大的灵活性和可维护性。
在Java中,策略模式的设计理念可以通过以下步骤实现:
在你提供的代码片段中,我无法确定与策略模式相关的代码。如果你有更多的上下文或示例代码,我可以更好地帮助你理解和应用策略模式。
1.2、优缺点

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

2.1、实现步奏


2.2、实现

①定义策略接口
  1. package com.cc.eed.strategy;
  2. /**
  3. * <p>基于SpringBean的策略模式</p>
  4. *
  5. * @author CC
  6. * @since 2023/10/13
  7. */
  8. public interface ISpringBeanStrategy {
  9.     /**
  10.      * 吃饭
  11.      */
  12.     String eating();
  13.     /**
  14.      * 玩
  15.      */
  16.     String play();
  17. }
复制代码
②定义实现类1
  1. package com.cc.eed.strategy.impl;
  2. import com.cc.eed.strategy.ISpringBeanStrategy;
  3. import org.springframework.stereotype.Component;
  4. /**
  5. * <p>小美</p>
  6. *
  7. * @author CC
  8. * @since 2023/10/13
  9. */
  10. @Component
  11. public class MeiSpringBeanImpl implements ISpringBeanStrategy {
  12.     /**
  13.      * 吃饭
  14.      */
  15.     @Override
  16.     public String eating() {
  17.         return "小美,吃饭!";
  18.     }
  19.     /**
  20.      * 玩
  21.      */
  22.     @Override
  23.     public String play() {
  24.         return "小美,玩!";
  25.     }
  26. }
复制代码
定义实现类2
  1. package com.cc.eed.strategy.impl;
  2. import com.cc.eed.strategy.ISpringBeanStrategy;
  3. import org.springframework.stereotype.Component;
  4. /**
  5. * <p>小明</p>
  6. *
  7. * @author CC
  8. * @since 2023/10/13
  9. */
  10. @Component
  11. public class MingSpringBeanImpl implements ISpringBeanStrategy {
  12.     /**
  13.      * 吃饭
  14.      */
  15.     @Override
  16.     public String eating() {
  17.         return "小明,吃饭!";
  18.     }
  19.     /**
  20.      * 玩
  21.      */
  22.     @Override
  23.     public String play() {
  24.         return "小明,玩!";
  25.     }
  26. }
复制代码
③定义beanName的枚举
  1. package com.cc.eed.enums;
  2. import lombok.Getter;
  3. import org.springframework.util.Assert;
  4. import java.util.Arrays;
  5. /**
  6. * <p></p>
  7. *
  8. * @author CC
  9. * @since 2023/10/13
  10. */
  11. @Getter
  12. public enum PeopleEnum {
  13.     MING(1, "小明", "mingSpringBeanImpl"),
  14.     MEI(2, "小美", "meiSpringBeanImpl")
  15.     ;
  16.     public Integer type;
  17.     public String name;
  18.     public String beanName;
  19.     /** <p>根据类型获取beanName<p>
  20.      * @param type type
  21.      * @return {@link String}
  22.      * @since 2023/10/13
  23.      * @author CC
  24.      **/
  25.     public static String getBeanName(Integer type) {
  26.         PeopleEnum peopleEnum = Arrays.stream(values())
  27.                 .filter(p -> p.getType().equals(type))
  28.                 .findAny().orElse(null);
  29.         Assert.notNull(peopleEnum, "暂不支持的策略模式!");
  30.         return peopleEnum.getBeanName();
  31.     }
  32.     PeopleEnum(Integer type, String name, String beanName) {
  33.         this.type = type;
  34.         this.name = name;
  35.         this.beanName = beanName;
  36.     }
  37.     public void setType(Integer type) {
  38.         this.type = type;
  39.     }
  40.     public void setName(String name) {
  41.         this.name = name;
  42.     }
  43.     public void setBeanName(String beanName) {
  44.         this.beanName = beanName;
  45.     }
  46. }
复制代码
④使用springBean工具类获取beanName
⑤使用
  1. @Test
  2. public void test02()throws Exception{
  3.     //根据BeanName获取具体的bean,实现策略模式
  4.     //根据人员ID(或者类型)获取不同的bean
  5.     String beanName = PeopleEnum.getBeanName(1);
  6.     ISpringBeanStrategy bean = (ISpringBeanStrategy) SpringBeanUtil.getBean(beanName);
  7.     String eating = bean.eating();
  8.     System.out.println(eating);
  9.     String play = bean.play();
  10.     System.out.println(play);
  11. }
复制代码
3、简单工厂模式实现(推荐)

3.1、实现步奏


3.2、实现

①定义策略接口
  1. package com.cc.eed.strategy;
  2. /**
  3. * <p>简单工厂模式 - 实现的策略模式</p>
  4. *
  5. * @author CC
  6. * @since 2023/10/13
  7. */
  8. public interface IFactoryStrategy {
  9.     /**
  10.      * 吃饭
  11.      */
  12.     String eating();
  13.     /**
  14.      * 玩
  15.      */
  16.     String play();
  17. }
复制代码
②生产策略bean的工厂
  1. package com.cc.eed.strategy;
  2. import com.cc.eed.enums.PirateEnum;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.beans.factory.annotation.Qualifier;
  5. import org.springframework.stereotype.Component;
  6. import org.springframework.util.Assert;
  7. import javax.annotation.Resource;
  8. import java.util.Map;
  9. import java.util.concurrent.ConcurrentHashMap;
  10. /**
  11. * <p>简单工厂</p>
  12. * <li>可以生产多个策略</li>
  13. *
  14. * @author CC
  15. * @since 2023/10/13
  16. */
  17. @Component
  18. public class StrategyByFactory {
  19.     /**
  20.      * 1、批量注入实现了 IFactoryStrategy 的Bean。
  21.      * 2、用bean的数量当做map的大小
  22.      */
  23.     @Resource
  24.     private final Map<String, IFactoryStrategy> BUSINESS_FACTORY = new ConcurrentHashMap<>(PirateEnum.values().length);
  25.     //生成的策略...
  26.     /** <p>根据类获取不同的Bean<p>
  27.      * @param type type
  28.      * @return {@link IFactoryStrategy}
  29.      * @since 2023/10/13
  30.      * @author CC
  31.      **/
  32.     public IFactoryStrategy getBusinessMap(Integer type){
  33.         Assert.notNull(type, "类型不能为空!");
  34.         String beanName = PirateEnum.getBeanName(type);
  35.         return BUSINESS_FACTORY.get(beanName);
  36.     }
  37.     //生成的其他策略...
  38. }
复制代码
③策略实现类1
  1. package com.cc.eed.strategy.impl;
  2. import com.cc.eed.enums.PirateEnum;
  3. import com.cc.eed.strategy.IFactoryStrategy;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * <p>路飞</p>
  7. *
  8. * @author CC
  9. * @since 2023/10/13
  10. */
  11. @Component(PirateEnum.LF_BEAN_NAME)
  12. public class LuFeiFactoryStrategy implements IFactoryStrategy {
  13.     /**
  14.      * 吃饭
  15.      */
  16.     @Override
  17.     public String eating() {
  18.         return "路飞,吃饭!";
  19.     }
  20.     /**
  21.      * 玩
  22.      */
  23.     @Override
  24.     public String play() {
  25.         return "路飞,玩!";
  26.     }
  27. }
复制代码
③策略实现类2
  1. package com.cc.eed.strategy.impl;
  2. import com.cc.eed.enums.PirateEnum;
  3. import com.cc.eed.strategy.IFactoryStrategy;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * <p>明哥</p>
  7. *
  8. * @author CC
  9. * @since 2023/10/13
  10. */
  11. @Component(PirateEnum.MG_BEAN_NAME)
  12. public class MingGgFactoryStrategy implements IFactoryStrategy {
  13.     /**
  14.      * 吃饭
  15.      */
  16.     @Override
  17.     public String eating() {
  18.         return "明哥,吃饭!";
  19.     }
  20.     /**
  21.      * 玩
  22.      */
  23.     @Override
  24.     public String play() {
  25.         return "明哥,玩!";
  26.     }
  27. }
复制代码
④定义beanName的枚举
  1. package com.cc.eed.enums;
  2. import org.springframework.util.Assert;
  3. import java.util.Arrays;
  4. /**
  5. * <p></p>
  6. *
  7. * @author CC
  8. * @since 2023/10/13
  9. */
  10. public enum PirateEnum {
  11.     MG(11, "明哥", PirateEnum.MG_BEAN_NAME),
  12.     LF(22, "路飞", PirateEnum.LF_BEAN_NAME)
  13.     ;
  14.     public Integer type;
  15.     public String name;
  16.     public String beanName;
  17.     /**
  18.      * 自定义的beanName
  19.      */
  20.     public static final String MG_BEAN_NAME = "mingGg_11";
  21.     public static final String LF_BEAN_NAME = "luFei_22";
  22.     /** <p>根据类型获取beanName<p>
  23.      * @param type type
  24.      * @return {@link String}
  25.      * @since 2023/10/13
  26.      * @author CC
  27.      **/
  28.     public static String getBeanName(Integer type) {
  29.         PirateEnum pirateEnum = Arrays.stream(values())
  30.                 .filter(p -> p.getType().equals(type))
  31.                 .findAny().orElse(null);
  32.         Assert.notNull(pirateEnum, "暂不支持的策略模式!");
  33.         return pirateEnum.getBeanName();
  34.     }
  35.     PirateEnum(Integer type, String name, String beanName) {
  36.         this.type = type;
  37.         this.name = name;
  38.         this.beanName = beanName;
  39.     }
  40.     public Integer getType() {
  41.         return type;
  42.     }
  43.     public void setType(Integer type) {
  44.         this.type = type;
  45.     }
  46.     public String getName() {
  47.         return name;
  48.     }
  49.     public void setName(String name) {
  50.         this.name = name;
  51.     }
  52.     public String getBeanName() {
  53.         return beanName;
  54.     }
  55.     public void setBeanName(String beanName) {
  56.         this.beanName = beanName;
  57.     }
  58. }
复制代码
⑤使用springBean工具类获取beanName
⑥使用
  1.     @Resource
  2.     private StrategyByFactory strategyByFactory;
  3.     @Test
  4.     public void test03()throws Exception{
  5.         //使用简单工厂生产的策略模式 —— 明显发现使用起来更简单,把创建bean的权利交给了简单工厂
  6.         IFactoryStrategy businessMap = strategyByFactory.getBusinessMap(33);
  7.         System.out.println(businessMap.eating());
  8.         System.out.println(businessMap.play());
  9.     }
复制代码
结果:
4、总结-工具类


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4