最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA中六種策略模式的實(shí)現(xiàn)方式(附代碼示例和適用場(chǎng)景)

 更新時(shí)間:2026年01月30日 10:20:19   作者:海闊天空在前走  
策略模式是一種行為模式,也是替代大量ifelse的利器,它所能幫你解決的是場(chǎng)景,一般是具有同類可替代的行為邏輯算法場(chǎng)景,這篇文章主要介紹了JAVA中六種策略模式實(shí)現(xiàn)方式的相關(guān)資料,需要的朋友可以參考下

前言

在 Java 中,策略模式的核心是定義算法族、封裝算法、動(dòng)態(tài)切換,其實(shí)現(xiàn)方式主要圍繞 “策略的定義、創(chuàng)建、選擇” 展開,根據(jù)場(chǎng)景復(fù)雜度和技術(shù)選型,常見有以下 6 種實(shí)現(xiàn)方式,附代碼示例和適用場(chǎng)景:

一、基礎(chǔ)實(shí)現(xiàn):接口 + 實(shí)現(xiàn)類(經(jīng)典方式)

最標(biāo)準(zhǔn)的實(shí)現(xiàn),通過接口定義策略契約,多個(gè)實(shí)現(xiàn)類封裝不同算法,客戶端通過注入或選擇不同實(shí)現(xiàn)類切換策略。

代碼示例

// 1. 策略接口(定義契約)
public interface PaymentStrategy {
    // 策略核心方法:支付
    boolean pay(double amount);
    // 獲取策略名稱
    String getStrategyName();
}

// 2. 具體策略1:支付寶支付
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("使用支付寶支付:" + amount + "元");
        return true; // 模擬支付成功
    }

    @Override
    public String getStrategyName() {
        return "alipay";
    }
}

// 3. 具體策略2:微信支付
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("使用微信支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyName() {
        return "wechat";
    }
}

// 4. 策略上下文(封裝策略,對(duì)外提供統(tǒng)一接口)
public class PaymentContext {
    private PaymentStrategy strategy;

    // 構(gòu)造器注入策略
    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    // 動(dòng)態(tài)切換策略
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    // 客戶端調(diào)用入口
    public boolean executePayment(double amount) {
        return strategy.pay(amount);
    }
}

// 5. 客戶端使用
public class Client {
    public static void main(String[] args) {
        // 選擇支付寶策略
        PaymentContext context = new PaymentContext(new AlipayStrategy());
        context.executePayment(100);

        // 動(dòng)態(tài)切換為微信策略
        context.setStrategy(new WechatPayStrategy());
        context.executePayment(200);
    }
}

適用場(chǎng)景

  • 策略數(shù)量固定、變化不頻繁(如支付方式、排序算法)。
  • 需明確暴露所有策略,允許客戶端直接選擇。

二、枚舉實(shí)現(xiàn)(簡化策略管理)

用枚舉封裝所有策略,利用枚舉的 “單例特性” 和 “天然分組” 優(yōu)勢(shì),減少類冗余,簡化策略選擇。

代碼示例

// 1. 枚舉策略(實(shí)現(xiàn)策略邏輯)
public enum PaymentStrategyEnum {
    // 支付寶策略
    ALIPAY {
        @Override
        public boolean pay(double amount) {
            System.out.println("枚舉-支付寶支付:" + amount + "元");
            return true;
        }
    },
    // 微信支付策略
    WECHAT {
        @Override
        public boolean pay(double amount) {
            System.out.println("枚舉-微信支付:" + amount + "元");
            return true;
        }
    };

    // 策略核心方法(枚舉抽象方法)
    public abstract boolean pay(double amount);
}

// 2. 客戶端使用(直接通過枚舉選擇策略)
public class Client {
    public static void main(String[] args) {
        // 根據(jù)枚舉值選擇策略
        PaymentStrategyEnum.ALIPAY.pay(100);
        PaymentStrategyEnum.WECHAT.pay(200);

        // 支持動(dòng)態(tài)傳入策略(如從配置文件讀?。?
        String strategyName = "ALIPAY"; // 可來自配置
        PaymentStrategyEnum strategy = Enum.valueOf(PaymentStrategyEnum.class, strategyName);
        strategy.pay(300);
    }
}

適用場(chǎng)景

  • 策略數(shù)量少、邏輯簡單(如狀態(tài)判斷、固定規(guī)則)。
  • 無需動(dòng)態(tài)擴(kuò)展策略(枚舉不可動(dòng)態(tài)新增)。

三、工廠模式 + 策略模式(解耦策略創(chuàng)建)

通過工廠類封裝策略的創(chuàng)建邏輯,客戶端無需關(guān)注策略的實(shí)例化細(xì)節(jié),只需傳入標(biāo)識(shí)即可獲取對(duì)應(yīng)策略,適合策略較多的場(chǎng)景。

代碼示例

// 1. 策略接口(同基礎(chǔ)實(shí)現(xiàn))
public interface PaymentStrategy {
    boolean pay(double amount);
    String getStrategyCode();
}

// 2. 具體策略(同基礎(chǔ)實(shí)現(xiàn):AlipayStrategy、WechatPayStrategy)

// 3. 策略工廠(封裝策略創(chuàng)建)
public class PaymentStrategyFactory {
    // 緩存策略實(shí)例(單例)
    private static final Map<String, PaymentStrategy> STRATEGY_MAP = new HashMap<>();

    // 靜態(tài)初始化:注冊(cè)所有策略
    static {
        STRATEGY_MAP.put("alipay", new AlipayStrategy());
        STRATEGY_MAP.put("wechat", new WechatPayStrategy());
    }

    // 禁止外部實(shí)例化
    private PaymentStrategyFactory() {}

    // 根據(jù)標(biāo)識(shí)獲取策略
    public static PaymentStrategy getStrategy(String strategyCode) {
        PaymentStrategy strategy = STRATEGY_MAP.get(strategyCode);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的支付方式:" + strategyCode);
        }
        return strategy;
    }

    // 擴(kuò)展:動(dòng)態(tài)注冊(cè)新策略(支持熱更新)
    public static void registerStrategy(String code, PaymentStrategy strategy) {
        STRATEGY_MAP.put(code, strategy);
    }
}

// 4. 客戶端使用
public class Client {
    public static void main(String[] args) {
        // 從工廠獲取策略(無需手動(dòng)new)
        PaymentStrategy alipay = PaymentStrategyFactory.getStrategy("alipay");
        alipay.pay(100);

        PaymentStrategy wechat = PaymentStrategyFactory.getStrategy("wechat");
        wechat.pay(200);

        // 動(dòng)態(tài)注冊(cè)新策略(如新增銀聯(lián)支付)
        PaymentStrategyFactory.registerStrategy("unionpay", new UnionPayStrategy());
        PaymentStrategyFactory.getStrategy("unionpay").pay(300);
    }
}

// 新增策略:銀聯(lián)支付(無需修改工廠核心邏輯)
class UnionPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("使用銀聯(lián)支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyCode() {
        return "unionpay";
    }
}

適用場(chǎng)景

  • 策略數(shù)量多(如 10+),需要統(tǒng)一管理創(chuàng)建邏輯。
  • 客戶端只需通過標(biāo)識(shí)(如字符串、枚舉)選擇策略,無需關(guān)注實(shí)現(xiàn)。

四、注解 + 反射(動(dòng)態(tài)掃描策略)

通過自定義注解標(biāo)記策略類,程序啟動(dòng)時(shí)掃描所有帶注解的策略并注冊(cè)到工廠,支持 “無侵入式擴(kuò)展”(新增策略無需修改工廠代碼)。

代碼示例

// 1. 自定義策略注解(標(biāo)記策略標(biāo)識(shí))
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PaymentStrategyAnnotation {
    String code(); // 策略唯一標(biāo)識(shí)
}

// 2. 策略接口(同基礎(chǔ)實(shí)現(xiàn))
public interface PaymentStrategy {
    boolean pay(double amount);
}

// 3. 具體策略(用注解標(biāo)記)
@PaymentStrategyAnnotation(code = "alipay")
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("注解-支付寶支付:" + amount + "元");
        return true;
    }
}

@PaymentStrategyAnnotation(code = "wechat")
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("注解-微信支付:" + amount + "元");
        return true;
    }
}

// 4. 策略工廠(反射掃描注解策略)
public class AnnotationStrategyFactory {
    private static final Map<String, PaymentStrategy> STRATEGY_MAP = new HashMap<>();

    // 初始化:掃描指定包下的所有策略
    static {
        try {
            // 掃描com.example.strategy包下的所有類
            Reflections reflections = new Reflections("com.example.strategy");
            // 獲取所有帶@PaymentStrategyAnnotation注解的類
            Set<Class<?>> strategyClasses = reflections.getTypesAnnotatedWith(PaymentStrategyAnnotation.class);

            // 實(shí)例化并注冊(cè)策略
            for (Class<?> clazz : strategyClasses) {
                PaymentStrategyAnnotation annotation = clazz.getAnnotation(PaymentStrategyAnnotation.class);
                String code = annotation.code();
                PaymentStrategy strategy = (PaymentStrategy) clazz.newInstance();
                STRATEGY_MAP.put(code, strategy);
            }
        } catch (Exception e) {
            throw new RuntimeException("策略初始化失敗", e);
        }
    }

    // 獲取策略
    public static PaymentStrategy getStrategy(String code) {
        return STRATEGY_MAP.getOrDefault(code, () -> {
            System.out.println("默認(rèn)策略:支付失敗");
            return false;
        });
    }
}

// 5. 客戶端使用(依賴Reflections庫,需導(dǎo)入依賴)
public class Client {
    public static void main(String[] args) {
        AnnotationStrategyFactory.getStrategy("alipay").pay(100);
        AnnotationStrategyFactory.getStrategy("wechat").pay(200);
    }
}

依賴說明

需導(dǎo)入反射掃描庫(Maven):

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.10.2</version>
</dependency>

適用場(chǎng)景

  • 大型項(xiàng)目,策略頻繁新增(如插件化架構(gòu))。
  • 追求 “開閉原則”,新增策略無需修改現(xiàn)有代碼。

五、Lambda 表達(dá)式(簡化無狀態(tài)策略)

對(duì)于無狀態(tài)、邏輯簡單的策略,可直接用 Lambda 表達(dá)式實(shí)現(xiàn)策略接口,無需創(chuàng)建單獨(dú)的實(shí)現(xiàn)類,簡化代碼。

代碼示例

// 1. 函數(shù)式策略接口(僅含一個(gè)抽象方法)
@FunctionalInterface
public interface PaymentStrategy {
    boolean pay(double amount);
}

// 2. 策略上下文(同基礎(chǔ)實(shí)現(xiàn))
public class PaymentContext {
    private PaymentStrategy strategy;

    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public boolean execute(double amount) {
        return strategy.pay(amount);
    }
}

// 3. 客戶端使用(Lambda直接實(shí)現(xiàn)策略)
public class Client {
    public static void main(String[] args) {
        // Lambda實(shí)現(xiàn)支付寶策略
        PaymentContext alipayContext = new PaymentContext(amount -> {
            System.out.println("Lambda-支付寶支付:" + amount + "元");
            return true;
        });
        alipayContext.execute(100);

        // Lambda實(shí)現(xiàn)微信策略
        PaymentContext wechatContext = new PaymentContext(amount -> {
            System.out.println("Lambda-微信支付:" + amount + "元");
            return true;
        });
        wechatContext.execute(200);

        // 甚至可以直接傳遞Lambda,無需上下文
        PaymentStrategy unionPay = amount -> {
            System.out.println("Lambda-銀聯(lián)支付:" + amount + "元");
            return true;
        };
        unionPay.pay(300);
    }
}

適用場(chǎng)景

  • 策略邏輯簡單(1-3 行代碼)、無狀態(tài)(無需成員變量)。
  • 臨時(shí)策略(僅使用一次),無需復(fù)用。

六、Spring 容器整合(依賴注入 + 自動(dòng)裝配)

在 Spring 項(xiàng)目中,利用 Spring 的 IOC 容器管理策略實(shí)例,通過@Autowired自動(dòng)注入所有策略,結(jié)合MapList實(shí)現(xiàn)策略選擇,無需手動(dòng)創(chuàng)建工廠。

代碼示例

// 1. 策略接口(同基礎(chǔ)實(shí)現(xiàn))
public interface PaymentStrategy {
    boolean pay(double amount);
    String getStrategyCode();
}

// 2. 具體策略(Spring組件)
@Component // 交給Spring管理
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("Spring-支付寶支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyCode() {
        return "alipay";
    }
}

@Component
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("Spring-微信支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyCode() {
        return "wechat";
    }
}

// 3. 策略服務(wù)(Spring組件,自動(dòng)注入所有策略)
@Service
public class PaymentService {
    // Spring會(huì)自動(dòng)將所有PaymentStrategy實(shí)現(xiàn)類注入到Map中:key=beanName,value=策略實(shí)例
    @Autowired
    private Map<String, PaymentStrategy> strategyMap;

    // 或按策略code映射(自定義key)
    private Map<String, PaymentStrategy> codeToStrategyMap;

    // 初始化:將策略按code分組
    @PostConstruct
    public void init() {
        codeToStrategyMap = strategyMap.values().stream()
                .collect(Collectors.toMap(PaymentStrategy::getStrategyCode, s -> s));
    }

    // 執(zhí)行策略
    public boolean executePayment(String strategyCode, double amount) {
        PaymentStrategy strategy = codeToStrategyMap.get(strategyCode);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的支付方式");
        }
        return strategy.pay(amount);
    }
}

// 4. 客戶端使用(Spring環(huán)境)
@SpringBootApplication
public class StrategyApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(StrategyApplication.class, args);
        PaymentService paymentService = context.getBean(PaymentService.class);

        paymentService.executePayment("alipay", 100);
        paymentService.executePayment("wechat", 200);
    }
}

適用場(chǎng)景

  • Spring Boot/Spring MVC 項(xiàng)目(充分利用 Spring 的 IOC 特性)。
  • 策略需要依賴其他 Spring 組件(如@Autowired數(shù)據(jù)源、緩存等)。

六種實(shí)現(xiàn)方式對(duì)比

實(shí)現(xiàn)方式優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景
接口 + 實(shí)現(xiàn)類(經(jīng)典)結(jié)構(gòu)清晰、易理解策略多時(shí)有類爆炸問題策略少、變化不頻繁
枚舉實(shí)現(xiàn)代碼簡潔、無類冗余策略邏輯復(fù)雜時(shí)不適用,不可動(dòng)態(tài)擴(kuò)展策略少、邏輯簡單
工廠 + 策略解耦創(chuàng)建邏輯、支持動(dòng)態(tài)擴(kuò)展新增策略需修改工廠注冊(cè)代碼策略較多、需要統(tǒng)一管理
注解 + 反射無侵入擴(kuò)展、支持插件化依賴反射庫、初始化開銷略大大型項(xiàng)目、策略頻繁新增
Lambda 表達(dá)式代碼極簡、無需創(chuàng)建類無狀態(tài)、邏輯簡單場(chǎng)景受限臨時(shí)策略、簡單邏輯
Spring 整合自動(dòng)注入、支持依賴管理依賴 Spring 環(huán)境Spring 項(xiàng)目、策略需依賴其他組件

核心設(shè)計(jì)原則

無論哪種實(shí)現(xiàn)方式,都需遵循:

  1. 開閉原則:新增策略無需修改現(xiàn)有代碼(枚舉方式除外)。
  2. 單一職責(zé):每個(gè)策略只負(fù)責(zé)一種算法,上下文只負(fù)責(zé)協(xié)調(diào)策略。
  3. 里氏替換:任何策略都可替換為其他實(shí)現(xiàn),不影響客戶端使用。

總結(jié) 

到此這篇關(guān)于JAVA中六種策略模式實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)JAVA策略模式實(shí)現(xiàn)方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解Java定時(shí)調(diào)度(Timer)機(jī)制

    深入理解Java定時(shí)調(diào)度(Timer)機(jī)制

    這篇文章主要介紹了深入理解Java定時(shí)調(diào)度(Timer)機(jī)制,本節(jié)我們主要分析 Timer 的功能。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • Spring Cloud @EnableFeignClients注解的屬性字段basePacka詳解

    Spring Cloud @EnableFeignClients注解的屬性字段basePacka詳解

    這篇文章主要介紹了Spring Cloud @EnableFeignClients注解的屬性字段basePacka詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 零基礎(chǔ)寫Java知乎爬蟲之獲取知乎編輯推薦內(nèi)容

    零基礎(chǔ)寫Java知乎爬蟲之獲取知乎編輯推薦內(nèi)容

    上篇文章我們拿百度首頁做了個(gè)小測(cè)試,今天我們來個(gè)復(fù)雜的,直接抓取知乎編輯推薦的內(nèi)容,小伙伴們可算松了口氣,終于進(jìn)入正題了,哈哈。
    2014-11-11
  • Java網(wǎng)絡(luò)編程基礎(chǔ)詳解

    Java網(wǎng)絡(luò)編程基礎(chǔ)詳解

    網(wǎng)絡(luò)編程是指編寫運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。本文介紹了一些網(wǎng)絡(luò)編程基礎(chǔ)的概念,并用Java來實(shí)現(xiàn)TCP和UDP的Socket的編程,來讓讀者更好的了解其原理
    2021-08-08
  • Java方法重寫_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java方法重寫_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    在Java和其他一些高級(jí)面向?qū)ο蟮木幊陶Z言中,子類可繼承父類中的方法,而不需要重新編寫相同的方法。但有時(shí)子類并不想原封不動(dòng)地繼承父類的方法,而是想作一定的修改,這就需要采用方法的重寫。方法重寫又稱方法覆蓋,下文給大家介紹java方法重寫及重寫規(guī)則,一起學(xué)習(xí)吧
    2017-04-04
  • IDEA 2020 2全家桶安裝激活超詳細(xì)圖文教程

    IDEA 2020 2全家桶安裝激活超詳細(xì)圖文教程

    這篇文章主要介紹了IDEA-2020-2 全家桶安裝激活超詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java實(shí)現(xiàn)計(jì)算一個(gè)月有多少天和多少周

    Java實(shí)現(xiàn)計(jì)算一個(gè)月有多少天和多少周

    這篇文章主要介紹了Java實(shí)現(xiàn)計(jì)算一個(gè)月有多少天和多少周,本文直接給出實(shí)例代碼,需要的朋友可以參考下
    2015-06-06
  • 安全漏洞修復(fù)導(dǎo)致SpringBoot2.7與Springfox不兼容的偽命題解決

    安全漏洞修復(fù)導(dǎo)致SpringBoot2.7與Springfox不兼容的偽命題解決

    項(xiàng)目基于Spring Boot 2.5.2使用Springfox Swagger2生成API文檔,因安全漏洞需升級(jí)至2.7.8,導(dǎo)致兼容問題,下面就來介紹一下問題解決,感興趣的可以了解一下
    2025-06-06
  • Spring、SpringMvc和SpringBoot的區(qū)別及說明

    Spring、SpringMvc和SpringBoot的區(qū)別及說明

    Spring框架提供了全面的Java開發(fā)解決方案,核心包括IOC和AOP,SpringMvc作為其中的WEB層開發(fā)框架,通過復(fù)雜的XML配置管理前端視圖和后臺(tái)邏輯,SpringBoot則簡化了配置,專注于微服務(wù)接口開發(fā),支持嵌入式服務(wù)器,提高了開發(fā)效率
    2024-10-10
  • Java中Switch用法代碼示例

    Java中Switch用法代碼示例

    這篇文章主要介紹了Java中Switch用法代碼示例,向大家分享了兩段代碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11

最新評(píng)論

乌拉特中旗| 华池县| 农安县| 唐河县| 陆河县| 津南区| 巴彦县| 土默特左旗| 高要市| 揭西县| 河曲县| 寿阳县| 武强县| 新干县| 永丰县| 寻甸| 象州县| 辽阳县| 朝阳市| 黄冈市| 安仁县| 云梦县| 古蔺县| 邯郸县| 界首市| 临汾市| 伊宁市| 开远市| 武义县| 长治县| 江北区| 阿巴嘎旗| 武川县| 琼海市| 徐州市| 望谟县| 兖州市| 新绛县| 荃湾区| 德昌县| 肃南|