精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Java 枚舉與策略模式、函數(shù)式接口的結(jié)合:實(shí)現(xiàn)高內(nèi)聚低耦合的設(shè)計(jì)

京東云 ? 來(lái)源:jf_75140285 ? 作者:jf_75140285 ? 2024-11-21 14:06 ? 次閱讀

作者:京東物流 楊唯一

一、Java 枚舉類

Java 枚舉是一個(gè)特殊的類,一般表示一組常量,比如一年的 4 個(gè)季節(jié),一年的 12 個(gè)月份,一個(gè)星期的 7 天,方向有東南西北等。

我們?cè)跇I(yè)務(wù)需求開發(fā)中,通常會(huì)使用枚舉來(lái)定義業(yè)務(wù)上的一組常量,那除了簡(jiǎn)單地定義常量之外,我們?nèi)绾卫妹杜e來(lái)實(shí)現(xiàn)高內(nèi)聚、低耦合的設(shè)計(jì)呢?下面介紹下枚舉和策略模式、函數(shù)式接口的組合應(yīng)用。

二、枚舉+策略模式

首先介紹下策略模式,已經(jīng)掌握策略模式的同學(xué)可以直接跳過(guò)此部分。

1、策略模式

策略模式(Strategy Pattern)屬于對(duì)象的行為模式。其用意是針對(duì)一組算法,將每一個(gè)算法封裝到具有共同接口的獨(dú)立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發(fā)生變化。 其主要目的是通過(guò)定義相似的算法,替換if else 語(yǔ)句寫法,并且可以隨時(shí)相互替換。

策略模式主要由這三個(gè)角色組成,環(huán)境角色(Context)、抽象策略角色(Strategy)和具體策略角色(ConcreteStrategy)。

?環(huán)境角色(Context):持有一個(gè)策略類的引用,提供給客戶端使用。

?抽象策略角色(Strategy):這是一個(gè)抽象角色,通常由一個(gè)接口或抽象類實(shí)現(xiàn)。此角色給出所有的具體策略類所需的接口。

?具體策略角色(ConcreteStrategy):包裝了相關(guān)的算法或行為。

這里為了方便理解,我們就拿剛學(xué)習(xí)Java的時(shí)候使用計(jì)算方法來(lái)說(shuō)吧。 在使用計(jì)算器進(jìn)行計(jì)算的時(shí)候,會(huì)經(jīng)常用到加減乘除方法。如果我們想得到兩個(gè)數(shù)字相加的和,我們需要用到“+”符號(hào),得到相減的差,需要用到“-”符號(hào)等等。雖然我們可以通過(guò)字符串比較使用if/else寫成通用方法,但是計(jì)算的符號(hào)每次增加,我們就不得不加在原先的方法中進(jìn)行增加相應(yīng)的代碼,如果后續(xù)計(jì)算方法增加、修改或刪除,那么會(huì)使后續(xù)的維護(hù)變得困難。 但是在這些方法中,我們發(fā)現(xiàn)其基本方法是固定的,這時(shí)我們就可以通過(guò)策略模式來(lái)進(jìn)行開發(fā),可以有效避免通過(guò)if/else來(lái)進(jìn)行判斷,即使后續(xù)增加其他的計(jì)算規(guī)則也可靈活進(jìn)行調(diào)整。

首先定義一個(gè)抽象策略角色,并擁有一個(gè)計(jì)算的方法。

interface CalculateStrategy {
   int doOperation(int num1, int num2);
}

然后再定義加減乘除這些具體策略角色并實(shí)現(xiàn)方法。

代碼如下:

class OperationAdd implements CalculateStrategy {
    @Override 
    public int doOperation(int num1, int num2) {
         return num1 + num2; 
    } 
}
class OperationSub implements CalculateStrategy {
    @Override 
    public int doOperation(int num1, int num2) { 
        return num1 - num2;
    } 
}

class OperationMul implements CalculateStrategy {
    @Override 
    public int doOperation(int num1, int num2) { 
        return num1 * num2; 
    } 
}

class OperationDiv implements CalculateStrategy { 
    @Override 
    public int doOperation(int num1, int num2) { 
        return num1 / num2; 
    } 
}

最后在定義一個(gè)環(huán)境角色,提供一個(gè)計(jì)算的接口供客戶端使用。 代碼如下:

class CalculatorContext { 
    private CalculateStrategy strategy; 
   
    public CalculatorContext(CalculateStrategy strategy) {
        this.strategy = strategy; 
    } 
    public int executeStrategy(int num1, int num2) { 
        return strategy.doOperation(num1, num2); 
    }
}

編寫好之后,那么我們來(lái)進(jìn)行測(cè)試。 測(cè)試代碼如下:

public static void main(String[] args) {
    int a=4,b=2;

    CalculatorContext context = new CalculatorContext(new OperationAdd());
    System.out.println("a + b = "+context.executeStrategy(a, b));

    CalculatorContext context2 = new CalculatorContext(new OperationSub());
    System.out.println("a - b = "+context2.executeStrategy(a, b));

    CalculatorContext context3 = new CalculatorContext(new OperationMul());
    System.out.println("a * b = "+context3.executeStrategy(a, b));

    CalculatorContext context4 = new CalculatorContext(new OperationDiv());
    System.out.println("a / b = "+context4.executeStrategy(a, b)); }

輸出結(jié)果:

 a + b = 6
 a - b = 2 
 a * b = 8 
 a / b = 2

上面這段是網(wǎng)上常見的對(duì)于策略模式的介紹和示例,但在這段測(cè)試代碼中,我們對(duì)于策略的選擇依然是在具體的調(diào)用處通過(guò)對(duì)CalculatorContext類構(gòu)造器的傳參去指定的,那么如何能動(dòng)態(tài)地選擇策略并將選擇策略的具體邏輯抽取,就要用到枚舉+策略這套組合拳啦。

2、枚舉+策略模式的使用

定義策略模式的枚舉類,并將具體策略的 bean 名稱作為枚舉類 strategy 的值;

在getStrategyEnum方法中,我們可以去實(shí)現(xiàn)選擇策略的邏輯,將選擇策略的判斷邏輯內(nèi)聚在枚舉類中,與業(yè)務(wù)代碼隔離,當(dāng)然在具體業(yè)務(wù)中,我們對(duì)于策略選擇的判斷會(huì)更復(fù)雜,此處只是舉個(gè)簡(jiǎn)單的例子說(shuō)明下:

@Getter
public enum CalculateStrategyEnum {    
    ADD("operationAdd"),    
    SUB("operationSub"),    
    MUL("operationMul"),
    DIV("operationDiv");
    private final String strategy;    
    CalculateStrategyEnum(String strategy) {
        this.strategy = strategy;    
    }    
    public static CalculateStrategyEnum getStrategyEnum(String operationName) {        
        switch (operationName) {            
            case "加法運(yùn)算":                
                return ADD;            
            case "減法運(yùn)算":                
                return SUB;            
            case "乘法運(yùn)算":                
                return MUL;            
            case "除法運(yùn)算":                
                return DIV;            
            default:                
                return null;        
        }    
    }
}

策略實(shí)現(xiàn)類中加入@Component 注解,將 bean 實(shí)例交給 spring 容器管理

@Component
class OperationAdd implements CalculateStrategy {
    @Override 
    public int doOperation(int num1, int num2) {
         return num1 + num2; 
    } 
}

@Component
class OperationSub implements CalculateStrategy {
    @Override 
    public int doOperation(int num1, int num2) { 
        return num1 - num2;
    } 
}

@Component
class OperationMul implements CalculateStrategy {
    @Override 
    public int doOperation(int num1, int num2) { 
        return num1 * num2; 
    } 
}

@Component
class OperationDiv implements CalculateStrategy { 
    @Override 
    public int doOperation(int num1, int num2) { 
        return num1 / num2; 
    } 
}

策略調(diào)用處:業(yè)務(wù)處理

@Service
class CalculateService {
    // 注入所有策略類
    @Resource
    Map calculateStrategy;
   
    public executeStrategy(String operationName, int num1, int num2) {   
        // 根據(jù)參數(shù)匹配對(duì)應(yīng)的枚舉實(shí)例
        CalculateStrategyEnum strategy = CalculateStrategyEnum.getStrategyEnum(operationName);
        
        // 獲取對(duì)應(yīng)bean執(zhí)行策略算法
        if (stategy != null) {
            calculateStrategy.get(strategy.getStrategy()).doOperation(num1, num2)
        }      
    } 
}

當(dāng)我們需要新增算法時(shí),只需新增新的策略實(shí)現(xiàn)類和枚舉實(shí)例,修改枚舉類中的策略選擇方法,無(wú)需入侵現(xiàn)有業(yè)務(wù)代碼,實(shí)現(xiàn)了高內(nèi)聚、低耦合,增強(qiáng)了系統(tǒng)的靈活性和可擴(kuò)展性。

三、枚舉+函數(shù)式接口

1、函數(shù)式接口

什么是函數(shù)式接口

函數(shù)式接口是只包含一個(gè)抽象方法的接口。但是默認(rèn)方法和靜態(tài)方法在此接口中可以定義多個(gè)。Java 中的函數(shù)式接口可以被用作 Lambda 表達(dá)式的目標(biāo)類型。通過(guò)函數(shù)式接口,可以實(shí)現(xiàn)更簡(jiǎn)潔、更具可讀性的代碼,從而支持函數(shù)式編程的思想。

Java 中有一些內(nèi)置的函數(shù)式接口,用于不同的用途:

1.Runnable: 用于描述可以在單獨(dú)線程中執(zhí)行的任務(wù)。

2.Callable: 類似于 Runnable,但可以返回執(zhí)行結(jié)果或拋出異常。

3.Comparator: 用于比較兩個(gè)對(duì)象的順序。

4.Function: 接受一個(gè)參數(shù)并產(chǎn)生一個(gè)結(jié)果。

5.Predicate: 接受一個(gè)參數(shù)并返回一個(gè)布爾值,用于判斷條件是否滿足。

6.Supplier: 不接受參數(shù),但返回一個(gè)值。

7.Consumer: 接受一個(gè)參數(shù),無(wú)返回值。

2、枚舉+函數(shù)式接口的使用

我們可以通過(guò)為枚舉類設(shè)置函數(shù)式接口類型的屬性,讓枚舉實(shí)例擁有一些特定的行為

例如下面的例子,通過(guò)Runnable接口為枚舉實(shí)例賦予了對(duì)應(yīng)的行為。

public enum ActionEnum {    
    RUN(ActionEnum::run),    
    JUMP(ActionEnum::jump),    
    SIT(ActionEnum::sit);    
    
    private final Runnable action;   
     
    ActionEnum(Runnable action) {        
        this.action = action;    
    }    
    
    public static void run() {        
        System.out.println("Running");    
    }    
    
    public static void jump() {        
        System.out.println("Jumping");    
    }    
    
    public static void sit() {        
        System.out.println("Sitting");    
    }
}

也可以根據(jù)具體行為是否消費(fèi)參數(shù),以及是否提供返回值來(lái)選擇合適的接口

public enum ActionEnum {    
    RUN(ActionEnum::run),    
    JUMP(ActionEnum::jump),    
    SIT(ActionEnum::sit);    
    
    private final Supplier action;    
    
    ActionEnum(Supplier action) {        
        this.action = action;    
    } 
       
    public static String run() {        
        return "Running";    
    }    
    
    public static String jump() {        
        return "Jumping";    
    }    
    
    public static String sit() {        
        return "Sitting";    
    }
}

這樣,我們可以將與枚舉值強(qiáng)關(guān)聯(lián)的一些行為封裝到枚舉類中,與其他業(yè)務(wù)代碼隔離,實(shí)現(xiàn)高內(nèi)聚、低耦合的設(shè)計(jì)。

引用:

策略模式介紹:

https://www.cnblogs.com/xuwujing/p/9954263.html

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8496

    瀏覽量

    150831
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2957

    瀏覽量

    104544
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用C語(yǔ)言實(shí)現(xiàn)內(nèi)耦合

    編程時(shí),我們講究的是內(nèi)耦合,在協(xié)同開發(fā)、代碼移植、維護(hù)等環(huán)節(jié)都起到很重要的作用。
    發(fā)表于 09-21 11:33 ?1159次閱讀

    如何實(shí)現(xiàn)代碼的內(nèi)耦合

    大家在談到面向?qū)ο缶幊痰臅r(shí)候基本都是討論軟件的“內(nèi)耦合”的特點(diǎn),這6個(gè)字也是算是成為了大部分評(píng)判代碼質(zhì)量的一個(gè)標(biāo)準(zhǔn),所以很多小伙伴一
    發(fā)表于 10-13 08:57 ?1023次閱讀

    如何去實(shí)現(xiàn)模塊設(shè)計(jì)中的內(nèi)耦合

    內(nèi)耦合分別是什么意思?有何作用?如何去實(shí)現(xiàn)模塊設(shè)計(jì)中的
    發(fā)表于 02-25 07:05

    怎么把硬件操作和APP軟件耦合起來(lái)?

    你們寫嵌入都是怎么把硬件操作和APP軟件耦合起來(lái)的,怎樣達(dá)到內(nèi)
    發(fā)表于 11-06 07:57

    深入理解java枚舉類型enum用法

    的子類(java.lang.Enum 是一個(gè)抽象類)。枚舉類型符合通用模式 Class Enum packagecom.hmw.test; /** * 枚舉測(cè)試類 *@author《
    發(fā)表于 09-27 11:49 ?0次下載

    C語(yǔ)言中的內(nèi)耦合講解

    編程時(shí),我們講究的是內(nèi)耦合,在協(xié)同開發(fā)、代碼移植、維護(hù)等環(huán)節(jié)都起到很重要的作用。 一、原理篇而
    的頭像 發(fā)表于 08-16 14:06 ?2304次閱讀

    C語(yǔ)言--“內(nèi)耦合”編程思想

    1、定義內(nèi)耦合,是軟件工程中的概念,是判斷設(shè)計(jì)好壞的標(biāo)準(zhǔn),主要是面向?qū)ο蟮脑O(shè)計(jì),主要是看類的內(nèi)聚性是否
    發(fā)表于 01-13 13:43 ?3次下載
    C語(yǔ)言--“<b class='flag-5'>高</b><b class='flag-5'>內(nèi)</b><b class='flag-5'>聚</b>,<b class='flag-5'>低</b><b class='flag-5'>耦合</b>”編程思想

    很強(qiáng)大!耦合內(nèi)的MCU實(shí)用軟件框架

    一個(gè)模塊內(nèi)部各個(gè)元素之間的聯(lián)系的緊密程度,如果各個(gè)元素(語(yǔ)句、程序段)之間的聯(lián)系程度越高,則內(nèi)聚性越高,也就是內(nèi)
    發(fā)表于 02-08 15:56 ?3次下載
    很強(qiáng)大!<b class='flag-5'>低</b><b class='flag-5'>耦合</b><b class='flag-5'>高</b><b class='flag-5'>內(nèi)</b><b class='flag-5'>聚</b>的MCU實(shí)用軟件框架

    為什么我不再推薦枚舉策略模式

    我們可以看到經(jīng)典方法,創(chuàng)建了一個(gè)接口、三個(gè)策略類,還是比較啰嗦的。調(diào)用類的實(shí)現(xiàn)也待商榷,新增一個(gè)策略類還要修改榜單實(shí)例(可以用抽象工廠解決,但是復(fù)雜度又上升了)。加之我們有更好的選擇,
    的頭像 發(fā)表于 04-14 10:52 ?1999次閱讀

    Java枚舉的特點(diǎn)及用法

    Java 枚舉出現(xiàn)之前,通常會(huì)使用常量類來(lái)表示一組固定的常量值,直到Java 1.5之后推出了枚舉,那么枚舉類型有哪些特點(diǎn),它比常量類又
    的頭像 發(fā)表于 09-30 10:02 ?1386次閱讀

    函數(shù)接口的應(yīng)用知識(shí)點(diǎn)

    )對(duì)java.util.function包進(jìn)行解讀 (原理篇)介紹函數(shù)接口實(shí)現(xiàn)原理 應(yīng)用篇將階段相關(guān)的JDK源碼以及給出典型的示例代碼
    的頭像 發(fā)表于 10-13 11:32 ?615次閱讀
    <b class='flag-5'>函數(shù)</b><b class='flag-5'>式</b><b class='flag-5'>接口</b>的應(yīng)用知識(shí)點(diǎn)

    什么是函數(shù)接口

    、及其所使用的一些和函數(shù)接口相關(guān)的知識(shí)點(diǎn)進(jìn)行一個(gè)全面的學(xué)習(xí)。函數(shù)接口所涉及的知識(shí)點(diǎn)包含:
    的頭像 發(fā)表于 10-13 14:48 ?1469次閱讀
    什么是<b class='flag-5'>函數(shù)</b><b class='flag-5'>式</b><b class='flag-5'>接口</b>

    java switch case值能為枚舉值嗎

    Java中的switch語(yǔ)句可以接受枚舉類型的值作為參數(shù)。在Java中,枚舉是一種特殊的數(shù)據(jù)類型,它定義了一個(gè)固定數(shù)量的命名常量。因此,可以將枚舉
    的頭像 發(fā)表于 11-30 14:41 ?5081次閱讀

    Java中保持?jǐn)U展性的實(shí)現(xiàn)方法

    SOLID(單一、開閉、里替換、接口隔離、依賴倒置)五大原則和23種設(shè)計(jì)模式(常見的單例、構(gòu)建者、裝飾、適配、代理、組合、模板等等),小伙伴們對(duì)這些肯定都很熟悉。這些原則和設(shè)計(jì)模式
    的頭像 發(fā)表于 12-01 10:01 ?348次閱讀
    <b class='flag-5'>Java</b>中保持?jǐn)U展性的<b class='flag-5'>實(shí)現(xiàn)</b>方法

    編程如何做到內(nèi)耦合呢?

    耦合,是指模塊之間盡可能的使其獨(dú)立存在,模塊之間不產(chǎn)生聯(lián)系不可能,但模塊與模塊之間的接口應(yīng)該盡量少而簡(jiǎn)單。
    的頭像 發(fā)表于 12-06 09:20 ?963次閱讀