聊聊Swift中的设计模式---创建型(建造者模式)

485 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情


前言

在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。

正文

建造者模式也叫生成器模式,它用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”创建不同的对象。

例子:

我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个主食(Main coures)和一杯冷饮(Cold drink)。

主食(Main coures)可以是牛排(steak)或汉堡(Burger),它们是在餐盘中。

冷饮(Cold drink)可以是可乐(cola)或无糖可乐(Diet Coke),它们是装在瓶子中。

我们将创建一个表示食物条目(比如主食和冷饮)的 Item 接口和实现 Item 的接口的实体类,以及一个表示食物包装的 Packing 接口和实现接口的实体类。主食是放在餐盘中,冷饮装在瓶子里。

然后我们创建 Meal 类,和一个创建不同类型的 Meal 对象的 MealBuilder。

step 1 先创建食物包装的 protocol

/// 食物包装
protocol Packing {
    var pack: String {get}
}

class Box: Packing {
    var pack: String {"餐盘"}
}
class Bottle: Packing {
    var pack: String {"瓶子"}
}

step 2 创建食物具备哪些属性的 protocol


/// 食物条目
protocol Item {
    var name: String {get}
    var packing: Packing { get }
    var price: Double { get }
}

step 3 创建主食


class Main_coures: Item {
    var packing: Packing { Box() }
    var price: Double { 10 }
    var name: String {"主食"}
}

class Steak: Main_coures {
    override var price: Double { 50 }
    override var name: String {"牛排"}
}

class Burger: Main_coures {
    override var price: Double { 25 }
    override var name: String { "汉堡"}
}

step 4 创建冷饮


class ColdDrink: Item {
    var packing: Packing { Bottle() }
    var price: Double { 15 }
    var name: String { "冷饮" }
}

class Cola: ColdDrink {
    override var price: Double { 30 }
    override var name: String { "可乐" }
}

class Diet_Coke : ColdDrink {
    override var price: Double { 35 }
    override var name: String { "无糖可乐"}
}

step 5 构建套餐

/// 套餐
class Meal {
    
    var items: [Item] = []
    
    func add(item: Item) {
        items.append(item)
    }
    
    func getCost() -> Double {
        return items.reduce(0) { (total, item) -> Double in
            return total + item.price
        }
    }
    
    func showItems() {
        items.forEach { (item) in
            print("条目:(item.name), 打包:(item.packing.pack), 价格:(item.price)")
        }
    }
}

/// 创建 Meal 对象
class MealBuilder {
    func makeSteakMeal() -> Meal {
        let meal = Meal()
        meal.add(item: Steak())
        meal.add(item: Cola())
        return meal
    }
    
    func makeBurgerMeal() -> Meal {
        let meal = Meal()
        meal.add(item: Burger())
        meal.add(item: Diet_Coke())
        return meal
    }
}


let mealBuilder = MealBuilder()

print("牛排套餐")
let vegMal = mealBuilder.makeSteakMeal()
vegMal.showItems()
print("总计:(vegMal.getCost())\n")


print("汉堡套餐")
let noVegMal = mealBuilder.makeBurgerMeal()
noVegMal.showItems()
print("总计:(noVegMal.getCost())")

最后输出:

牛排套餐

条目:牛排, 打包:纸盒, 价格:50.0

条目:可乐, 打包:瓶子, 价格:35.0

总计:85.0

汉堡套餐 条目:汉堡, 打包:纸盒, 价格:25.0

条目:无糖可乐, 打包:瓶子, 价格:30.0

总计:55.0

结语

建造者模式适合有多个复杂属性的对象,就像例子中的套餐一样。

优点:对复杂对象的创建细节进行隔离,方便使用者调用,减少了bug。

缺点:代码重复,需要对每种情况进行处理,有一定的维护成本。


扩展阅读 下面还有其他模式

创建型-工厂模式

结构型-适配器模式

结构型-桥接模式

结构型-组合模式