写一个商品结算程序:
我:想起了上次的优化,使用简单工厂设计模式改进一次。
策略与简单工厂模式的结合
简单工厂模式
最后的反思:感觉策略模式用处并不是很大,只不过封装了一次,让调用者与算法分离。降低耦合度,但是代码量增多了,阅读复杂。更多等以后理解更深刻了,再补充。
public class Program {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("单价:");
String numberOne = sc.next();
System.out.println("数量:");
String numberTwo = sc.next();
System.out.println("打折率:");
String rang = sc.next();
if(!StringUtils.isNumeric(rang)){
System.out.println("打折率输入错误");
System.exit(0);
}
// 获取实际打折率
float[] rangArr = new float[]{0,0.9f,0.8f,0.7f};
float total = 0f;
String rangStr = "不打折";
try {
switch (Integer.parseInt(rang)) {
case 0 :
total = Float.parseFloat(numberOne) * Float.parseFloat(numberTwo);
rangStr = "不打折";
break;
case 9 :
total = Float.parseFloat(numberOne) * Float.parseFloat(numberTwo) * rangArr[10 - Integer.parseInt(rang)];
rangStr = "打9折";
break;
case 8 :
total = Float.parseFloat(numberOne) * Float.parseFloat(numberTwo) * rangArr[10 - Integer.parseInt(rang)];
rangStr = "打8折";
break;
case 7 :
total = Float.parseFloat(numberOne) * Float.parseFloat(numberTwo) * rangArr[10 - Integer.parseInt(rang)];
rangStr = "打7折";
break;
default:
throw new RuntimeException("不包含此种折扣");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("输入的单价或者数量不是正数或者不包含此种折扣");
System.exit(0);
}
System.out.println("总计:" + rangStr + "后 " + total);
}
}
问题来了:“这样子增加一个算法,就更改一下代码,又不利于其他算法的保密,也不符合面向对象的三大特性”。我:想起了上次的优化,使用简单工厂设计模式改进一次。
public class Program {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("单价:");
String price = sc.next();
System.out.println("数量:");
String number = sc.next();
System.out.println("打折率:");
String rang = sc.next();
// 获取实际打折率
double[] rangArr = new double[]{0,0.9f,0.8f,0.7f};
double total = 0f;
try {
CashSuper cash = CashFactory.createCash(rang);
total = cash.acceptCash(Double.parseDouble(price) * Double.parseDouble(number)) ;
} catch (Exception e) {
e.printStackTrace();
System.out.println("输入的单价或者数量不是正数或者不包含此种折扣");
System.exit(0);
}
System.out.println("总计:" + rang + "后 " + total);
}
}
abstract class CashSuper{
public abstract double acceptCash(double money);
}
// 正常收费
class CashNormal extends CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
// 打折收费
class CashRebate extends CashSuper{
private double moneyRebate = 1l;
public CashRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public double acceptCash(double money) {
return money * moneyRebate;
}
}
// 满多少返利
class CashReturn extends CashSuper{
private double moneyCondition = 0.0f;
private double moneyReturn = 0.0f;
public CashReturn(double moneyCondition, double moneyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
@Override
public double acceptCash(double money) {
double result = money;
if(money >= moneyCondition){
result = money - Math.floor(money/moneyCondition)*moneyReturn;
}
return result;
}
}
class CashFactory {
public static CashSuper createCash(String rang) {
CashSuper cash = null;
switch (rang) {
case "不打折":
cash = new CashNormal();
break;
case "打9折":
cash = new CashRebate(0.9f);
break;
case "打8折":
cash =new CashRebate(0.8f);
break;
case "满300送100":
cash = new CashReturn(300,100);
break;
default:
throw new RuntimeException("不包含此种折扣");
}
return cash;
}
}
问题来了:“上面每增加一个算法都要更改工厂模式,重复利用代码少了,有没有更好的的设计模式呢”,最终找到了策略设计模式public class Program {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("单价:");
String price = sc.next();
System.out.println("数量:");
String number = sc.next();
System.out.println("打折率:");
String rang = sc.next();
// 获取实际打折率
double[] rangArr = new double[]{0,0.9f,0.8f,0.7f};
double total = 0f;
CashContext cash = null;
try {
switch (rang) {
case "不打折":
cash = new CashContext(new CashNormal());
break;
case "打9折":
cash = new CashContext(new CashRebate(0.9f));
break;
case "打8折":
cash = new CashContext(new CashRebate(0.8f));
break;
case "满300送100":
cash = new CashContext(new CashReturn(300, 100));
break;
default:
throw new RuntimeException("不包含此种折扣");
}
total = cash.getResult(Double.parseDouble(price) * Double.parseDouble(number)) ;
} catch (Exception e) {
e.printStackTrace();
System.out.println("输入的单价或者数量不是正数或者不包含此种折扣");
System.exit(0);
}
System.out.println("总计:" + rang + "后 " + total);
}
}
abstract class CashSuper{
public abstract double acceptCash(double money);
}
// 正常收费
class CashNormal extends CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
// 打折收费
class CashRebate extends CashSuper{
private double moneyRebate = 1l;
public CashRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public double acceptCash(double money) {
return money * moneyRebate;
}
}
// 满多少返利
class CashReturn extends CashSuper{
private double moneyCondition = 0.0f;
private double moneyReturn = 0.0f;
public CashReturn(double moneyCondition, double moneyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
@Override
public double acceptCash(double money) {
double result = money;
if(money >= moneyCondition){
result = money - Math.floor(money/moneyCondition)*moneyReturn;
}
return result;
}
}
class CashContext{
private CashSuper strage;
public CashContext(CashSuper strage) {
this.strage = strage;
}
public double getResult(double money){
return strage.acceptCash(money);
}
}
仔细看了,这不是又回到了起点,还多封装了一次。重复代码更多了。又改如何改进?策略与简单工厂模式的结合
public class Program {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("单价:");
String price = sc.next();
System.out.println("数量:");
String number = sc.next();
System.out.println("打折率:");
String rang = sc.next();
// 获取实际打折率
double[] rangArr = new double[]{0,0.9f,0.8f,0.7f};
double total = 0f;
try {
CashContext cash = new CashContext(rang);
total = cash.getResult(Double.parseDouble(price) * Double.parseDouble(number)) ;
} catch (Exception e) {
e.printStackTrace();
System.out.println("输入的单价或者数量不是正数或者不包含此种折扣");
System.exit(0);
}
System.out.println("总计:" + rang + "后 " + total);
}
}
abstract class CashSuper{
public abstract double acceptCash(double money);
}
// 正常收费
class CashNormal extends CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
// 打折收费
class CashRebate extends CashSuper{
private double moneyRebate = 1l;
public CashRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public double acceptCash(double money) {
return money * moneyRebate;
}
}
// 满多少返利
class CashReturn extends CashSuper{
private double moneyCondition = 0.0f;
private double moneyReturn = 0.0f;
public CashReturn(double moneyCondition, double moneyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
@Override
public double acceptCash(double money) {
double result = money;
if(money >= moneyCondition){
result = money - Math.floor(money/moneyCondition)*moneyReturn;
}
return result;
}
}
class CashContext{
private CashSuper strage;
public CashContext(String rang) {
switch (rang) {
case "不打折":
strage = new CashNormal();
break;
case "打9折":
strage = new CashRebate(0.9f);
break;
case "打8折":
strage = new CashRebate(0.8f);
break;
case "满300送100":
strage = new CashReturn(300, 100);
break;
default:
throw new RuntimeException("不包含此种折扣");
}
}
public double getResult(double money){
return strage.acceptCash(money);
}
}
简单工厂模式和策略简单工厂模式的比较简单工厂模式
CashSuper cash = CashFactory.createCash(rang);
total = cash.acceptCash(Double.parseDouble(price) * Double.parseDouble(number)) ;
策略工厂模式CashContext cash = new CashContext(rang);
total = cash.getResult(Double.parseDouble(price) * Double.parseDouble(number)) ;
简单工厂模式调用者需要认识两个类,CashSuper和CashFactory,而策略工厂模式只要认识CashContext一个类。耦合程度更加降低最后的反思:感觉策略模式用处并不是很大,只不过封装了一次,让调用者与算法分离。降低耦合度,但是代码量增多了,阅读复杂。更多等以后理解更深刻了,再补充。