<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一種思路:策略模式 + 反射工廠,很好的實現(xiàn)了開閉原則

          共 15362字,需瀏覽 31分鐘

           ·

          2021-09-13 18:14

          作者 | 麻辣你個王子

          來源 | blog.csdn.net/qq_28675967/article/details/90581208


          應用場景:某天接到了一個需求,品牌給了一個第三方接口,例如:www.baidu.com,我們通過調用這個第三接口,會返回4種狀態(tài),ex:

          • String pageStatus = "pdpAdvertisePage"; 代表我們經(jīng)過一堆處理后要返回的是pdp廣告頁面
          • String pageStatus = "plpAdvertisePage"; 代表我們經(jīng)過一堆業(yè)務處理后要返回的是plp廣告頁面
          • String pageStatus = "shoppingCartAdvertisePage"; 代表我們經(jīng)過一堆業(yè)務處理后要返回的是購物車廣告頁面
          • String pageStatus = "checkoutAdvertisePage"; 代表我們經(jīng)過一堆業(yè)務處理后要返回的是購物車廣告頁面

          期間的解決方案一: 做了好多的判斷 if elseif elseif 寫到后面我都不知道里面的判斷邏輯是啥,太復雜了,果斷放棄了

          期間的解決方案二: 利用了策略模式+簡單工廠模式,總算把那些個if else給去掉了,邏輯算是比較清晰了

          期間的解決方案三: 利用策略模式+反射工廠,很完美的解決了簡單工廠模式所帶來的弊端 -- 實現(xiàn)了所謂的開閉原則

          代碼目錄結構:

          公共的接口:GetPointAdvertisePageStrategey.java

          import org.springframework.ui.Model;
           
          /**
           * @author : David.liu
           * @description : 得到指定廣告頁面
           * @creat :2019-05-26-22:02
           */

          public interface GetPointAdvertisePageStrategey {
           
              /**
               * 得到指定的頁面
               * @param itemRecommendParam
               * @param model
               * @return
               */

              String getAdvertisePage(Model model);
          }

          Ppd實現(xiàn)接口代碼:PdpAdvertisePageStrategey.java

          import org.springframework.stereotype.Component;
          import org.springframework.ui.Model;
           
          /**
           * @author : David.liu
           * @description : 得到pdp廣告頁面
           * @creat :2019-05-26-22:05
           */

          @Component
          public class PdpAdvertisePageStrategey implements  GetPointAdvertisePageStrategey{
           
              /**
               * 得到指定的頁面
               *
               * @param itemRecommendParam
               * @param model
               * @return
               */

              @Override
              public String getAdvertisePage() {
                  return "pdp-advertise.jsp";
              }
          }

          Plp實現(xiàn)接口代碼:PlpAdvertisePageStrategey.java

          import org.springframework.stereotype.Component;
          import org.springframework.ui.Model;
           
          /**
           * @author : David.liu
           * @description : 得到指定的plp廣告頁面
           * @creat :2019-05-26-22:07
           */

          @Component
          public class PlpAdvertisePageStrategey implements GetPointAdvertisePageStrategey {
              /**
               * 得到指定的plp廣告頁面
               *
               * @param itemRecommendParam
               * @param model
               * @return
               */

              @Override
              public String getAdvertisePage() {
                  return "plp-advertise.jsp";
              }
          }

          購物車實現(xiàn)接口代碼 ShopingCartAdvertisePageStrategey.java

          import org.springframework.stereotype.Component;
          import org.springframework.ui.Model;
           
          /**
           * @author : David.liu
           * @description : 得到購物車廣告頁面
           * @creat :2019-05-26-22:10
           */

          @Component
          public class ShopingCartAdvertisePageStrategey implements  GetPointAdvertisePageStrategey {
              /**
               * 得到指定的購物車頁面
               *
               * @param model
               * @return
               */

              @Override
              public String getAdvertisePage() {
                  return "shoppingcart-advertise.jsp";
              }
          }

          結算實現(xiàn)接口代碼:CheckoutAdvertisePageStrategey.java

          import org.springframework.stereotype.Component;
          import org.springframework.ui.Model;
           
          /**
           * @author : David.liu
           * @description : 得到結算頁面廣告頁面
           * @creat :2019-05-26-22:12
           */

          @Component
          public class CheckoutAdvertisePageStrategey implements  GetPointAdvertisePageStrategey {
              /**
               * 得到指定的結算頁面
               *
               * @param itemRecommendParam
               * @param model
               * @return
               */

              @Override
              public String getAdvertisePage() {
                  return "checkout-advertise.jsp";
              }
          }

          生產(chǎn)廣告頁面。簡單工廠類 GetPointAdvertisePageReflectFactory.java,案例未使用,但代碼貼出來了,供讀者對比兩個的差異,感受一下,開閉原則,對比一下,簡單工廠和反射工廠的不同。

          如果您正在學習Spring Boot,推薦一個連載多年還在繼續(xù)更新的免費教程:http://blog.didispace.com/spring-boot-learning-2x/

          思考角度,如果需求在加一個策略類,2個、3個?那么你就感受到了

          import com.feilong.core.Validator;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.stereotype.Component;
           
          import java.util.HashMap;
          import java.util.Map;
           
          /**
           * @author : David.liu
           * @description : 生產(chǎn)廣告頁面簡單工廠
           * @creat :2019-05-26-22:14
           */

          @Component
          public class GetPointAdvertisePageSimpleFactory {
              public static final String PDP_ITEM_ADVERTISE = "PDP_ITEM_ADVERTISE";
              public static final String PLP_ITEM_ADVERTISE = "PLP_ITEM_ADVERTISE";
              public static final String CHECKOUT_ITEM_ADVERTISE = "CHECKOUT_ITEM_ADVERTISE";
              public static final String SHOPPINGCART_ITEM_ADVERTISE = "SHOPPINGCART_ITEM_ADVERTISE";
           
              private static Map<String, GetPointAdvertisePageStrategey> recommendStrategyMap = new HashMap<>();
           
              @Autowired
              private CheckoutAdvertisePageStrategey checkoutAdvertisePageStrategey;
              @Autowired
              private PdpAdvertisePageStrategey pdpAdvertisePageStrategey;
              @Autowired
              private PlpAdvertisePageStrategey plpAdvertisePageStrategey;
              @Autowired
              private ShopingCartAdvertisePageStrategey shopingCartAdvertisePageStrategey;
           
              /** 初始化所有的策略類 */
              protected void init(){
                  recommendStrategyMap.put(PDP_ITEM_ADVERTISE, pdpAdvertisePageStrategey);
                  recommendStrategyMap.put(PLP_ITEM_ADVERTISE,plpAdvertisePageStrategey );
                  recommendStrategyMap.put(CHECKOUT_ITEM_ADVERTISE, checkoutAdvertisePageStrategey);
                  recommendStrategyMap.put(SHOPPINGCART_ITEM_ADVERTISE,shopingCartAdvertisePageStrategey );
              }
           
              /** 根據(jù)pageType 得到指定的處理類 */
              public GetPointAdvertisePageStrategey getStrategey(String pageType) {
                  if(Validator.isNullOrEmpty(recommendStrategyMap)){
                      init();
                  }
                  return recommendStrategyMap.get(pageType);
              }
          }

          生產(chǎn)廣告頁面。反射工廠類 GetPointAdvertisePageReflectFactory.java

          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
          import org.springframework.context.ApplicationContext;
          import org.springframework.stereotype.Component;
           
          /**
           * @author : David.liu
           * @description : 生產(chǎn)廣告頁面反射工廠
           * @creat :2019-05-26-22:15
           */

          @Component
          public class GetPointAdvertisePageReflectFactory {
              @Autowired
              private ApplicationContext context;
              private static final Logger LOGGER = LoggerFactory.getLogger(GetPointAdvertisePageReflectFactory.class);
              // 通過配置文件名:filePathName   和 文件中的key 得到指定的類
              public GetPointAdvertisePageStrategey getAdvertisePageStrategey(String filePathName, String key){
                  GetPointAdvertisePageStrategey getPointAdvertisePageStrategey = null;
                  String classPath = null;
                  try {
                      classPath = PropertyUtil.get(filePathName,key);
                      if(Validator.isNullOrEmpty(classPath)) return null;
                      //通過反射創(chuàng)建對象
                      Class<?> handler = Class.forName(classPath);
                      //這里必須強行納入spring管理,否則在得到的具體實現(xiàn)類中,如果有通過@Autowired注入的bean,將會報注入失敗
                      getPointAdvertisePageStrategey = (GetPointAdvertisePageStrategey) context.getAutowireCapableBeanFactory().createBean(handler, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
                  } catch (Exception e) {
                      LOGGER.error("Failed to reflect the corresponding object through the specified path,filePath:{},key:{}",filePathName,key);
                      return null;
                  }
                  return getPointAdvertisePageStrategey;
              }
          }

          文件讀取工具類: PropertyUtil.java

          import com.feilong.core.Validator;
           
          import java.io.IOException;
          import java.io.InputStream;
          import java.util.HashMap;
          import java.util.Map;
          import java.util.Properties;
           
          /**
           *  獲取配置文件參數(shù)工具類
           *  擁有緩存功能,當查詢了某個文件時會自動緩存
           *  @author wei.liu5
           *  @Date 2019/5/20
           */

          public class PropertyUtil {
              private static Map<String, Properties> cache = new HashMap<>();
           
              /**
               *
               * @param configFileName 配置文件名
               * @param key  配置文件中的 key=value  中的key
               * @return
               */

              public static String get(String configFileName,String key){
                  return getProperties(configFileName).getProperty(key);
              }
           
              public static Properties getProperties(String configFileName) {
                  if (Validator.isNotNullOrEmpty(cache.get(configFileName))) {
                      return cache.get(configFileName);
                  }
                  InputStream inputStream = PropertyUtil.class.getResourceAsStream(configFileName);
                  Properties properties = new Properties();
                  try {
                      properties.load(inputStream);
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
                  cache.put(configFileName,properties);
                  return  properties;
              }
           
          }

          配置文件:itemrecommend.properties

          # 下面是每個實現(xiàn)類的具體路徑,利用反射的原理來達到獲取某個具體類的目的
          pdp.item.advertise=com.wy.store.web.manager.PdpAdvertisePageStrategey
          plp.item.advertise=com.wy.store.web.manager.PlpAdvertisePageStrategey
          shoppingcart.item.advertise=com.wy.store.web.manager.ShopingCartAdvertisePageStrategey
          checkout.item.advertise=com.wy.store.web.manager.CheckoutAdvertisePageStrategey

          測試類:測試代碼用的是 策略模式+反射工廠,這里未使用簡單工廠,但代碼也貼出來了

          import com.feilong.core.Validator;
          import org.junit.Test;
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          import org.springframework.beans.factory.annotation.Autowired;
           
           
          public class ItemRecommendReflectFactoryTest {
              private static final Logger LOGGER = LoggerFactory.getLogger(ItemRecommendReflectFactoryTest.class);
              @Autowired
              private GetPointAdvertisePageReflectFactory getItemRecommendStrategey;
           
              @Test
              public void  refectFactoryTest(){
                  String path = "/itemrecommend.properties";
                  GetPointAdvertisePageStrategey getPointAdvertisePageStrategey = getItemRecommendStrategey.getAdvertisePageStrategey(path,"pdp.item.advertise");
                  if(Validator.isNotNullOrEmpty(getPointAdvertisePageStrategey)){
                      LOGGER.info("通過配置文件和反射機制,在運行時動態(tài)獲取指定的執(zhí)行類,測試成功");
                      LOGGER.info(getPointAdvertisePageStrategey.getAdvertisePage());
                  }
              }
          }

          - END -

          往期推薦

          如何更快地將string轉換成int/long

          OAuth2 服務器Keycloak中的Realm

          Java 17 將至,可能帶來哪些新特性呢?

          機械妖姬上門要源碼后續(xù)結果來了!

          重磅消息:Spring 6 和Spring Boot 3



          喜歡本文歡迎轉發(fā),關注我訂閱更多精彩

          關注我回復「加群」,加入Spring技術交流群

          瀏覽 43
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品午夜福利电影 | 青青草美女视频 | 99国产香蕉 | 国产内射免费观看视频 | 色就是色setufree |