策略模式

策略模式

策略模式概述

策略模式的定义:策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到其他客户

策略模式和简单工厂模式配合使用,可以让客户端只知道strategyContext对象,而不需要知道所有的算法实现类对象

策略模式的结构

image.png

抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口实现。此角色给出所有的具体策略类所需的接口。

具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

策略上下文(Context)角色:持有一个Strategy的引用,并且在某处调用了算法。模式的实现

策略模式的实现

1.定义一个算法抽象类或者接口

public abstract class CashSupper {
    private Double money;

    public abstract Double acceptCash(double money);

}

2.定义具体的算法实现类继承抽象类或实现接口

public class CashNormal extends CashSupper {

    @Override
    public Double acceptCash(double money) {
        return money;
    }
}
public class CashRebate extends CashSupper {

    private Double moneyRebate;

    public CashRebate(Double moneyRebate) {
        this.moneyRebate = moneyRebate;
    }

    @Override
    public Double acceptCash(double money) {
        return moneyRebate * money;
    }
}
public class CashReturn extends CashSupper {
    private Double returnMoney;
    private Double conditionMoney;

    public CashReturn(Double returnMoney, Double conditionMoney) {
        this.returnMoney = returnMoney;
        this.conditionMoney = conditionMoney;
    }

    @Override
    public Double acceptCash(double money) {
        double resultMoney = money;
        if (money >= conditionMoney) {
            //满减
            resultMoney = money - Math.floor(money / conditionMoney) * returnMoney;
        }
        return resultMoney;
    }
}

3.定义策略上下文角色(此处配合简单工厂使用)

简单工厂不仅仅是一个工厂类,也可以通过构造器

package org.example.strategy;

/**
 * @author 
 * @date 2021/3/9 10:42
 **/
public class CashContext {

    private CashSupper cashSupper;

    //public CashContext(CashSupper cashSupper) {
    //
    //
    //    //重写构造器,让简单工厂模式与策略模式配合使用
    //
    //    //this.cashSupper = cashSupper;
    //
    //}
    public CashContext(String type){
        switch (type){
            case "正常收费":
                cashSupper=new CashNormal();
                break;
            case "满300减100":
                cashSupper=new CashReturn(100D,300D);
                break;
            case "打8折":
                cashSupper=new CashRebate(0.8);
            default:
        }
    }


    public double getResult(double money){
        return cashSupper.acceptCash(money);
    }
}

4.客户端调用

package org.example.strategy;

/**
 * @author 
 * @date 2021/3/9 10:52
 **/
public class Test2 {

    public static void main(String[] args) {
        CashContext context = new CashContext("打8折");
        System.out.println("300元打八折后价格为:" + context.getResult(300));
        CashContext context1 = new CashContext("满300减100");
        System.out.println("700满300减100后价格为:" + context1.getResult(700));
        CashContext context2 = new CashContext("正常收费");
        System.out.println("300元正常收费价格为:" + context2.getResult(300));
    }
}

5.运行结果

image.png

策略模式的优缺点

优点

1.上下文和具体策略是松耦合关系。因此上下文只知道它要使用某一个实现Strategy接口类的实例,但不需要知道具体是哪一个类,连实现对象的父类都不知道,只知道一个上下文对象。

2.策略模式满足“开-闭原则”。当增加新的具体策略时,不需要修改上下文类(不搭配工厂模式的情况下)的代码,上下文就可以引用新的具体策略的实例。

缺点

因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容