一句话概括
策略模式是一种定义一系列算法的方法,这些算法具有相同的功能,只是不同的实现。它以相同的方式(Api)调用所有算法类,减少了算法类和使用算法类的耦合。
需求
实现一个商城收银系统,可以根据单价和数量算出总价。
Code V1.0
根据需求很容易实现相关功能,计算出单个商品的总价,再累加求出总价。
class CashierSystem {
static var totalPrice: Float = 0
static func calculateTotalPrice(commodityName: String, unitPrice: Float, number: Int) {
let singleCommodityTotalPrice = unitPrice * Float(number)
totalPrice += singleCommodityTotalPrice
print("商品:\(commodityName),价格:\(unitPrice) * \(number)个 = \(singleCommodityTotalPrice)")
print("总价为:\(totalPrice)")
}
static func reset() {
totalPrice = 0
}
}
Code V2.0
商城经常会出现打折、满减活动,1.0的代码就满足不了这些需求。那么可以利用简单工厂模式来实现,属于创建型模式,由工厂类来生成不同的优惠类。
class CashierSystem {
static var totalPrice: Float = 0
static func calculateTotalPrice(commodityName: String, unitPrice: Float, number: Int, type: String) {
let cashAccept = CashFctory.creatCashAccept(type: type)
var singleCommodityTotalPrice = unitPrice * Float(number)
singleCommodityTotalPrice = cashAccept.acceptCash(money: singleCommodityTotalPrice)
totalPrice += singleCommodityTotalPrice
print("商品:\(commodityName),价格:\(unitPrice) * \(number)个 = \(singleCommodityTotalPrice)")
print("总价为:\(totalPrice)")
}
static func reset() {
totalPrice = 0
}
}
protocol CashProtocol {
func acceptCash(money: Float) -> Float
}
class CashNormal: CashProtocol {
func acceptCash(money: Float) -> Float {
return money
}
}
class CashDiscount: CashProtocol {
///折扣
let discount: Float
init(discount: Float) {
self.discount = discount
}
func acceptCash(money: Float) -> Float {
return money * discount
}
}
class CashReturn: CashProtocol {
///满减条件金额
let moneyCondition: Float
///满减金额
let moneyReturn: Float
init(moneyCondition: Float, moneyReturn: Float) {
self.moneyCondition = moneyCondition
self.moneyReturn = moneyReturn
}
func acceptCash(money: Float) -> Float {
var result = money
if money > moneyCondition {
result = floor(money / moneyCondition) * moneyReturn
}
return result
}
}
class CashFctory {
static func creatCashAccept(type: String) -> CashProtocol {
var cash: CashProtocol = CashNormal()
switch type {
case "正常收费":
cash = CashNormal()
case "打8折":
cash = CashDiscount(discount: 0.8)
case "满300返100":
cash = CashReturn(moneyCondition: 300, moneyReturn: 100)
default:
break
}
return cash
}
}
Code V3.0
下面用策略模式来实现这个需求,策略模式属于行为型模式。和简单工厂模式区别是策略模式不生成对象,是拿传进来的对象做事情,简单工厂模式是通过传进来的参数来生成对象。
class CashierSystem {
static var totalPrice: Float = 0
static func calculateTotalPrice(commodityName: String, unitPrice: Float, number: Int, type: String) {
let cashContext = CashContext(type: type)
var singleCommodityTotalPrice = unitPrice * Float(number)
singleCommodityTotalPrice = cashContext.getResult(money: singleCommodityTotalPrice)
totalPrice += singleCommodityTotalPrice
print("商品:\(commodityName),价格:\(unitPrice) * \(number)个 = \(singleCommodityTotalPrice)")
print("总价为:\(totalPrice)")
}
static func reset() {
totalPrice = 0
}
}
protocol CashProtocol {
func acceptCash(money: Float) -> Float
}
class CashNormal: CashProtocol {
func acceptCash(money: Float) -> Float {
return money
}
}
class CashDiscount: CashProtocol {
///折扣
let discount: Float
init(discount: Float) {
self.discount = discount
}
func acceptCash(money: Float) -> Float {
return money * discount
}
}
class CashReturn: CashProtocol {
///满减条件金额
let moneyCondition: Float
///满减金额
let moneyReturn: Float
init(moneyCondition: Float, moneyReturn: Float) {
self.moneyCondition = moneyCondition
self.moneyReturn = moneyReturn
}
func acceptCash(money: Float) -> Float {
var result = money
if money > moneyCondition {
result = floor(money / moneyCondition) * moneyReturn
}
return result
}
}
class CashContext {
let cash: CashProtocol
//标准策略模式不在Context内部生成对象
init(type: String) {
switch type {
case "正常收费":
self.cash = CashNormal()
case "打8折":
self.cash = CashDiscount(discount: 0.8)
case "满300返100":
self.cash = CashReturn(moneyCondition: 300, moneyReturn: 100)
default:
self.cash = CashNormal()
}
}
func getResult(money: Float) -> Float {
cash.acceptCash(money: money)
}
}