優化if...else...語句

来源:https://www.cnblogs.com/cjsblog/archive/2023/01/16/17055846.html
-Advertisement-
Play Games

寫代碼的時候經常遇到這樣的場景:根據某個欄位值來進行不同的邏輯處理。例如,不同的會員等級在購物時有不同的折扣力度。如果會員的等級很多,那麼代碼中與之相關的if...elseif...else...會特別長,而且每新增一種等級時需要修改原先的代碼。可以用策略模式來優化,消除這種場景下的if...els ...


寫代碼的時候經常遇到這樣的場景:根據某個欄位值來進行不同的邏輯處理。例如,不同的會員等級在購物時有不同的折扣力度。如果會員的等級很多,那麼代碼中與之相關的if...elseif...else...會特別長,而且每新增一種等級時需要修改原先的代碼。可以用策略模式來優化,消除這種場景下的if...elseif...else...,使代碼看起來更優雅。

首先,定義一個介面

/**
 * 會員服務
 */
public interface VipService {
    void handle();
}

然後,定義實現類

/**
 * 白銀會員
 */
public class SilverVipService implements VipService {
    @Override
    public void handle() {
        System.out.println("白銀");
    }
}

/**
 * 黃金會員
 */
public class GoldVipService implements VipService {
    @Override
    public void handle() {
        System.out.println("黃金");
    }
}

最後,定義一個工廠類,目的是當傳入一個會員等級後,返回其對應的處理類

public class VipServiceFactory {
    private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();

    public static void register(String type, VipService service) {
        vipMap.put(type, service);
    }

    public static VipService getService(String type) {
        return vipMap.get(type);
    }
}

為了建立會員等級和與之對應的處理類之間的映射關係,這裡通常可以有這麼幾種處理方式:

方式一:實現類手動註冊

可以實現InitializingBean介面,或者在某個方法上加@PostConstruct註解

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
 * 白銀會員
 */
@Component
public class SilverVipService implements VipService, InitializingBean {
    @Override
    public void handle() {
        System.out.println("白銀");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        VipServiceFactory.register("silver", this);
    }
}

/**
 * 黃金會員
 */
@Component
public class GoldVipService implements VipService, InitializingBean {
    @Override
    public void handle() {
        System.out.println("黃金");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        VipServiceFactory.register("gold", this);
    }
}

方式二:從Spring容器中直接獲取Bean

public interface VipService {
    void handle();
    String getType();
}

/**
 * 白銀會員
 */
@Component
public class SilverVipService implements VipService {
    @Override
    public void handle() {
        System.out.println("白銀");
    }
    @Override
    public String getType() {
        return "silver";
    }
}

/**
 * 黃金會員
 */
@Component
public class GoldVipService implements VipService {
    @Override
    public void handle() {
        System.out.println("黃金");
    }
    @Override
    public String getType() {
        return "gold";
    }
}

/**
 * 上下文
 */
@Component
public class VipServiceFactory implements ApplicationContextAware {
    private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, VipService> map = applicationContext.getBeansOfType(VipService.class);
        map.values().forEach(service -> vipMap.put(service.getType(), service));
    }

    public static VipService getService(String type) {
        return vipMap.get(type);
    }
}

/**
 * 測試
 */
@SpringBootTest
class DemoApplicationTests {
    @Test
    void contextLoads() {
        VipServiceFactory.getService("silver").handle();
    }
}

方式三:反射+自定義註解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberLevel {
    String value();
}

@MemberLevel("silver")
@Component
public class SilverVipService implements VipService {
    @Override
    public void handle() {
        System.out.println("白銀");
    }
}

@MemberLevel("gold")
@Component
public class GoldVipService implements VipService {
    @Override
    public void handle() {
        System.out.println("黃金");
    }
}

/**
 * 上下文
 */
@Component
public class VipServiceFactory implements ApplicationContextAware {
    private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        Map<String, VipService> map = applicationContext.getBeansOfType(VipService.class);
        Map<String, Object> map = applicationContext.getBeansWithAnnotation(MemberLevel.class);
        for (Object bean : map.values()) {
            if (bean instanceof VipService) {
                String type = bean.getClass().getAnnotation(MemberLevel.class).value();
                vipMap.put(type, (VipService) bean);
            }
        }
    }

    public static VipService getService(String type) {
        return vipMap.get(type);
    }
}

完整示例代碼

/**
 * 結算業務種類
 * @Author: ChengJianSheng
 * @Date: 2023/1/16
 */
@Getter
public enum SettlementBusiType {
    RE1011("RE1011", "轉貼現"),
    RE4011("RE4011", "買斷式貼現"),
    RE4021("RE4021", "回購式貼現"),
    RE4022("RE4022", "回購式貼現贖回");
//    ......

    private String code;
    private String name;

    SettlementBusiType(String code, String name) {
        this.code = code;
        this.name = name;
    }
}


/**
 * 結算處理器
 * @Author: ChengJianSheng
 * @Date: 2023/1/16
 */
public interface SettlementHandler {
    /**
     * 清算
     */
    void handle();

    /**
     * 獲取業務種類
     */
    SettlementBusiType getBusiType();
}


/**
 * 轉貼現結算處理
 */
@Component
public class RediscountSettlementHandler implements SettlementHandler {
    @Override
    public void handle() {
        System.out.println("轉貼現");
    }

    @Override
    public SettlementBusiType getBusiType() {
        return SettlementBusiType.RE1011;
    }
}


/**
 * 買斷式貼現結算處理
 */
@Component
public class BuyoutDiscountSettlementHandler implements SettlementHandler {
    @Override
    public void handle() {
        System.out.println("買斷式貼現");
    }

    @Override
    public SettlementBusiType getBusiType() {
        return SettlementBusiType.RE4011;
    }
}


/**
 * 預設處理器
 * @Author: ChengJianSheng
 * @Date: 2023/1/16
 */
@Component
public class DefaultSettlementHandler implements /*SettlementHandler,*/ ApplicationContextAware {
    private static Map<SettlementBusiType, SettlementHandler> allHandlerMap = new ConcurrentHashMap<>();

    public static SettlementHandler getHandler(SettlementBusiType busiType) {
        return allHandlerMap.get(busiType);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, SettlementHandler> map = applicationContext.getBeansOfType(SettlementHandler.class);
        map.values().forEach(e -> allHandlerMap.put(e.getBusiType(), e));
    }
}


@SpringBootTest
class Demo2023ApplicationTests {
    @Test
    void contextLoads() {
        // 收到結算結果通知,根據業務種類進行結算處理
        SettlementHandler handler = DefaultSettlementHandler.getHandler(SettlementBusiType.RE1011);
        if (null != handler) {
            handler.handle();
        }
    }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • StringBuilder類 一、結構剖析 一個可變的字元序列。此類提供一個與 StringBuffer 相容的 API,但不保證同步(StringBuilder 不是線程安全的)。該類被設計用作 StringBuffer 的一個簡易替換,==用在字元串緩衝區被單個線程使用的時候==。如果可能,建議 ...
  • Typora軟體與Markdown語法 Typora軟體的安裝 ​ ==Typora是什麼軟體:== ​ Typora是一款很火的輕量級支持Markdown語法的文本編輯器 ​ ==Typora下載:== ​ mac:https://mac.qdrayst.com/02/Typora_1.1.4_m ...
  • pycharm下載安裝與基本配置 1.簡介 PyCharm是一種Python IDE(Integrated Development Environment,集成開發環境),帶有一整套可以幫助用戶在使用Python語言開發時提高其效率的工具,比如調試、語法高亮、項目管理、代碼跳轉、智能提示、自動完成、 ...
  • 原創:扣釘日記(微信公眾號ID:codelogs),歡迎分享,轉載請保留出處。 簡介 最近我觀察到一個現象,當服務的請求量突發的增長一下時,服務的有效QPS會下降很多,有時甚至會降到0,這種現象網上也偶有提到,但少有解釋得清楚的,所以這裡來分享一下問題成因及解決方案。 隊列延遲 目前的Web伺服器, ...
  • CF鏈接:Least Prefix Sum Luogu鏈接:Least Prefix Sum $ {\scr \color {CornflowerBlue}{\text{Solution}}} $ 先來解釋一下題意: 給定一個數組,問最少把多少個數變成相反數,使得$ \forall \cal{i}$ ...
  • Spring管理Bean-IOC 1.Spring配置/管理bean介紹 Bean管理包括兩方面: 創建bean對象 給bean註入屬性 Bean的配置方式: 基於xml文件配置方式 基於註解配置方式 2.基於XML配置bean 2.1通過類型來獲取bean 通過id來獲取bean在Spring基本 ...
  • 1、yaml文件準備 common: secretid: AKIDxxxxx secretKey: 3xgGxxxx egion: ap-guangzhou zone: ap-guangzhou-7 InstanceChargeType: POSTPAID_BY_HOUR 2、config配置類準備 ...
  • 簡介 Netflix Eureka是微服務系統中最常用的服務發現組件之一,非常簡單易用。當客戶端註冊到Eureka後,客戶端可以知道彼此的hostname和埠等,這樣就可以建立連接,不需要配置。 Eureka 服務端 添加Maven依賴: <dependency> <groupId>org.spr ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...