设计模式-策略模式

设计模式-策略模式

先使用简单工厂设计一个商场收银软件

现金收费抽象类

java 复制代码
abstract class CashSuper
{
    public abstract double acceptCash(double money);//现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价
}

正常收费子类

java 复制代码
class CashNormal:CashSuper
{
    public override double acceptCash(double money){
        return money;
    }
}

打折收费子类

java 复制代码
class CashRebate:CashSuper
{
    private double moneyRebate = 1d;
    public CashRebate(string moneyRebate){
        this.moneyRebate = double.Parse(moneyRebate);        
    }
    public override double acceptCash(double money){
        return money*moneyRebate;
    }
}

返利收费子类

java 复制代码
class CashReturn:CashSuper
{
    private double moneyCondition = 0.0d;
    private double moneyReturn = 0.0d;
    public CashReturn(string moneyCondition,string moneyReturn){
        this.moneyCondition = double.Parse(moneyCondition);
        this.moneyReturn = double.Parse(moneyReturn);
    }
    public override double acceptCash(double money){
        double result = money;
        if(money >= moneyCondition)
            result = money - Math.Floor(money/moneyCondition) * moneyReturn;
        return result
    }
}

现金收费工厂类

java 复制代码
class CashFactory{
    public static CashSuper createCashAccept(string type){
        CashSuper cs = null;
        switch(type){
			case "正常收费";
                cs = new CashNormal();
                break;
 			case "满300返100";
                cs = new CashReturn("300","100");
                break;    
			case "打8折";
                cs = new CashRebate("0.8");
                break;                
        }
        return cs;
    }
}

客户端窗体程序(主要部分)

java 复制代码
double total = 0.0d;
private void btnOK_Click(object sender,EventArgs e){
    CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());//要收的费用超类体现了多态
    double totalPrices = 0d;
    totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.txt));//单价x数量是原价
    total = total + totalPrices;
}

简单工厂的缺点

复制代码
增加 需要打5折或者满500送200的促销活动时候,需要在生成工厂添加两个条件。
增加 满100积分10点,需要加一个积分算法,构造方法有两个参数:条件和返点,让它继承CashSuper,再增加分支条件。

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

策略模式

Strategy类,定义所有支持的算法的公共接口

java 复制代码
//抽象算法类
abstract class Strategy
{
    //算法方法
    public abstract void AlgorithmInterface();
}

ConcreteStrategy,封装了具体的算法或行为,继承于Strategy

java 复制代码
//具体算法A
class ConcreteStategyA:Strategy{
    //算法A实现方法
    public override void AlgorithmInterface(){
        Console.WriteLine("算法A实现")
    }
}
//具体算法B
class ConcreteStategyB:Strategy{
    //算法B实现方法
    public override void AlgorithmInterface(){
        Console.WriteLine("算法B实现")
    }
}
//具体算法C
class ConcreteStategyC:Strategy{
    //算法C实现方法
    public override void AlgorithmInterface(){
        Console.WriteLine("算法C实现")
    }
}

Context,用一个ConcreteStrategy 来配置,维护一个对Strategy对象的引用

java 复制代码
//上下文
class Context
{
    Strategy strategy;
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    //上下文接口
    public void ContextInterface(){
        strategy.AlgorithmInterface();
    }
}

客户端代码

java 复制代码
static void Main(string[] args){
    Context context;
    context = new Context(new ConcreteStrategyA());
    context.ContextInterface();
    context = new Context(new ConcreteStrategyB());
    context.ContextInterface();
    context = new Context(new ConcreteStrategyC());
    context.ContextInterface();
}

策略模式实现商场收银

CashContext类(与简单工厂结合)
java 复制代码
class CashContext
{
    CashSuper cs = null;
    public CashContext(string type){
        switch(type){
			case "正常收费";
                cs = new CashNormal();
                break;
 			case "满300返100";
                cs = new CashReturn("300","100");
                break;    
			case "打8折";
                cs = new CashRebate("0.8");
                break;                
        }     
    }
    public double GetResult(double money){
        return cs.acceptCash(money);
    }
}
客户端主要代码
java 复制代码
double total = 0.0d;
private void btnOK_Click(object sender,EventArgs e){
    CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());
    double totalPrices = 0d;
    totalPrices = csuper.GetResult(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.txt));//单价x数量是原价
    total = total + totalPrices;
}

两种设计模式总结

java 复制代码
//简单工厂模式的用法
 CashSuper csuper = CashFactory.createCashAccept(...);
 ...=csuper.acceptCash(...);
java 复制代码
//策略模式与简单工厂结合的用法
CashContext csuper = new Cashcontext(...);
...=csuper.GetResult(...);

简单工厂模式需要让客户端认识两个类,CashSuper和CashFactory,而策略模式与简单工厂结合的用法,客户端只需要认识一个类CashContext就可以,耦合更加降低!

相关推荐
饼干哥哥21 小时前
一夜之间,全世界的 Agent 能力提高了一个档次
设计模式·agent·代码规范
Kel1 天前
管道、IPC、Socket:你以为的三种技术,其实是同一件事
javascript·设计模式·node.js
我登哥MVP1 天前
进 Gang of Four 设计模式:建造者模式
java·设计模式·建造者模式
进击的前栈2 天前
鸿蒙实战:19 页面全景汇总与 7 大共享设计模式回顾
华为·设计模式·harmonyos
刀法如飞2 天前
Spring Boot 4.1 + JDK 25 DDD开源脚手架,面向 AI 编程
设计模式·架构·ai编程
折哥的程序人生 · 物流技术专研2 天前
第8篇:模板方法模式的优缺点与面试高频考点
java·设计模式·面试·模板方法模式·行为型模式·优缺点·扩充系列
workflower2 天前
人形机器人全身运动控制能力大幅提升
人工智能·深度学习·机器学习·设计模式·机器人·自动化
折哥的程序人生 · 物流技术专研2 天前
Java 23 种设计模式:从踩坑到精通 | 备忘录模式 —— 快照与撤销,给对象装一个“后悔药”
java·设计模式·备忘录模式·行为型模式·java设计模式·从踩坑到精通·撤销重做
Kel2 天前
万物皆 Runnable:LangChain 如何用一个接口统一模型、链与图
人工智能·设计模式·架构
ttod_qzstudio2 天前
【软考设计模式】策略模式:算法族的封装与动态切换精讲
设计模式·策略模式