设计模式-策略模式
先使用简单工厂设计一个商场收银软件
现金收费抽象类
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就可以,耦合更加降低!