设计模式 - 策略模式

设计模式 - 策略模式

类图

类图

解析

  1. 策略模式是一种定义一系列算法的方法, 从概念上看, 所有的这些算法完成的都是相同的工作, 只是实现不同. 他可以用同样的方式调用任意的一个算法, 减少了算法类与使用算法类之间的耦合.

  2. 策略模式中的 Strategy 类层为 Context 定义了一系列可供重用的算法或行为. 继承有处于析取这些算法中的公共功能.

  3. 简化了单元测试, 因为每个算法都有自己的类, 可以通过自己的接口单独测试.

  4. 只要在分析的过程中听到需要在不同时间应用不同的业务规则, 就可以考虑使用策略模式处理这种变化的可能性.

例子

场景: 超市收银机, 有不同的优惠策略.

定义打折类

public abstract class Discount {
    public abstract double algorithm(double money);
}

定义三个具体的优惠策略: 1) 不打折, 2) 打X折, 3) 满XXX返XXX

public class DiscountNormal extends Discount {
    @Override
    public double algorithm(double money) {
        return money;
    }
}
public class DiscountRebate extends Discount {

    private double debate = 1d;

    public DiscountRebate(double debate) {
        this.debate = debate;
    }

    @Override
    public double algorithm(double money) {
        return money*debate;
    }
}

public class DiscountReturn extends Discount {

    private double conditionMoney;
    private double returnMoney;

    public DiscountReturn(double conditionMoney, double returnMoney) {
        this.conditionMoney = conditionMoney;
        this.returnMoney = returnMoney;
    }

    @Override
    public double algorithm(double money) {
        return money - Math.floor(money/conditionMoney)*returnMoney;
    }
}

定义Context类

public class CashierContext {

    private Discount discount;

    public CashierContext(Discount discount) {
        this.discount = discount;
    }

    public double getResult(double money) {
        return this.discount.algorithm(money);
    }
}

客户端

import java.util.Scanner;

public class ClientMain {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int strategy = 1;
        double input = 0.0d;
        Discount algorithm = null; // 策略的具体实现要由客户端程序员完成

        try {
            System.out.print("选择打折方式:\n1: 不打折\n2: 打八折\n3: 满200返20\n> ");
            strategy = scanner.nextInt();
            System.out.print("输入金额: ");
            input = scanner.nextDouble();
        } catch (Exception e) {
            System.out.println("您的输入有误.");
        }
        switch (strategy) { //客户端程序员任然有选择的压力
            case (1):
                algorithm = new DiscountNormal();
                break;
            case (2):
                algorithm = new DiscountRebate(0.8);
                break;
            case (3):
                algorithm = new DiscountReturn(200, 20);
                break;
        }
        System.out.println("最终金额: " + (new CashierContext(algorithm).getResult(input))); // Context 类也要由客户端完成.
    }
}

在这个程序中, 客户端程序员编写分流的代码. 在现在的基础上使用简单工厂模式便可以消除分流的代码.

定义工厂上下文类

public class CashierFactoryContext {

    Discount algorithm = null;

    public CashierFactoryContext(int strategy) {
        switch (strategy) { //客户端程序员任然有选择的压力
            case (1):
                this.algorithm = new DiscountNormal();
                break;
            case (2):
                this.algorithm = new DiscountRebate(0.8);
                break;
            case (3):
                this.algorithm = new DiscountReturn(200, 20);
                break;
        }
    }

    public double getResult(double money) {
        return this.algorithm.algorithm(money);
    }
}

客户端程序

import java.util.Scanner;

public class FactoryClientMain {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int strategy = 1;
        double input = 0.0d;

        try {
            System.out.print("选择打折方式:\n1: 不打折\n2: 打八折\n3: 满200返20\n> ");
            strategy = scanner.nextInt();
            System.out.print("输入金额: ");
            input = scanner.nextDouble();
        } catch (Exception e) {
            System.out.println("您的输入有误.");
        }
        System.out.println("最终金额: " + (new CashierFactoryContext(strategy).getResult(input)));
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值