设计模式之策略模式(加简单工厂模式)
案例:超市收银结账
咋们由浅到深。
需求一
要求通过商品单价和商品数量计算总价格
这个简单,一两分钟就好
public static void main(String[] args) {
//模拟一个商品的单价
double unitPrice = 10.50d;
//模拟商品的数量
int num = 6;
System.out.println(num * unitPrice);
}
需求二
超市打八折
// 模拟打折
private static final double discount = 0.8d;
public static void main(String[] args) {
//模拟一个商品的单价
double unitPrice = 10.50d;
//模拟商品的数量
int num = 6;
double money = discount * (num * unitPrice);
System.out.println(money);
}
从这里可以看出,超市的活动会很多,打的折扣不同,或者是满多少送多少,又或者是什么活动也没有,它们的相同的也就是初始参数不同
需求三
增加满减
使用简单工厂来进行操作一下
首先我们先定义一个现金收取方法抽象类
//现金收取方法抽象类
public abstract class CashSuper {
public abstract double acceptCash(double money);
}
定义实体类去继承现金收取方法抽象类
//正常收费
public class CashNormal extends CashSuper {
@Override
public double acceptCash(double money) {
return money;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//打折收费
public class CashRebate extends CashSuper {
// 打折
private double moneyRebate = 1d;
// 初始化定义打折率
public CashRebate(String moneyRebate) {
this.moneyRebate = Double.parseDouble(moneyRebate);
}
@Override
public double acceptCash(double money) {
return moneyRebate * money;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//满减
public class CashRrturn extends CashSuper {
//初始定义
// 满
private double moneyCondition = 0.0d;
// 返
private double moneyReturn = 0.0d;
public CashRrturn(String moneyCondition, String moneyReturn) {
this.moneyCondition = Double.parseDouble(moneyCondition);
this.moneyReturn = Double.parseDouble(moneyReturn);
}
@Override
public double acceptCash(double money) {
if (money >= moneyCondition) {
money = money - Math.floor(money / moneyCondition) * moneyReturn;
}
return money;
}
}
接下来是工厂的创建和界面代码
//我是工厂
public class CashFactory {
public CashSuper creatCashAccept(String type) {
CashSuper cs = null;
switch (type) {
case "正常收费":
cs = new CashNormal();
break;
case "满300减100":
cs = new CashRrturn("300", "100");
break;
case "打八折":
cs = new CashRebate("0.8");
break;
default:
break;
}
return cs;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//我是界面
public class XXX {
public static void main(String[] args) {
//模拟一个商品的单价
double unitPrice = 100d;
//模拟商品的数量
int num = 7;
// 购物类型
String type = "满300减100";
// 获取相应类型的对象
CashSuper csSuper = new CashFactory().creatCashAccept(type);
double money = csSuper.acceptCash(num * unitPrice);
System.out.println(money);
}
}
上面使用简单工厂来实现的,接下来我们使用策略模式来
何为策略模式:它定义了算法,分别封装起来,让他们可以相互替换。此模式让算法变化,不会影响到使用算法的客户
之前写的抽象类和子类都不用改变 ,需要写一个CashContext类,并改一下界面就好了
//上下文
public class CashContext {
private CashSuper cs = null;
public CashContext(CashSuper cs){
this.cs = cs;
}
public double getResult(double money){
return cs.acceptCash(money);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//我是界面
public class XXX {
public static void main(String[] args) {
//模拟一个商品的单价
double unitPrice = 100d;
//模拟商品的数量
int num = 7;
// 购物类型
String type = "满300减100";
CashContext cc = null;
switch (type) {
case "正常收费":
cc = new CashContext(new CashNormal());
break;
case "满300减100":
cc = new CashContext(new CashRrturn("300", "100"));
break;
case "打八折":
cc = new CashContext(new CashRebate("0.8"));
break;
default:
break;
}
double result = cc.getResult(num * unitPrice);
System.out.println(result);
}
}
使用了两种模式后发现:工厂模式你需要让界面认识两个类CashSuper和CashFactory,而策略模式只需要让界面知道CashContext就行
不过策略模式又让界面去判断使用那个算法。so
简单工厂模式与策略模式的结合
还是抽象类与其子类不需要改变,只需要改界面代码和上下文(CashContext)
//上下文
public class CashContext {
private CashSuper cs = null;
// 使用构造器去初始化CashSuper并判断算法
public CashContext(String type) {
switch (type) {
case "正常收费":
cs = new CashNormal();
break;
case "满300减100":
cs = new CashRrturn("300", "100");
break;
case "打八折":
cs = new CashRebate("0.8");
break;
}
}
public double getResult(double money){
return cs.acceptCash(money);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//我是界面
public class XXX {
public static void main(String[] args) {
//模拟一个商品的单价
double unitPrice = 100d;
//模拟商品的数量
int num = 7;
// 购物类型
String type = "满300减100";
// 传一个类型就可以了
CashContext cc = new CashContext(type);
double result = cc.getResult(num * unitPrice);
System.out.println(result);
}
}
现在要改什么算法,只需要在CashContext里面更改更改就好,不过还是很麻烦,每次都需要去更改swith代码。
这个还有更简单的办法,用到了反射的技术,以后会提到的,嘿嘿
反射反射,程序员的快乐
高手与菜鸟的区别在于做同样的事,花最小的代价。或者花同样的代价获取最大的收益。
就比如一样的需求更改,十分钟后,高手都开始玩第二局王者荣耀了。菜鸟还刚理清代码。
加油一起努力吧。程序员!
本文介绍策略模式与简单工厂模式结合应用在超市收银结账的案例。通过定义算法并封装,使得算法可以在不修改客户端的情况下进行更换。具体包括正常收费、打折收费及满减等场景。
1802

被折叠的 条评论
为什么被折叠?



