【设计模式】04 - 策略模式 (Strategy Patter

2019-05-06  本文已影响0人  Lebron_James

这篇文章是我阅读raywenderlich.comDesign Patterns by Tutorials的总结,文中的代码是我阅读书本之后根据自己的想法修改的。如果想看原版书籍,请点击链接购买。


策略模式定义了多个在运行中可以切换的对象。这个模式由三部分组成:

策略模式UML图

什么时候使用

当我们有多个不同的可切换的行为时,可以使用策略模式。

策略模式有点类似于代理模式,这两种模式都依赖于某个协议;在代理模式中,遵循了协议的对象就可以成为代理;在策略模式中,遵循了协议的就可以成一个策略。

但不同的是,策略模式有多个策略组成的集合,可以在运行时根据需要切换。

简单Demo

假设我们要做一个可以查看餐饮商家在不同平台的评分情况,例如大众点评、口碑等,我们就可以使用策略模式。

代码如下:

import UIKit

protocol FoodMerchantRatingStrategy {
    var ratingServiceName: String { get }
    func fetchRatingforMerchant(named name: String,
                            success: (_ rating: String, _ review: String) -> Void)
}

class DianPingClient: FoodMerchantRatingStrategy {
    let ratingServiceName = "大众点评"
    func fetchRatingforMerchant(named name: String,
                            success: (String, String) -> Void) {
        let rating = "⭐️⭐️⭐️⭐️"
        let review = "还不错!!!"
        success(rating, review)
    }
}

class KouBeiClient: FoodMerchantRatingStrategy {
    let ratingServiceName = "口碑"
    func fetchRatingforMerchant(named name: String,
                            success: (String, String) -> Void) {
        let rating = "⭐️⭐️⭐️⭐️⭐️"
        let review = "非常好!"
        success(rating, review)
    }
}

class FoodMerchantRatingViewController: UIViewController {

    private let foodMerchantRatingClient: FoodMerchantRatingStrategy

    // MARK: - Initializers

    init(withRaingClient client: FoodMerchantRatingStrategy) {
        foodMerchantRatingClient = client
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Views

    @IBOutlet private var merchantNameTextField: UITextField!
    @IBOutlet private var ratingServiceNameLabel: UILabel!
    @IBOutlet private var ratingLabel: UILabel!
    @IBOutlet private var reviewLabel: UILabel!

    // MARK: - View Lifecycles

    override func viewDidLoad() {
        super.viewDidLoad()
        ratingServiceNameLabel.text = foodMerchantRatingClient.ratingServiceName
    }

    // MARK: - Actions

    @IBAction private func searchButtonTapped() {
        guard let merchantName = merchantNameTextField.text,
            !merchantName.isEmpty  else {
                return
        }
        foodMerchantRatingClient
            .fetchRatingforMerchant(named: merchantName,
                                success: { [weak self] (rating, review) in
                                    self?.ratingLabel.text = rating
                                    self?.reviewLabel.text = review
            })
    }
}

总结

如果有多个不同的行为,可以使用策略模式。但如果只有一个行为,并且不会再发生改变,直接把逻辑写到View Controller里面就好了。

欢迎加入我管理的Swift开发群:536353151

下一篇文章:【设计模式】05 - 单例模式

上一篇 下一篇

猜你喜欢

热点阅读