251003 thinking factory method& abstract factory
1. 工厂方法
以点菜为例。
1 | type dish interface{ Cook() } |
若不用工厂方法,则客户端直连产品,新增产品要改分支,不符合开闭原则。
1 | func orderDish(typeName string) dish { |
而使用工厂方法后,客户端只依赖抽象工厂,新增产品时只需要新增具体工厂即可,符合开闭原则。
即,把“怎么做菜”的细节从用户(软件开发程序员)手里拿走,交给各自的工厂(中间件)。
1 | type Factory interface { |
这样的话,新增产品时只需要新增产品 + 工厂即可,无需修改用户程序。符合开闭原则。
1 | type sushi struct{} |
客户端只依赖抽象工厂,只需调用工厂方法即可,不用修改。
类图:
classDiagram
class Dish {
+Cook()
}
class Pizza {
+Cook()
}
class Burger {
+Cook()
}
Dish <|.. Pizza
Dish <|.. Burger
class Factory {
+Create() Dish
}
class PizzaFactory
class BurgerFactory
Factory <|.. PizzaFactory
Factory <|.. BurgerFactory
Factory ..> Dish : Create()
2. 抽象工厂
场景:套餐由两个相关组件组成(菜 Dish + 饮料 Drink),同一风格的组件应该一起创建并保持搭配一致(意式:Pizza+Coffee,美式:Burger+Cola)。
1 | // 产品族接口 |
抽象工厂提供“同时创建多个相关产品”的统一接口,客户端只选择工厂(风格),不再传字符串。
中间件:工厂方法的“实现”,负责创建具体产品。
1 | // 抽象工厂:一次创建同一风格的多个相关产品 |
用户只需要依赖抽象工厂,无需知道具体产品。
1 | func orderSet(f kitchenFactory) (dish, drink) { |
类图:
classDiagram
class dish {
+Cook()
}
class drink {
+Serve()
}
class pizza {
+Cook()
}
class burger {
+Cook()
}
class coffee {
+Serve()
}
class cola {
+Serve()
}
dish <|.. pizza
dish <|.. burger
drink <|.. coffee
drink <|.. cola
class kitchenFactory {
+CreateDish() dish
+CreateDrink() drink
}
class italianFactory
class americanFactory
kitchenFactory <|.. italianFactory
kitchenFactory <|.. americanFactory
italianFactory ..> dish : CreateDish()
italianFactory ..> drink : CreateDrink()
americanFactory ..> dish : CreateDish()
americanFactory ..> drink : CreateDrink()
- 客户端不写 switch、不传 “pizza/burger” 字符串;只选风格工厂(Italian/American)。
- 搭配关系由工厂保证,防止“风格混搭”造成业务不一致。
- 扩展新风格时,仅新增“具体工厂 + 其产品”,保持开闭原则。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Elian's blog page!