设计模式-策略模式

设计模式-策略模式

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

现金收费抽象类

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就可以,耦合更加降低!

相关推荐
触底反弹30 分钟前
🤯 面试被问 AI Workflow 和 Agent 有啥区别?3 张图 + 2 段代码讲清楚!
人工智能·设计模式·面试
张小姐的猫18 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
杨充21 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充21 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充21 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充21 小时前
2.面向对象的特性
设计模式
杨充21 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充21 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充21 小时前
3.接口vs抽象类比较
设计模式