設計模式之策略模式

策略模式定義:

定義了算法族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化獨立於使用算法的客戶。

解決的問題:

在一些算法比較相似的情況下,需要有較多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 模塊了。

       }

 

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