🐻通过KFC点餐来学习建造者模式

1,983 阅读2分钟

思考

软件是什么?软件是为了解决生活中实际的问题而存在的,软件中的设计模式也恰好是限时生活中的总结,甚至如果你设计模式弄好了,不仅仅是软件更具有扩展性,而且会反哺到你的实际生活中,下面我们就用KFC举例。

KFC点餐

进到KFC中,会有很多套餐,A、B、C、D。

  • 小一点的只有一个点餐的地方,大一点的会有多个同时点餐的地方。
  • 有很多服务员,准备顾客点的各种套餐
  • 后厨,这些是套餐的真正建造者。

我们通过建造者模式来完成这个流程。

创建模式之构建者模式

  • KFCWaiter:指挥者 对象指挥具体的MealBuilder从而得到完整的套餐
  • MealBuilder:抽象建造者
  • MealBuilderA:具体建造者
  • Meal:套餐

KFC 点餐代码


class KFCBuilder{
    enum MealType{
        case mealA
        case mealB
    }
    /// 点餐
    func orderMeal(type:MealType) throws{
        var mealBuilder:MealBuilder?
        switch type {
        case .mealA:
            mealBuilder = MealBuilderA()
        case .mealB:
            mealBuilder = MealBuilderB()
        }
        guard let builder = mealBuilder else{
            throw(NSError())
        }
       let waiter = KFCWaiter()
       waiter.setMealBuilder(builder)
    }

}

Director:指挥者

class KFCWaiter{
private(set) var mb:MealBuilder?
/// 构建
func construct()->Meal?{
    mb?.buildDrink()
    mb?.buildMeal()
    return mb?.getMeal()
}
func setMealBuilder(_ mb:MealBuilder){
    self.mb = mb
}

}

套餐

class Meal{
    var drink:String?
    var food:String?
}

建造者

/// 抽象建造者
class MealBuilder{
    lazy var meal:Meal = Meal()
    func buildDrink(){
}
func buildMeal(){
    
}
func getMeal()->Meal?{
    return meal
}

} /// 具体建造者A class MealBuilderA:MealBuilder{ override func buildDrink(){ meal.drink = "A 类型喝的" } override func buildMeal(){ meal.food = "A 类型吃的" } } /// 具体建造者B class MealBuilderB:MealBuilder{ override func buildDrink(){ meal.drink = "B 类型喝的" } override func buildMeal(){ meal.food = "B 类型吃的" } }

有些餐厅会把东西组装好,直接给你送过来这时waiter和builder的角色就合并为一个了,当店铺越来越大时,人越来越多,责任细化,就会再次划分,公司也是这样。

区分

建造者模式与工厂三兄弟的区分:

  • 需要创建一个简单产品时,用工厂三兄弟
  • 需要创建一个组合产品时,用建造者模式

参考

  • https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/builder.html

本文使用 mdnice 排版