策略模式

刚开始看《大话设计模式》这本书,在此记录一些个人的理解,不当之处请指教。

策略模式

策略模式是对一些规则/算法的封装模式,有时候需要对一个数据根据应用场景的不同做不同的处理,为避免太多的逻辑判断,减少代码的耦合,处理的方式可以封装起来。

结构如图:

比如在本按例中,需要对收到的金额做不同的处理,1、普通收费,2、打折销售,3、积分抵扣

从所有的方法类中抽取一个运算的抽象方法,形成一个抽象类

package cn.sasa.strategy;

//运算方法的抽象类
public abstract class Strategy {
    //抽象方法
    public abstract double Calculate(double momey);
}

各个计算方法继承Strategy

package cn.sasa.strategy;
//普通计算
public class NormalCalculate extends Strategy{

    @Override
    public double Calculate(double momey) {
        return momey;
    }

}
package cn.sasa.strategy;

import java.math.BigDecimal;
//打折销售
public class DiscountCalculate extends Strategy{

    private double discount = 1d;
    
    public DiscountCalculate(double discount) {
        this.discount = discount;
    }
    
    @Override
    public double Calculate(double money) {
        BigDecimal moneydec = new BigDecimal(money);
        BigDecimal discountdec = new BigDecimal(discount);
        return moneydec.multiply(discountdec).doubleValue();
    }

}
package cn.sasa.strategy;
//积分抵扣
public class ScourCalculate extends Strategy{

    private double scour = 0;
    private double subMoney = 0; 
    public ScourCalculate(double scour) {
        this.scour = scour;
        subMoney = this.scour*0.001;
    }
    
    @Override
    public double Calculate(double money) {
        return money-subMoney;
    }

}

处理规则

package cn.sasa.strategy;
//处理规则的类
public class StrategyContext {
    public Strategy stra;

    // 传递一个标识
    //策略与简单工厂结合
    public StrategyContext(int flag) {
        switch (flag) {
        case 1:
            stra = new NormalCalculate();
            break;
        case 2:
            stra = new DiscountCalculate(0.8);
            break;
        case 3:
            stra = new ScourCalculate(200);
            break;        
        }
    }

    // 调用计算的方法
    public double Calculate(double money) {
        return stra.Calculate(money);
    }

}

客户端代码:

package cn.sasa.strategy;

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        System.out.println("请输入计算方式");
        System.out.println("1、普通计算 2、打折销售 3、积分抵扣");
        Scanner sc = new Scanner(System.in);
        int flag = sc.nextInt();
        System.out.println("你输入的是"+flag);
        StrategyContext context = new StrategyContext(flag);
        System.out.println(context.Calculate(200));
    }
}

这样如果再增加计算的规则,那么只需要再定义一个计算的类,再在处理规则的类中添加相应的处理。

每个规则都是独立的,规则之间互不影响,在进行测试的时候更容易发现问题。

原文地址:https://www.cnblogs.com/SasaL/p/10616905.html