【原創】從策略模式閒扯到lambda表達式

引言

策略模式,講這個模式的文章不少,但都缺少一個按部就班的過程。講lambda表達式的文章也不少,但基本都是堆砌一堆的概念,不多帶有本身的看法。博主一時興起,想寫一篇這兩者的文章。須要說明的是,在看這篇文章的時候,請忘記全部的概念。容博主一步一步的帶大家入坑。java

正文

假設咱們有一個Hero類,其UML圖以下
image
這個時候,咱們有一個需求:算法

  • 咱們要找出type爲刺客的Hero

這時,咱們先封裝一個要根據type類型來篩選Hero的方法ide

public static List<Hero> getHero(List<Hero> heroList, String type){
        List<Hero> result = new ArrayList<Hero>();
        for(Hero hero : heroList){
            if(type.equals(hero.getType())){
                result.add(hero);
            }
        }
        return result;
    }

而後呢,作以下調用性能

getHero(heroList, "刺客");

忽然有一天,產品忽然改需求,如今的需求spa

  • 咱們要找出stature(身高)大於170的Hero

也很簡單嘛,再加一個重載的getHero方法就能夠嘛,重載的getHero(List heroList, int stature)方法以下 code

public static List<Hero> getHero(List<Hero> heroList, int stature){
        List<Hero> result = new ArrayList<Hero>();
        for(Hero hero : heroList){
            if(hero.getStature() > stature){
                result.add(hero);
            }
        }
        return result;
    }

而後呢,作以下調用對象

getHero(heroList, 170);

又過了幾日,產品喪心病況的又改需求,如今最新的需求blog

  • 要找出stature(身高)大於170而且type類型爲刺客的Hero

固然,你或許說了,能夠再加一個getHero(List heroList, String type, int stature)方法呀。不過呢,這種改法不夠優雅。方法體中存在大量相同的代碼,只是判斷條件稍做改變。在這種狀況下使用策略模式,就可以解決這個問題。
稍微介紹一下策略模式
策略模式
意圖:策略模式定義了一系列的 算法,並將每個 算法封裝起來,並且使他們能夠相互替換,讓算法獨立於使用它的客戶而獨立變化。
get

主要解決:在有多種算法類似的狀況下,使用 if...else 所帶來的複雜和難以維護。產品

什麼時候使用:一個系統有許多許多類,而區分它們的只是他們直接的行爲。

如何解決:將這些算法封裝成一個一個的類,任意地替換。

ps:在這裏,上面的算法指的就是上面提到的判斷條件。咱們將判斷條件封裝爲相應的類。

此時代碼結構以下圖所示
image
那麼此時的getHero方法以下所示

public static List<Hero> getHero(List<Hero> heroList, Predicate<Hero> predicate){
        List<Hero> result = new ArrayList<Hero>();
        for(Hero hero : heroList){
            if(predicate.test(hero)){
                result.add(hero);
            }
        }
        return result;
    }

而後呢,根據需求作以下調用,想找那種類型的Hero,就傳那種類型的Predicate進去。

getHero(heroList,new TMPredicate());

但是呢,機智的你又發現了一個缺陷,每次新增一個算法,要新加一個實現類。因而,機智的你提出,利用匿名內部類來作調用,不寫實現類,因而調用代碼變成下面這樣

getHero(heroList,new Predicate<Hero>() {
    @Override
    public boolean test(Hero t) {
        return t.getStature() > 170 && "刺客".equals(t.getType());
    }
});

機智的你忽然間又以爲:這麼寫,佔用了太多的行數,看起來不夠美觀,因而,你決定用lambda表達式來改寫,因而代碼最終變成下面的樣子

getHero(heroList,(t)->t.getStature() > 170 && "刺客".equals(t.getType()));

好了,到這裏就結束了,是否是比咱們最開始的版本簡潔了很多,代碼優雅了不少。lambda主要的目的就是提供一個更加簡潔的代碼結構,可是對於初學者,它可能反而增長閱讀的難度。

固然,lambda表達式除了能簡化代碼代碼意外,還能並行處理元素,充分利用多核CPU的性能,例以下面的代碼

import java.util.Arrays;
import java.util.List;

public class Demo7 {
    public static void main(String[] args) {
        List<String> values = Arrays.asList("1","2","3","4");
        print(values);
    }

    public static void print(List<String> values){
       values.parallelStream().forEach(System.out :: println);//System.out表示對象,println表示方法
    }
}

輸出以下

3
4
1
2

總結

本文以循序漸近的方式說明了,咱們爲何要用策略模式以及如何用lambda表達式改寫策略模式。但願你們有所收穫。

參考文獻

《JAVA8實戰》

相關文章
相關標籤/搜索