策略模式解决if-else问题

2024-01-10 13:50:45

释义:

策略模式是一种行为设计模式,它允许在运行时根据不同的情况来选择不同的策略。

这种模式支持开闭原则,在不修改现有代码的前提下,动态的添加、删除、替换算法。

组成部分:

策略接口(Strategy):它是一个接口,具体的策略实现类去实现这个接口,就可以提供不同的实现方式。

策略环境(Context):可以根据需要来修改策略,或者定义一个工厂类

策略实现类(ConcreteStrategy):以Strategy接口实现某具体算法

代码实现步骤:

1、定义Strategy接口(Strategy)

package com.example.strategy.service;


import com.example.strategy.entity.ResourcesEntity;

/**
 * 获取资源信息策略接口
 *
 */
public interface ResourcesStrategy {


    /*
    * 获取对应资源信息
    * 专家、队伍、装备
    * */
    ResourcesEntity getResourcesData(String type);


}

2、实体类、常量类定义(entity、constant)

//返回实体类
package com.example.strategy.entity;


import lombok.Data;

@Data
public class ResourcesEntity {

    private String name;
    private String lat;
    private String lng;

    private String resourcesType;

}

//常量类
package com.example.strategy.constant;

public class ResourcesConstant {
    public static final String EXPERT = "expert";
    public static final String EQUIP = "equip";
    public static final String MATERIALS = "materials";
    public static final String TEAM = "team";
}

3、具体的策略实现类(EquipStrategy、ExpertStrategy、TeamStrategy)

//装备策略实现类
package com.example.strategy;

import com.example.strategy.constant.ResourcesConstant;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.stereotype.Component;


@Component(ResourcesConstant.EQUIP)
public class EquipStrategy implements ResourcesStrategy {
    @Override
    public ResourcesEntity getResourcesData(String type) {
        ResourcesEntity resources = new ResourcesEntity();
        resources.setResourcesType(ResourcesEnum.EQUIP.id);
        resources.setName("装备");
        resources.setLng("");
        resources.setLat("");
        return resources;
    }
}

//专家策略实现类

package com.example.strategy;

import com.example.strategy.constant.ResourcesConstant;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.stereotype.Component;


@Component(ResourcesConstant.EXPERT)
public class ExpertStrategy implements ResourcesStrategy {
    @Override
    public ResourcesEntity getResourcesData(String type) {
        ResourcesEntity resources = new ResourcesEntity();
        resources.setResourcesType(ResourcesEnum.EXPERT.id);
        resources.setName("李安心专家");
        resources.setLng("");
        resources.setLat("");
        return resources;
    }
}


//队伍策略实现类
package com.example.strategy;

import com.example.strategy.constant.ResourcesConstant;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.stereotype.Component;


@Component(ResourcesConstant.TEAM)
public class TeamStrategy implements ResourcesStrategy {
    @Override
    public ResourcesEntity getResourcesData(String type) {
        ResourcesEntity resources = new ResourcesEntity();
        resources.setResourcesType(ResourcesEnum.TEAM.id);
        resources.setName("队伍1");
        resources.setLng("");
        resources.setLat("");
        return resources;
    }
}

4、策略环境(上下文)Context

package com.example.strategy.context;


import com.example.strategy.service.ResourcesStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class ResourcesStrategyContext {


    /*
    * 策略集合
    * 注入实例名和对应实例
    * */
    @Autowired
    private Map<String, ResourcesStrategy>  resourcesStrategyMap = new ConcurrentHashMap<>();


    /*
    * 初始化
    * */
    public ResourcesStrategyContext(Map<String, ResourcesStrategy> resourcesStrategyMap){
        //先进行清空处理
        this.resourcesStrategyMap.clear();
        //由于我们的具体策略实现业务类使用了@Component注解,所以会被spring自动扫描并且装配到容器中
        resourcesStrategyMap.forEach(this.resourcesStrategyMap::put);

    }

    public ResourcesStrategy getResourcesStrategy(String strategy){
        return  resourcesStrategyMap.get(strategy);
    }

}

5、功能验证

package com.example.strategy.controller;
import com.example.demo.util.StringUtils;
import com.example.strategy.context.ResourcesStrategyContext;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/resources")
public class ResourcesController {

    @Autowired
    ResourcesStrategyContext resourcesStrategyContext;

    @RequestMapping("/getResourcesData")
    public ResourcesEntity getResourcesData(String type){
        ResourcesStrategy resourcesStrategy = resourcesStrategyContext.getResourcesStrategy(type);
        ResourcesEntity resourcesData = resourcesStrategy.getResourcesData(type);
        return resourcesData;
    }
}

6、结果展示

7、策略模式和if-esle比较:?

1、易于拓展:不需要修改原有代码,方便的增加、删除算法。

2、提高代码可读性:不同的业务处理在不同的策略实现类中,易于理解和维护

3、避免大量的if-else语句

4、提高代码复用性

文章来源:https://blog.csdn.net/weixin_43005845/article/details/135499240
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。