時勢造英雄——策略模式

《Android源碼設計模式解析與實戰》讀書筆記(七)php

《Android源碼設計模式解析與實戰》PDF資料下載算法

1、策略模式的簡介

1.一、定義

策略模式定義了一系列的算法,並將每個算法封裝起來,並且使它們還能夠相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。設計模式

1.二、使用場景

  • 針對同一類型問題的多種處理方式,僅僅是具體行爲有差異時;
  • 須要安全地封裝多種同一類型的操做時。
  • 出現同一抽象類有多個子類,而又須要使用if-else或者switch-case來選擇具體子類時。

2、策略模式的簡單實現

示例:公交車和地鐵的價格計算方式是不同的,須要計算乘不一樣出行工具的成本,下面是初版的代碼:安全

public class PriceCalculator {
    //公交車類型
    private static final int BUS = 1;
    //地鐵類型
    private static final int SUBWAY = 2;

    public static void main(String[] args) {
        PriceCalculator calculator = new PriceCalculator();
        System.out.println("坐16千米的公交車票價爲:" + calculator.calculatePrice(16, BUS));
        System.out.println("坐16千米的地鐵票價爲:" + calculator.calculatePrice(16, SUBWAY));
    }

    /**
     * 北京公交車,十千米以內一元錢,超過十千米以後每加一元錢能夠乘5千米
     *
     * @param km
     * @return
     */
    private int busPrice(int km) {
        //超過十千米的總距離
        int extraTotal = km - 10;
        //超過的距離是5千米的倍數
        int extraFactor = extraTotal / 5;
        //超過的距離對5千米取餘
        int fraction = extraTotal % 5;
        //價格計算
        int price = 1 + extraFactor * 1;
        return fraction > 0 ? ++price : price;
    }

    /**
     * 6千米(含)內3元;6~12千米(含)4元;12~22千米(含)5元;22~32千米(含)6元;
     * @param km
     * @return
     */
    private int subwayPrice(int km) {
        if (km <= 6) {
            return 3;
        } else if (km > 6 && km <= 12) {
            return 4;
        } else if (km > 12 && km <= 22) {
            return 5;
        } else if (km > 22 && km <= 32) {
            return 6;
        }
        return 7;
    }

    int calculatePrice(int km, int type) {
        if (type == BUS) {
            return busPrice(km);
        } else if (type == SUBWAY) {
            return subwayPrice(km);
        }
        return 0;
    }
}
複製代碼

輸出結果:bash

策略模式1.png

此時的代碼已經比較混亂,各類if-else語句纏繞其中。當價格的計算方法變化時,須要直接修改這個類中的代碼,很容易引入錯誤。 這類代碼必然是難以應對變化的,它會使得代碼變得愈來愈臃腫,難以維護。微信

用策略模式對上述示例進行重構:ide

/**
 * 計算接口
 */
public interface CalculateStrategy {
    /**
     * 按距離來計算價格
     * @param km
     * @return
     */
    int calculatePrice(int km);
}
複製代碼
//公交車價格計算策略
public class BusStrategy implements CalculateStrategy {
    /**
     * 北京公交車,十千米以內一元錢,超過十千米以後每加一元錢能夠乘5千米
     * @param km
     * @return
     */
    @Override
    public int calculatePrice(int km) {
        //超過十千米的總距離
        int extraTotal = km - 10;
        //超過的距離是5千米的倍數
        int extraFactor = extraTotal / 5;
        //超過的距離對5千米取餘
        int fraction = extraTotal % 5;
        //價格計算
        int price = 1 + extraFactor * 1;
        return fraction > 0 ? ++price : price;
    }
}
複製代碼
public class SubwayStrategy implements CalculateStrategy {
    @Override
    public int calculatePrice(int km) {
        if (km <= 6) {
            return 3;
        } else if (km > 6 && km <= 12) {
            return 4;
        } else if (km > 12 && km <= 22) {
            return 5;
        } else if (km > 22 && km <= 32) {
            return 6;
        }
        return 7;
    }
}
複製代碼

再建立一個扮演Context角色的類工具

public class TranficCalculator {
    public static void main(String[] args) {
        TranficCalculator calculator = new TranficCalculator();
        //設置計算策略
        calculator.setStrategy(new BusStrategy());
        //計算價格
        System.out.println("坐16千米的公交車票價爲:"+calculator.calculatePrice(16));
    }

    CalculateStrategy mStrategy;
    public void setStrategy(CalculateStrategy mStrategy) {
        this.mStrategy = mStrategy;
    }

    public int calculatePrice(int km) {
        return mStrategy.calculatePrice(km);
    }
}
複製代碼

這種方案在隱藏實現的同時,可擴展性變得很強。在簡化邏輯、結構的同時,加強了系統的可讀性、穩定性、可擴展性,這對於較爲複雜的業務邏輯顯得更爲直觀,擴展也更爲方便。ui

3、總結

策略模式主要用來分離算法,在相同的行爲抽象下有不一樣的具體實現策略。這個模式很好地演示了開閉原則,也就是定義抽象,注入不一樣的實現,從而達到很好的可擴展性。this

3.一、優勢

  1. 結構清晰明瞭、使用簡單直觀;
  2. 耦合度相對而言較低,擴展方便;
  3. 操做封裝也更爲完全,數據更爲安全。

3.二、缺點

  1. 隨着策略的增長,子類也會變得繁多。

學海無涯苦做舟

個人微信公衆號
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息