策略模式-

案例

做一个商场的收银软件,根据客户的所购买的商品的单价和数量去收费

代码

主实现

package day2;

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        Product product1=new Product("苹果",5,3);
        Product product2=new Product("香蕉",6,5);
        List<Product> products=new ArrayList<>();
        products.add(product1);
        products.add(product2);
        PointSale pos=new PointSale();
        double total=pos.calculateTotal(products);
        System.out.println(total);
    }
}

商品类

package day2;

public class Product {
    String name;
    double price;
    int quantity;

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", quantity=" + quantity +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public Product(String name, double price, int quantity) {
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
}

收银机类

package day2;

import java.util.List;

public class PointSale {
    public double calculateTotal(List<Product> products){
        double total=0;
        for(Product product:products){
            total+=product.getPrice()*product.getQuantity();

        }
        return total;
    }
}

问题1 

如果要增加打折的代码怎么办或者是需要满减的活动代码 我们需要去思考一下 有什么东西是相同的

简单工厂类的处理方法

工厂类

package day2;

public class cashFactory {
    public static cashSuper creatCashAccept(String type){
        cashSuper cs=null;
        switch (type){
            case"正常收费":
                cs=new CashNormal();
                break;
                case"满300反10":
               CashReturn cr1=new CashReturn(300,10);
               cs=cr1;
                    break;
            case"打折":
                cashRebate cr2=new cashRebate(0.8);
                cs=cr2;
                break;
        }
        return cs;
    }

}

正常收费类

package day2;

public class CashNormal extends cashSuper {

    @Override
    public double acceptCash(double money) {
        return money;
    }
}

返利类

package day2;

public class cashRebate extends cashSuper{
    public cashRebate(double rebate) {
        this.rebate = rebate;
    }

    double rebate=0;
    @Override
    public double acceptCash(double money) {
        return rebate*money;
    }
}

买多少反多少类

package day2;

public class CashReturn extends cashSuper{
 double moneyCondition=0;
 double moneyReturn=0;

    public CashReturn(double moneyCondition, double moneyReturn) {
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }

    @Override
    public double acceptCash(double money) {
        double result=0;
        if (money>=moneyCondition)
            result=money-Math.floor(money/moneyCondition)*moneyReturn;
        return result;
    }
}

抽象收费类

package day2;

abstract class cashSuper {
    public abstract  double acceptCash(double money);
}

客户端代码

缺点:

简单工厂模式虽然可以解决这个问题,但这个模式只是解决对象的创建问题,而且由于工厂本身包括了所有的收费方式,商场是可能经常性的更改打折额度和返利额度,每次维护的话都要去改动这个工厂,以至于代码需要去重新编译部署。

策略模式:

定义:

定义一系列算法,封装每一个算法,并使他们可以互换。

像商场收银时如何促销,用打折还是返利,其实都是一些算法,用工厂来生成算法对象。

策略模式在实际的开发中很常见,最常见的应用场景是利用他来替换过多的if-else嵌套的逻辑判断。

代码

context

package day2;

public class CashContext {
    private cashSuper cs;

    public CashContext(cashSuper cs) {
        this.cs = cs;
    }
    public double GetResult(double money){
        return cs.acceptCash(money);
    }
}

客户端代码也需要去修改一下

缺点:

代码回到了原来的老路 需要去用客户端去判断使用哪一个算法  那怎么就可以将这个判断的过程从客户端程序中转移走呢  ------------原来的简单工厂就可以完成这个任务 ----------------简单工厂不一定非要是一个单独的类 可以和策略模式的context去结合

策略和简单模式结合

代码

context

package day2;

public class CashContext {
    cashSuper cs=null;
    public  CashContext(String type){
        
        switch (type){
            case"正常收费":
                cs=new CashNormal();
                break;
            case"满300反10":
                CashReturn cr1=new CashReturn(300,10);
                cs=cr1;
                break;
            case"打折":
                cashRebate cr2=new cashRebate(0.8);
                cs=cr2;
                break;
        }
        
    }

    public CashContext(cashSuper cs) {
        this.cs = cs;
    }
    public double GetResult(double money){
        return cs.acceptCash(money);
    }
}

客户端

就是将cashFactory中的代码搬过来 客户端代码稍作改变 剩下的一样

客户端代码的不同之处

策略模式 解析

策略模式是一种定义一系列算法的方法,从概念上来看 所有的这些算法完成的都是相同的工作 知识实现不同 它可以用相同的方式去调用所有的算法 减少了各种算法类与只用算法类之间的耦合 

策略模式的strategy类层次为context定义了一系列可以重用的算法或行为 继承有助于吸取出这些算法中的公共功能 

策略模式简化了单元测试 因为每一个算法都有自己的类 可以通过自己的接口单独测试

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值