举个栗子 问题描述
商场收银软件,营业员根据客户所购买的商品单价和数量,向客户收费。
简单实现 /** * 普通实现 * Created by callmeDevil on 2019/6/1. */ public class NormalTest { public static void main(String[] args) { double price = 10; double num = 5; System.out.println(String.format("单价:%s 元", price)); System.out.println(String.format("数量:%s 个", num)); System.out.println(String.format("总价:%s 元", calculateTotal(price, num))); } /** * 计算总价 * * @param price 单价 * @param num 数量 * @return */ private static double calculateTotal(double price, double num) { return price * num; } } 问题2商品搞促销,打八折,也可能打七折,甚至五折。
数组实现 /** * 普通实现2 * Created by callmeDevil on 2019/6/1. */ public class NormalTest2 { public static void main(String[] args) { double price = 10; double num = 5; String[] discounts = {"正常收费", "打八折", "打七折", "打五折"}; System.out.println(String.format("单价:%s 元", price)); System.out.println(String.format("数量:%s 个", num)); System.out.println(String.format("折扣:%s ", discounts[1])); System.out.println(String.format("总价:%s 元", calculateTotal(price, num, 1))); } /** * 计算总价 * * @param price 单价 * @param num 数量 * @param discount 折扣 * @return */ private static double calculateTotal(double price, double num, int discount) { double total = 0L; switch (discount) { case 0: total = price * num; break; case 1: total = price * num * 0.8; break; case 2: total = price * num * 0.7; break; case 3: total = price * num * 0.5; break; default: break; } return total; } } 上述方式存在问题有很多重复代码,就switch语句来说,如果计算方式比较复杂,那么这里就会显得非常冗余,必须考虑重构,抽出共性代码。而且如果需要打其他折扣,修改的地方也很多。
使用简单工厂模式面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
/** * 现金收费抽象类 * Created by callmeDevil on 2019/6/1. */ public abstract class CashSuper { /** * 收取现金 * * @param money 原价 * @return 当前价 */ public abstract double acceptCash(double money); } /** * 正常收费子类 * Created by callmeDevil on 2019/6/1. */ public class CashNormal extends CashSuper { @Override public double acceptCash(double money) { // 正常收费,原价返回 return money; } } /** * 返利收费子类 * Created by callmeDevil on 2019/6/1. */ public class CashReturn extends CashSuper{ // 返利条件 private double moneyCondition = 0; // 返利值 private double moneyReturn = 0; // 返利收费,初始化时必须输入返利条件和返利值,比如满300返100, // 则moneyCondition 为300,moneyReturn 为100 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; } } /** * 打折收费子类 * Created by callmeDevil on 2019/6/1. */ public class CashRebate extends CashSuper{ // 折扣率 private double moneyRebate = 1; public CashRebate(double moneyRebate) { // 打折收费,初始化时,必须输入折扣率,如打八折,就是0.8 this.moneyRebate = moneyRebate; } @Override public double acceptCash(double money) { return money * moneyRebate; } } /** * 现金收费工厂类 * Created by callmeDevil on 2019/6/1. */ public class CashFactory { /** * 创建现金收取工厂实例 * * @param type 收费类型 * @return */ 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; default: break; } return cs; } } /** * 现金收费测试 * Created by callmeDevil on 2019/6/1. */ public class CashTest { public static void main(String[] args) { double price = 400; double num = 3; System.out.println(String.format("单价:%s 元,数量:%s 个", price, num)); String type = "正常收费"; CashSuper cashSuper = CashFactory.createCashAccept(type); double total = cashSuper.acceptCash(price) * num; System.out.println(String.format("折扣:%s;总价:%s 元", type, total)); type = "满300减100"; total = cashSuper.acceptCash(price) * num; System.out.println(String.format("折扣:%s;总价:%s 元", type, total)); type = "打8折"; total = cashSuper.acceptCash(price) * num; System.out.println(String.format("折扣:%s;总价:%s 元", type, total)); } }