4.Builder - QDDCoder/LZLearniOS GitHub Wiki

建造者模式

解释地址 https://www.runoob.com/design-pattern/builder-pattern.html

 建造者模式Builder Pattern使用多个简单的对象一步一步构建成一个复杂的对象这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式一个 Builder 类会一步一步构造最终的对象 Builder 类是独立于其他对象的意图将一个复杂的构建与其表示相分离使得同样的构建过程可以创建不同的表示主要解决主要解决在软件系统中有时候面临着"一个复杂对象"的创建工作其通常由各个部分的子对象用一定的算法构成由于需求的变化这个复杂对象的各个部分经常面临着剧烈的变化但是将它们组合在一起的算法却相对稳定何时使用一些基本部件不会变而其组合经常变化的时候如何解决将变与不变分离开关键代码建造者创建和提供实例导演管理建造出来的实例的依赖关系优点1建造者独立易扩展2便于控制细节风险缺点1产品必须有共同点范围有限制2如内部变化复杂会有很多的建造类使用场景1需要生成的对象具有复杂的内部结构2需要生成的对象内部属性本身相互依赖注意事项与工厂模式的区别是建造者模式更加关注与零件装配的顺序

1.创建接口

///1.创建接口
//食物条目
protocol Item{
    func name() -> String
    func packing() -> Packing
    func price() -> Float
}

//包装抽象
protocol Packing {
    func pack() -> String
}

2.Packing接口实体类,包装

//2.Packing接口实体类,包装
class Wrapper: Packing {
    func pack() -> String {
        return "Wrapper"
    }
}
class Bottle: Packing {
    func pack() -> String {
        return "Bottle"
    }
}

3.实现 Item 接口的抽象类

//3.实现 Item 接口的抽象类
//汉堡
protocol Burger:Item {

}
extension Burger{
    func packing() -> Packing {
        return Wrapper()
    }
}

//冷饮
protocol ColdDrink:Item {

}
extension ColdDrink{
    func packing() -> Packing {
        return Bottle()
    }
}

4.创建扩展了 Burger 和 ColdDrink 的实体类。

///4.创建扩展了 Burger 和 ColdDrink 的实体类。
class VegBurger:NSObject, Burger {
    func name() -> String {
        return "Veg Burger"
    }
    
    func price() -> Float {
        return 25.0
    }
}

class ChickenBurger: NSObject,Burger {
    func name() -> String {
        return "Chicken Burger"
    }
    
    func price() -> Float {
        return 50.5
    }
}

class Pepsi: ColdDrink {
    func name() -> String {
        return "Pepsi"
    }
    
    func price() -> Float {
        return 35.0
    }
}

class Coke: ColdDrink {
    func name() -> String {
        return "Coke"
    }
    
    func price() -> Float {
        return 30.0
    }
}

5.创建一个 Meal 类,带有上面定义的 Item 对象。

//5.创建一个 Meal 类,带有上面定义的 Item 对象。
class Meal: NSObject {
    var items = [Item]()
    func addItem(withItem item:Item)  {
        items.append(item)
    }
    
    func getCost() -> Float {
        var cost:Float = 0.0
        items.forEach { (item) in
            cost+=item.price()
        }
        return cost
    }
    
    func showItems()  {
        items.forEach { (item) in
            print("Item的名字:\(item.name())")
            print(",包装:\(item.packing().pack())")
            print(",价格:\(item.price())")
        }
    }
}

6.创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。

//6.创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。
class MealBuilder: NSObject {
    func prepareVegMeal() -> Meal {
        let meal = Meal()
        meal.addItem(withItem: VegBurger())
        meal.addItem(withItem: Coke())
        return meal
    }
    
    func prepareNonVegMeal() -> Meal {
        let meal = Meal()
        meal.addItem(withItem: ChickenBurger())
        meal.addItem(withItem: Pepsi())
        return meal
    }
}
  • 测试

let mealBuilder = MealBuilder()
print("-------Veg Meal-------")
let vegMeal = mealBuilder.prepareVegMeal()
vegMeal.showItems()
print("总价格是:\(vegMeal.getCost())")

let nonVegMeal = mealBuilder.prepareNonVegMeal()
print("-------Non-Veg Meal-------")
print("Non-Veg Meal")
nonVegMeal.showItems()
print("总价格:\(nonVegMeal.getCost())")
  • 测试结果

-------Veg Meal-------
Item的名字:Veg Burger
,包装:Wrapper
,价格:25.0
Item的名字:Coke
,包装:Bottle
,价格:30.0
总价格是:55.0
-------Non-Veg Meal-------
Non-Veg Meal
Item的名字:Chicken Burger
,包装:Wrapper
,价格:50.5
Item的名字:Pepsi
,包装:Bottle
,价格:35.0
总价格:85.5
⚠️ **GitHub.com Fallback** ⚠️