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

使用Java8實現(xiàn)模板方法模式的改造

 更新時間:2023年01月30日 11:22:36   作者:Hollis  
這篇文章主要為大家詳細介紹了如何使用Java8實現(xiàn)模板方法模式的改造,文中的示例代碼講解詳細,對我們深入了解java8有一定的幫助,感興趣的可以了了解一下

我們在日常開發(fā)中,經常會遇到類似的場景:當要做一件事兒的時候,這件事兒的步驟是固定好的,但是每一個步驟的具體實現(xiàn)方式是不一定的。

通常,遇到這種情況,我們會把所有要做的事兒抽象到一個抽象類中,并在該類中定義一個模板方法。這就是所謂的模板方法模式。

以前的模板方法

在我之前的一篇《設計模式——模板方法設計模式》文章中舉過一個例子:

當我們去銀行的營業(yè)廳辦理業(yè)務需要以下步驟:1.取號、2.辦業(yè)務、3.評價。

三個步驟中取號和評價都是固定的流程,每個人要做的事兒都是一樣的。但是辦業(yè)務這個步驟根據(jù)每個人要辦的事情不同所以需要有不同的實現(xiàn)。

我們可以將整個辦業(yè)務這件事兒封裝成一個抽象類:

/**
 * 模板方法設計模式的抽象類
 * @author hollis
 */

public abstract class AbstractBusinessHandler {
    /**
     * 模板方法
     */
    public final void execute(){

        getNumber();

        handle();

        judge();

    }

    /**
     * 取號
     * @return
     */
    private void getNumber(){

        System.out.println("number-00" + RandomUtils.nextInt());

    }

    /**
     * 辦理業(yè)務
     */

    public abstract void handle(); //抽象的辦理業(yè)務方法,由子類實現(xiàn)
    /**
     * 評價
     */
     
    private void judge(){

        System.out.println("give a praised");

    }

}

我們在類中定義了一個execute類,這個類編排了getNumber、handle和judge三個方法。這就是一個模板方法。

其中getNumber和judge都有通用的實現(xiàn),只有handle方法是個抽象的,需要子類根據(jù)實際要辦的業(yè)務的內容去重寫。

有了這個抽象類和模板方法,當我們想要實現(xiàn)一個"存錢業(yè)務"的時候,只需要繼承該AbstractBusinessHandeler并且重寫handle方法即可:

public class SaveMoneyHandler extends AbstractBusinessHandeler {

    @Override

    public void handle() {

        System.out.println("save 1000");

    }

}

這樣,我們在執(zhí)行存錢的業(yè)務邏輯的時候,只需要調用 SaveMoneyHandler的execute方法即可:

public static void main(String []args){

    SaveMoneyHandler saveMoneyHandler = new SaveMoneyHandler();

    saveMoneyHandler.execute();

}

輸出結果:

number-00958442164

save 1000

give a praised

以上,就是一個簡單的模板方法的實現(xiàn)。通過使用模板方法,可以幫助我們很大程度的復用代碼。

因為我們要在銀行辦理很多業(yè)務,所以可能需要定義很多的實現(xiàn)類:

//取錢業(yè)務的實現(xiàn)類

public class DrawMoneyHandler extends AbstractBusinessHandeler {

    @Override

    public void handle() {

        System.out.println("draw 1000");

    }

}

//理財業(yè)務的實現(xiàn)類

public class MoneyManageHandler extends AbstractBusinessHandeler{

    @Override

    public void handle() {

        System.out.println("money manage");

    }

}

一直以來,開發(fā)者們在使用模板方法的時候基本都是像上面這個例子一樣:需要準備一個抽象類,將部分邏輯以具體方法以及具體構造函數(shù)的形式實現(xiàn),然后聲明一些抽象方法來讓子類實現(xiàn)剩余的邏輯。不同的子類可以以不同的方式實現(xiàn)這些抽象方法,從而對剩余的邏輯有不同的實現(xiàn)。

但是,有了Java 8以后,模板方法有了另外一種實現(xiàn)方式,不需要定義特別多的實現(xiàn)類了。

Java 8 的函數(shù)式編程

2014年,Oracle發(fā)布了 Java 8,在Java 8中最大的新特性就是提供了對函數(shù)式編程的支持。

Java 8在java.util.function下面增加增加一系列的函數(shù)接口。其中主要有Consumer、Supplier、Predicate、Function等。

本文主要想要介紹一下Supplier和Consumer這兩個,使用者兩個接口,可以幫我們很好的改造模板方法。這里只是簡單介紹下他們的用法,并不會深入展開,如果大家想要學習更多用法,可以自行google一下。

Supplier

Supplier是一個供給型的接口,簡單點說,這就是一個返回某些值的方法。

最簡單的一個Supplier就是下面這段代碼:

public List<String> getList() {

    return new ArrayList();

}

使用Supplier表示就是:

Supplier<List<String>> listSupplier = ArrayList::new;

Consumer

Consumer 接口消費型接口,簡單點說,這就是一個使用某些值(如方法參數(shù))并對其進行操作的方法。

最簡單的一個Consumer就是下面這段代碼:

public void sum(String a1) {

    System.out.println(a1);

}

使用Consumer表示就是:

Consumer<String> printConsumer = a1 -> System.out.println(a1);

Consumer的用法,最見的的例子就是是Stream.forEach(Consumer)這樣的用法,

它接受一個Consumer,該Consumer消費正在迭代的流中的元素,并對每個元素執(zhí)行一些操作,比如打?。?/p>

Consumer<String> stringConsumer = (s) -> System.out.println(s.length());

Arrays.asList("ab", "abc", "a", "abcd").stream().forEach(stringConsumer);

Java 8以后的模板方法

在介紹過了Java 8中的Consumer、Supplier之后,我們來看下怎么改造之前我們介紹過的模板方法。

首先,我們定義一個BankBusinessHandler類,并且重新定義一個execute方法,這個方法有一個入參,是Consumer類型的,然后移除handle方法,重新編排后的模板方法內容如下:

/**
 * @author Hollis
 */

public class BankBusinessHandler {

    private void execute(Consumer<BigDecimal> consumer) {

        getNumber();

        consumer.accept(null);

        judge();

    }

    private void getNumber() {

        System.out.println("number-00" + RandomUtils.nextInt());

    }

    private void judge() {

        System.out.println("give a praised");

    }

}

我們實現(xiàn)的模板方法execute中,編排了getNumber、judge以及consumer.accept,這里面consumer.accept就是具體的業(yè)務邏輯,可能是存錢、取錢、理財?shù)?。需要由其他方法調用execute的時候傳入。

這時候,我們想要實現(xiàn)"存錢"業(yè)務的時候,需要BankBusinessHandler類中增加以下方法:

/**
 * @author Hollis
 */

public class BankBusinessHandler {

    public void save(BigDecimal amount) {

        execute(a -> System.out.println("save " + amount));

    }

}

在save方法中,調用execute方法,并且在入參處傳入一個實現(xiàn)了"存錢"的業(yè)務邏輯的Comsumer。

這樣,我們在執(zhí)行存錢的業(yè)務邏輯的時候,只需要調用 BankBusinessHandler的save方法即可:

public static void main(String[] args) throws {

    BankBusinessHandler businessHandler = new BankBusinessHandler();

    businessHandler.save(new BigDecimal("1000"));

}

輸出結果:

number-001736151440

save1000

give a praised

如上,當我們想要實現(xiàn)取錢、理財?shù)葮I(yè)務邏輯的時候,和存錢類似:

/**
 * @author Hollis
 */

public class BankBusinessHandler {

    public void save(BigDecimal amount) {

        execute(a -> System.out.println("save " + amount));

    }

    public void draw(BigDecimal amount) {

        execute(a -> System.out.println("draw " + amount));

    }

    public void moneyManage(BigDecimal amount) {

        execute(a -> System.out.println("draw " + amount));

    }

}

可以看到,通過使用Java 8中的Comsumer,我們把模板方法改造了,改造之后不再需要抽象類、抽象方法,也不再需要為每一個業(yè)務都創(chuàng)建一個實現(xiàn)類了。我們可以把所有的業(yè)務邏輯內聚在同一個業(yè)務類中。這樣非常方便這段代碼的后期運維。

前面介紹如何使用Consumer進行改造模板方法,那么Supplier有什么用呢?

我們的例子中,在取號、辦業(yè)務、評價這三個步驟中,辦業(yè)務是需要根據(jù)業(yè)務情況進行定制的,所以,我們在模板方法中,把辦業(yè)務這個作為擴展點開放給外部。

有這樣一種情況,那就是現(xiàn)在我們辦業(yè)務的時候,取號的方式也不一樣,可能是到銀行網點取號、在網上取號或者銀行客戶經理預約的無需取號等。

無論取號的方式如何,最終結果都是取一個號;而取到的號的種類不同,可能接收到的具體服務也不同,比如vip號會到VIP柜臺去辦理業(yè)務等。

想要實現(xiàn)這樣的業(yè)務邏輯,就需要使用到Supplier,Supplier是一個"供給者",他可以用來定制"取號邏輯"。

首先,我們需要改造下模板方法:

/**
 * 模板方法
 */

protected void execute(Supplier<String> supplier, Consumer<BigDecimal> consumer) {

    String number = supplier.get();

    System.out.println(number);


    if (number.startsWith("vip")) {

        //Vip號分配到VIP柜臺

        System.out.println("Assign To Vip Counter");

    }

    else if (number.startsWith("reservation")) {

        //預約號分配到專屬客戶經理

        System.out.println("Assign To Exclusive Customer Manager");

    }else{

        //默認分配到普通柜臺

        System.out.println("Assign To Usual Manager");

    }

    consumer.accept(null);

    judge();

}

經過改造,execute的入參增加了一個supplier,這個supplier可以提供一個號碼。至于如何取號的,交給調用execute的方法來執(zhí)行。

之后,我們可以定義多個存錢方法,分別是Vip存錢、預約存錢和普通存錢:

public class BankBusinessHandler extends AbstractBusinessHandler {

    public void saveVip(BigDecimal amount) {

        execute(() -> "vipNumber-00" + RandomUtils.nextInt(), a -> System.out.println("save " + amount));

    }

    public void save(BigDecimal amount) {

        execute(() -> "number-00" + RandomUtils.nextInt(), a -> System.out.println("save " + amount));

    }

    public void saveReservation(BigDecimal amount) {

        execute(() -> "reservationNumber-00" + RandomUtils.nextInt(), a -> System.out.println("save " + amount));

    }

}

在多個不同的存錢方法中,實現(xiàn)不同的取號邏輯,把取號邏輯封裝在supplier中,然后傳入execute方法即可。

測試代碼如下:

BankBusinessHandler businessHandler = new BankBusinessHandler();

businessHandler.saveVip(new BigDecimal("1000"));

輸出結果:

vipNumber-001638110566

Assign To Vip Counter

save 1000

give a praised

以上,我們就是用Comsumer和Supplier改造了模板方法模式。

使用Java 8對模板方法進行改造之后,可以進一步的減少代碼量,至少可少創(chuàng)建很多實現(xiàn)類,大大的減少重復代碼,提升可維護性。

當然,這種做法也不是十全十美的,有一個小小的缺點,那就是理解成本稍微高一點,對于那些對函數(shù)式編程不太熟悉的開發(fā)者來說, 上手成本稍微高了一些。。。

總結

以上,我們介紹了什么是模板方法模式,以及如何使用Comsumer和Supplier改造模板方法模式。

這樣的做法是我們日常開發(fā)中經常會用到的,其實,我覺得本文中的例子并不是完完全全能表達出來我想表達的意思,但是我們的真實業(yè)務中的邏輯講起來又比較復雜。

所以,這就需要大家能夠多多理解并且實踐一下。如果你代碼中用到過模板方法模式,那一定是可以通過本文中的方法進行改造的。

如果你還沒用過模板方法模式,那說明你的應用中一定有很多重復代碼,那就趕緊用起來。

到此這篇關于使用Java8實現(xiàn)模板方法模式的改造的文章就介紹到這了,更多相關Java8改造模板方法模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java中List接口的方法詳解

    java中List接口的方法詳解

    這篇文章主要介紹了java中List接口的方法詳解,List接口是繼承Collection接口,所以Collection集合中有的方法,List集合也繼承過來,本文主要介紹一下list下的方法,需要的朋友可以參考下
    2023-10-10
  • JDK14性能管理工具之jstack使用介紹

    JDK14性能管理工具之jstack使用介紹

    jstack工具主要用來打印java堆棧信息,主要是java的class名字,方法名,字節(jié)碼索引,行數(shù)等信息。這篇文章主要介紹了JDK14性能管理工具之jstack使用介紹,需要的朋友可以參考下
    2020-05-05
  • MybatisPlus代碼生成器的使用方法詳解

    MybatisPlus代碼生成器的使用方法詳解

    在這里我將展示如何自動生成實體類、控制層、服務層、mapper等代碼,這些基礎的代碼全部不需要我們手動創(chuàng)建,由MybatisPlus自動幫我們完成,我們只需要告訴MybatisPlus怎么生成這些代碼就可以了,在此之前我們需要配置好測試的環(huán)境,數(shù)據(jù)庫和表數(shù)據(jù) ,需要的朋友可以參考下
    2021-06-06
  • Jvm調優(yōu)和SpringBoot項目優(yōu)化的詳細教程

    Jvm調優(yōu)和SpringBoot項目優(yōu)化的詳細教程

    這篇文章主要介紹了Jvm調優(yōu)和SpringBoot項目優(yōu)化,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Java 格式化輸出JSON字符串的2種實現(xiàn)操作

    Java 格式化輸出JSON字符串的2種實現(xiàn)操作

    這篇文章主要介紹了Java 格式化輸出JSON字符串的2種實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • java 爬蟲詳解及簡單實例

    java 爬蟲詳解及簡單實例

    這篇文章主要介紹了java 爬蟲詳解及簡單實例的相關資料,需要的朋友可以參考下
    2017-05-05
  • java并發(fā)學習之BlockingQueue實現(xiàn)生產者消費者詳解

    java并發(fā)學習之BlockingQueue實現(xiàn)生產者消費者詳解

    這篇文章主要介紹了java并發(fā)學習之BlockingQueue實現(xiàn)生產者消費者詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot讀取excel表格的示例代碼

    SpringBoot讀取excel表格的示例代碼

    這篇文章主要介紹了SpringBoot讀取excel表格的示例代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Java深入講解Object類常用方法的使用

    Java深入講解Object類常用方法的使用

    前面java繼承中說到的Object類是java中一個特殊的類,所有的類都是直接或者間接的繼承自Object類,即如果某個類沒有使用extends關鍵字則默認是java.lang.Object類的子類,所以所有的類都可以使用Object類中定義的方法,下面介紹Object類的常用方法
    2022-04-04
  • 基于Listener監(jiān)聽器生命周期(詳解)

    基于Listener監(jiān)聽器生命周期(詳解)

    下面小編就為大家?guī)硪黄贚istener監(jiān)聽器生命周期(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論