设计模式之策略模式

策略模式定义:

定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

解决的问题:

在一些算法比较相似的情况下,需要有较多if...else 或者switch case的时候,代码比较复杂并且难以维护。

工作中的业务需求:

实现直播勋章系统时,涉及到每个区域(评论区,连麦区,房主区,进场特效区域)的勋章展示逻辑不一样。一开始,使用switch...case...处理每个区域的逻辑,感觉代码比较复杂。后来,把每个区域抽象成一个类,把每个区域的处理逻辑交给对应的类去处理。基于spring框架的ApplicationContextAware接口,使用策略模式实现了该业务逻辑。一下是demo:

 1)创建勋章区域枚举:

   public enum MedalRegionEnum{

  OWNER_REGION_MEDAL(1,"房主区域"),
  AUDIENCE_REGION_MEDAL(2,"观众席区域"),
 ENTER_SPECIAL_REGION_MEDAL(3,"进场特效区域"),;
MedalRegionEnum(int index, String desc) {
    this.index = index;
    this.desc = desc;
}
private int index;

private String desc;
public int getIndex() {
    return index;
}
public String getDesc() {
    return desc;
}

   }

   2)创建勋章区域服务接口。

 public interface IMedalRegionService {
   //过滤以及排序勋章服务
    List<MedalPO> filterAndSortMedals(List<MedalPO> list);
   //对应区域枚举
    MedalRegionEnum getRegionEnum();
 }

  3)创建一个抽象类,一个过滤勋章的虚函数,一个排序勋章的函数

  public abstract class AbstractRegionService implements IMedalRegionService {

    abstract List<MedalPO> filterMedals(List<MedalPO> medalPOList);

    List<MedalPO> sortMedals(List<MedalPO> medalPOList){

    //sort medalPOList

   } 

}

 4)创建每个区域具体的勋章服务(RegionAudienceServiceImpl,RegionOwnerServiceImpl,RegionEnterServiceImpl),

    继承AbstractRegionService服务。

  eg:

   @Service

     public class RegionOwnerServiceImpl extends AbstractRegionService {

        List<MedalPO> filterMedals(List<MedalPO> medalPOList){

        //doSomething 房主区域勋章的具体排序

        }

      @Override

        public MedalRegionEnum getRegionEnum()

        { return MedalRegionEnum.OWNER_REGION_MEDAL; }

    }

    6)创建需要用勋章服务

    @Service

     public class MedalServiceImpl implements IMedalService, ApplicationContextAware {

       private Map<MedalRegionEnum, IMedalRegionService> regionServiceMap = new ConcurrentHashMap<>();

       //setApplicationContext方法初始化regionServiceMap

    @Override

     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

   Map<String, IMedalRegionService> regionTempMap = applicationContext.getBeansOfType(IMedalRegionService.class);       regionTempMap.values().forEach(iMedalRegionService -> regionServiceMap.put(iMedalRegionService.getRegionEnum(),       iMedalRegionService)); }

    //接着可以用regionServiceMap替换可恶的if...else/switch ..case 模块了。

       }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章