java-設計模式-策略模式

策略模式 和 狀態模式有點像,但是比狀態模式稍微比較簡單。

狀態模式的狀態之間是可以互相轉換的,但是策略模式的策略之間是相互獨立的。

 

策略模式 是把每個策略(解決問題的方法)獨立成類,調用者只需要調用抽象策略,具體的實現策略以具體的情況而定。

策略的理解可以是一系列可以解決同一類問題的方法。

比如 小明去上班這個問題,策略可以有:走路、騎車、公交車、自駕,它們都可以解決 從 小明家 到 公司 這個問題。

 

下面以 網上購物付款 這個問題來說明策略模式

支付策略有:支付寶付款、微信付款、銀聯付款

 

支付接口(抽象的策略):

/**
 * 支付接口
 */
public interface Pay {
    /**
     * 進行支付
     */
    boolean doPay(double money);
}

 支付寶支付 策略(具體策略1)

/**
 * 支付實現類 支付寶支付
 */
public class AliPay implements Pay {
    @Override
    public boolean doPay(double money) {
        System.out.println("使用支付寶支付 打95折 ");
        money = money * 0.95;
        System.out.println("實際消費 "+money +" 並且得到阿里積分 "+(money/10));
        return false;
    }
}

微信支付 策略(具體策略2)


/**
 * 微信支付
 */
public class MicroPay implements Pay{
    @Override
    public boolean doPay(double money) {
        System.out.println("使用微信支付 打98折");
        money = money * 0.98;
        System.out.println("實際消費 "+money);
        return true;
    }
}

銀聯支付 策略(具體策略3)

/**
 * 銀聯支付策略
 */
public class BlankPay implements Pay {
    @Override
    public boolean doPay(double money) {
        System.out.println("使用銀聯支付 打85折");
        money = money * 0.85;
        System.out.println("實際消費 "+money +" 並且得到銀聯積分 "+(money/1));
        return true;
    }
}

 

對外使用的策略(策略上下文Context)

使用 工廠方法 對支付類 進行實例。

構造函數 需要傳入支付方式

只暴露 doPay()供對外調用,使用者不需要關係具體是用什麼進行支付的


/**
 * 支付的上下文
 */
public class PayHelp {
    public static final int PAY_TYPE_ALI = 0;
    public final int PAY_TYPE_MICRO = 1;
    public final int PAY_TYPE_BLANK = 2;

    //支付
    private Pay pay;

    /**
     * 構造方法
     */
    public PayHelp(int payType){
        initPayType(payType);
    }

    /**
     * 初始化 支付類型 用工廠方法進行實例
     * @param payType
     */
    public void initPayType(int payType){
        switch (payType){
            case PAY_TYPE_ALI:
                pay = new AliPay();
                break;
            case PAY_TYPE_MICRO:
                pay = new MicroPay();
                break;
            case PAY_TYPE_BLANK:
                pay = new BlankPay();
                break;
            default:
                pay = new AliPay();
        }
    }

    /**
     * 進行支付
     */
    public boolean doPay(double money){
        return pay.doPay(money);
    }

}

 

測試類:


import java.util.Scanner;

public class StrategyTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String text = null;
        System.out.println("請輸入結算方式(0支付寶 1 微信 2 銀聯):");
        while ((text = scanner.next()) != null){
            if(text.equals("0") || text.equals("1")||text.equals("2")){
                PayHelp payHelp = new PayHelp(Integer.parseInt(text));
                System.out.println("請輸入金額:");
                double d = scanner.nextDouble();
                payHelp.doPay(d);
                System.out.println();
                System.out.println("請輸入結算方式(0支付寶 1 微信 2 銀聯):");
            }else {
                System.out.println("結算方式輸入錯誤,請重新輸入(0支付寶 1 微信 2 銀聯):");
            }
        }
    }
}

運行效果:

請輸入結算方式(0支付寶 1 微信 2 銀聯):
0
請輸入金額:
12.12
使用支付寶支付 打95折 
實際消費 11.514 並且得到阿里積分 1.1514

請輸入結算方式(0支付寶 1 微信 2 銀聯):
1
請輸入金額:
23.12
使用微信支付 打98折
實際消費 22.657600000000002

請輸入結算方式(0支付寶 1 微信 2 銀聯):
2
請輸入金額:
76.09
使用銀聯支付 打85折
實際消費 64.6765 並且得到銀聯積分 64.6765

運行結果會根據具體選擇的結算方式來實例 Pay,如果這個時候多加了個 iphone支付,那麼只要再新增一個iphone支付的類以及把PayHelper()簡單改造下就可以了,不用去修改客戶端調用的方法(如果此客戶端不需要iphone支付)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章