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支付)。

发布了60 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/xiaoluo5238/article/details/104599582