欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式之java策略模式詳解

 更新時(shí)間:2021年09月15日 10:24:32   作者:大忽悠愛忽悠  
這篇文章主要介紹了Java經(jīng)典設(shè)計(jì)模式之策略模式,簡單說明了策略模式的概念、原理并結(jié)合實(shí)例形式分析了java策略模式的具有用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下

為什么使用策略模式?

實(shí)現(xiàn)某一個(gè)功能有多條途徑,每一條途徑對(duì)應(yīng)一種算法,此時(shí)我們可以使用一種設(shè)計(jì)模式來實(shí)現(xiàn)靈活地選擇解決途徑,也能夠方便地增加新的解決途徑。

策略模式包含角色

  • Context(環(huán)境類):環(huán)境類是使用算法的角色,它在解決某個(gè)問題(即實(shí)現(xiàn)某個(gè)方法)時(shí)可以采用多種策略。在環(huán)境類中維持一個(gè)對(duì)抽象策略類的引用實(shí)例,用于定義所采用的策略。
  • Strategy(抽象策略類):它為所支持的算法聲明了抽象方法,是所有策略類的父類,它可以是抽象類或具體類,也可以是接口。環(huán)境類通過抽象策略類中聲明的方法在運(yùn)行時(shí)調(diào)用具體策略類中實(shí)現(xiàn)的算法。
  • ConcreteStrategy(具體策略類):它實(shí)現(xiàn)了在抽象策略類中聲明的算法,在運(yùn)行時(shí),具體策略類將覆蓋在環(huán)境類中定義的抽象策略類對(duì)象,使用一種具體的算法實(shí)現(xiàn)某個(gè)業(yè)務(wù)處理。

策略模式的類圖

在這里插入圖片描述

策略模式需要一個(gè)策略接口,不同的策略實(shí)現(xiàn)不同的實(shí)現(xiàn)類,在具體業(yè)務(wù)環(huán)境中僅持有該策略接口,根據(jù)不同的場景使用不同的實(shí)現(xiàn)類即可。

面向接口編程,而不是面向?qū)崿F(xiàn)。

排序案例

對(duì)數(shù)組進(jìn)行排序的算法有很多,但是不同的算法在不同的場景下可以發(fā)揮更大的效率,例如數(shù)據(jù)量很大的時(shí)候,我們可以使用快速排序,數(shù)據(jù)量小的時(shí)候就可以采用插入排序

在這里插入圖片描述

抽象策略類

//抽象策略類
public  interface Strategy
{
    public void sort();
}

具體策略類

public class QuickSort implements Strategy
{
    @Override
    public void sort() {
        System.out.println("快速排序");
    }
}
public class InsertSort implements Strategy
{
    @Override
    public void sort() {
        System.out.println("插入排序");
    }
}
public class BubbleSort implements Strategy
{
    @Override
    public void sort() {
        System.out.println("冒泡排序");
    }
}

環(huán)境類

public class Context
{
    private  Strategy strategy;
    public void sort(int[] arr,Strategy strategy)
    {
        this.strategy=strategy;
        doSort();
    }
    private void doSort()
    {
        strategy.sort();
    }
}

測試類

public class Client
{
    public static void main(String[] args) {
        int[] arr={1,1,1,1,1,1,1,1,1,1};
        int[] arr1={1,1,1,1,1,1};
        int[] arr2={1,1,1};
        Context context=new Context();
        context.sort(arr,new QuickSort());
        context.sort(arr1,new InsertSort());
        context.sort(arr2,new BubbleSort());
    }
}

在這里插入圖片描述

策略模式的優(yōu)點(diǎn)

  • 策略模式提供了對(duì) “開閉原則” 的完美支持,用戶可以在不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為,也可以靈活地增加新的算法或行為。
  • 策略模式提供了管理相關(guān)的算法族的辦法。策略類的等級(jí)結(jié)構(gòu)定義了一個(gè)算法或行為族,恰當(dāng)使用繼承可以把公共的代碼移到抽象策略類中,從而避免重復(fù)的代碼。
  • 策略模式提供了一種可以替換繼承關(guān)系的辦法。如果不使用策略模式而是通過繼承,這樣算法的使用就 和算法本身混在一起,不符合 “單一職責(zé)原則”,而且使用繼承無法實(shí)現(xiàn)算法或行為在程序運(yùn)行時(shí)的動(dòng)態(tài)切 換。
  • 使用策略模式可以避免多重條件選擇語句。多重條件選擇語句是硬編碼,不易維護(hù)。
  • 策略模式提供了一種算法的復(fù)用機(jī)制,由于將算法單獨(dú)提取出來封裝在策略類中,因此不同的環(huán)境類可以方便地復(fù)用這些策略類。

策略模式的缺點(diǎn)

  • 客戶端必須知道所有的策略類,并自行決定使用哪一個(gè)策略類。這就意味著客戶端必須理解這些算法的區(qū)別,以便適時(shí)選擇恰當(dāng)?shù)乃惴?。換言之,策略模式只適用于客戶端知道所有的算法或行為的情況。
  • 策略模式將造成系統(tǒng)產(chǎn)生很多具體策略類,任何細(xì)小的變化都將導(dǎo)致系統(tǒng)要增加一個(gè)新的具體策略類。
  • 無法同時(shí)在客戶端使用多個(gè)策略類,也就是說,在使用策略模式時(shí),客戶端每次只能使用一個(gè)策略類,不支持使用一個(gè)策略類完成部分功能后再使用另一個(gè)策略類來完成剩余功能的情況。

適用場景

  • 一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種,那么可以將這些算法封裝到一個(gè)個(gè)的具體算法類中,而這些具體算法類都是一個(gè)抽象算法類的子類。換言之,這些具體算法類均有統(tǒng)一的接口,根據(jù) “里氏代換原則” 和面向?qū)ο蟮亩鄳B(tài)性,客戶端可以選擇使用任何一個(gè)具體算法類,并只需要維持一個(gè)數(shù)據(jù)類型是抽象算法類的對(duì)象。
  • 一個(gè)對(duì)象有很多的行為,如果不用恰當(dāng)?shù)哪J?,這些行為就只好使用多重條件選擇語句來實(shí)現(xiàn)。此時(shí),使用策略模式,把這些行為轉(zhuǎn)移到相應(yīng)的具體策略類里面,就可以避免使用難以維護(hù)的多重條件選擇語句。
  • 不希望客戶端知道復(fù)雜的、與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu),在具體策略類中封裝算法與相關(guān)的數(shù)據(jù)結(jié)構(gòu),可以提高算法的保密性與安全性。

源碼分析策略模式的典型應(yīng)用

Java Comparator 中的策略模式

java.util.Comparator 接口是比較器接口,可以通過 Collections.sort(List,Comparator)Arrays.sort(Object[],Comparator) 對(duì)集合和數(shù)據(jù)進(jìn)行排序,下面為示例程序

一個(gè)學(xué)生類,有兩個(gè)屬性 id 和 name

@Data
@AllArgsConstructor
public class Student {
    private Integer id;
    private String name;
    @Override
    public String toString() {
        return "{id=" + id + ", name='" + name + "'}";
    }
}

實(shí)現(xiàn)兩個(gè)比較器,比較器實(shí)現(xiàn)了 Comparator 接口,一個(gè)升序,一個(gè)降序

// 降序
public class DescSortor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o2.getId() - o1.getId();
    }
}
// 升序
public class AscSortor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getId() - o2.getId();
    }
}

通過 Arrays.sort() 對(duì)數(shù)組進(jìn)行排序

public class Test1 {
    public static void main(String[] args) {
        Student[] students = {
                new Student(3, "張三"),
                new Student(1, "李四"),
                new Student(4, "王五"),
                new Student(2, "趙六")
        };
        toString(students, "排序前");
        Arrays.sort(students, new AscSortor());
        toString(students, "升序后");
        Arrays.sort(students, new DescSortor());
        toString(students, "降序后");
    }
    public static void toString(Student[] students, String desc){
        for (int i = 0; i < students.length; i++) {
            System.out.print(desc + ": " +students[i].toString() + ", ");
        }
        System.out.println();
    }
}

在這里插入圖片描述

通過 Collections.sort() 對(duì)集合List進(jìn)行排序

public class Client
{
    public static void main(String[] args) {
        List<Stu> students = Arrays.asList(
                new Stu(3, "張三"),
                new Stu(1, "李四"),
                new Stu(4, "王五"),
                new Stu(2, "趙六")
        );
        toString(students, "排序前");
        Collections.sort(students, new AscSortor());
        toString(students, "升序后");
        Collections.sort(students, new DescSortor());
        toString(students, "降序后");
    }
    public static void toString(List<Stu> students, String desc){
        for (Stu student : students) {
            System.out.print(desc + ": " + student.toString() + ", ");
        }
        System.out.println();
    }
}

在這里插入圖片描述

我們向 Collections.sort()Arrays.sort() 分別傳入不同的比較器即可實(shí)現(xiàn)不同的排序效果(升序或降序)

這里 Comparator 接口充當(dāng)了抽象策略角色,兩個(gè)比較器 DescSortor 和 AscSortor 則充當(dāng)了具體策略角色,Collections 和 Arrays 則是環(huán)境角色

參考文章

策略模式

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Java利用POI讀取、寫入Excel的方法指南

    Java利用POI讀取、寫入Excel的方法指南

    這篇文章主要給大家介紹了關(guān)于Java利用POI讀取、寫入Excel的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Spring Boot和Vue跨域請(qǐng)求問題原理解析

    Spring Boot和Vue跨域請(qǐng)求問題原理解析

    這篇文章主要介紹了Spring Boot和Vue跨域請(qǐng)求問題原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 一文帶你掌握J(rèn)ava?LinkedBlockingQueue

    一文帶你掌握J(rèn)ava?LinkedBlockingQueue

    LinkedBlockingQueue?是一個(gè)可選有界阻塞隊(duì)列,這篇文章主要為大家詳細(xì)介紹了Java中LinkedBlockingQueue的實(shí)現(xiàn)原理與適用場景,感興趣的可以了解一下
    2023-04-04
  • 讓JPA的Query查詢接口返回Map對(duì)象的方法

    讓JPA的Query查詢接口返回Map對(duì)象的方法

    下面小編就為大家分享一篇讓JPA的Query查詢接口返回Map對(duì)象的方法,具有很的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • 解決rocketmq-spring-boot-starter導(dǎo)致的多消費(fèi)者實(shí)例重復(fù)消費(fèi)問題

    解決rocketmq-spring-boot-starter導(dǎo)致的多消費(fèi)者實(shí)例重復(fù)消費(fèi)問題

    這篇文章主要介紹了解決rocketmq-spring-boot-starter導(dǎo)致的多消費(fèi)者實(shí)例重復(fù)消費(fèi)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 使用Java將字節(jié)數(shù)組轉(zhuǎn)成16進(jìn)制形式的代碼實(shí)現(xiàn)

    使用Java將字節(jié)數(shù)組轉(zhuǎn)成16進(jìn)制形式的代碼實(shí)現(xiàn)

    在很多場景下,需要進(jìn)行分析字節(jié)數(shù)據(jù),但是我們存起來的字節(jié)數(shù)據(jù)一般都是二進(jìn)制的,這時(shí)候就需要我們將其轉(zhuǎn)成16進(jìn)制的方式方便分析,本文主要介紹如何使用Java將字節(jié)數(shù)組格式化成16進(jìn)制的格式并輸出,需要的朋友可以參考下
    2024-05-05
  • Java?NIO?中?Selector?解析

    Java?NIO?中?Selector?解析

    這篇文章主要介紹了Java?NIO?中?Selector,Selector即選擇器,選擇器提供選擇執(zhí)行已經(jīng)就緒的任務(wù)的能力即為翻譯為多路復(fù)用,下面文章對(duì)Selector詳細(xì)介紹內(nèi)容,需要的小伙伴可以參考一下
    2022-02-02
  • Java并發(fā)之synchronized實(shí)現(xiàn)原理深入理解

    Java并發(fā)之synchronized實(shí)現(xiàn)原理深入理解

    這篇文章主要介紹了Java中synchronized實(shí)現(xiàn)原理詳解,涉及synchronized實(shí)現(xiàn)同步的基礎(chǔ),Java對(duì)象頭,Monitor,Mark Word,鎖優(yōu)化,自旋鎖等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • 使用Spring的JAVA Mail支持簡化郵件發(fā)送功能

    使用Spring的JAVA Mail支持簡化郵件發(fā)送功能

    這篇文章主要為大家詳細(xì)介紹了使用Spring的JAVA Mail支持簡化郵件發(fā)送功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Java實(shí)現(xiàn)員工信息管理系統(tǒng)

    Java實(shí)現(xiàn)員工信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)員工信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評(píng)論