一,概念:
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化。
二,使用场景
1.针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
2.需要安全地封装多种同一类型的操作时; 3.出现同一抽象类有多个子类,而又需要使用 if-else 或者 switch-case 来选择具体子类时。
三,类图
环境(Context)角色:持有一个Strategy的引用。
抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
四,代码实例
protocol CardInterface { var money: Float{get set} var discountShopping: Float{get} var discountFood: Float{get} var discountRecreation: Float{get} func shopping(standardCost: Float) -> Bool func food(standardCost: Float) -> Bool func recreation(standardCost: Float) -> Bool}class BaseCard: CardInterface { var money: Float var discountShopping: Float var discountFood: Float var discountRecreation: Float init(money: Float, dShopping: Float, dFood: Float, dRecreation: Float) { self.money = money discountShopping = dShopping discountFood = dFood discountRecreation = dRecreation } func shopping(standardCost: Float) -> Bool { if money >= standardCost * discountShopping { money -= standardCost * discountShopping print("success: price(\(standardCost)), cost (\(standardCost * discountShopping)) in fact,left (\(money)),type shopping") return true } print("Lack of balance") return false } func food(standardCost: Float) -> Bool { if money >= standardCost * discountFood { money -= standardCost * discountFood print("success: price(\(standardCost)), cost (\(standardCost * discountFood)) in fact,left (\(money)),type food") return true } print("Lack of balance") return false } func recreation(standardCost: Float) -> Bool { if money >= standardCost * discountRecreation { money -= standardCost * discountRecreation print("success: price(\(standardCost)), cost (\(standardCost * discountRecreation)) in fact,left (\(money)),type recreation") return true } print("Lack of balance") return false }}class NomalCard: BaseCard { init(money: Float) { super.init(money: money, dShopping: 0.88, dFood: 0.9, dRecreation: 0.8) }}class VipCard: BaseCard { init(money: Float) { super.init(money: money, dShopping: 0.8, dFood: 0.8, dRecreation: 0.7) }}class SuperVipCard: BaseCard { init(money: Float) { super.init(money: money, dShopping: 0.7, dFood: 0.75, dRecreation: 0.5) }}
enum CardType: String { case Nomal case VIP case SuperVIP}class Customer { var card: CardInterface? var cardType: CardType init(cType: CardType) { cardType = cType addCard() } fileprivate func addCard() { switch cardType { case .Nomal: card = NomalCard(money: 100) case .VIP: card = VipCard(money: 100) case .SuperVIP: card = SuperVipCard(money: 100) default: break } } }
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let xiaoMing = Customer(cType: .SuperVIP) var rel = xiaoMing.card?.recreation(standardCost: 88) print(rel ?? false) rel = xiaoMing.card?.recreation(standardCost: 100) print(rel ?? false) rel = xiaoMing.card?.recreation(standardCost: 100) print(rel ?? false) }}