1、定义
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
2、简介
当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品
角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个
具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。
抽象工厂模式解决的的是多个产品等级结构问题。
3、UML结构
抽象工厂模式.jpgHeadFirst
抽象工厂-HeadFirst.jpg4、代码实现
工厂接口(协议)
//每一个协议方法就相当于一个产品,PizzaIngredientFactory是多个产品的集合
//每个协议方法的实现利用的是工厂模式
protocol PizzaIngredientFactory {
//创建面团
func createDough() -> DoughProtocol
//创建酱汁
func createSauce() -> SauceProtocol
//创建奶酪
func createCheese() -> CheeseProtocol
//创建蔬菜
func createVeggies() -> [VeggiesProtocol]
//创建意大利辣香肠
func createPepperoni() -> PepperoniProtocol
//创建蛤蜊
func createClams() -> ClamsProtocol
}
具体工厂类(NYPizzaIngredientFactory)
//NewYork原料工厂
class NYPizzaIngredientFactory: PizzaIngredientFactory {
func createDough() -> DoughProtocol { return ThickCrushDough() }
func createSauce() -> SauceProtocol { return MarinaraSauce() }
func createCheese() -> CheeseProtocol { return RegginaoCheese() }
func createVeggies() -> [VeggiesProtocol] { return [Garlic(), Onion(), Mushroom(), RedPepper()] }
func createPepperoni() -> PepperoniProtocol { return SlicedPepperoni() }
func createClams() -> ClamsProtocol { return FreshClam() }
}
Pizza协议
protocol PizzaProtocol {
var name: String { get set }
var sauce: SauceProtocol { get set }
var dough: DoughProtocol { get set }
var cheese: CheeseProtocol { get set }
var pepperoni: PepperoniProtocol { get set }
var clams: ClamsProtocol { get set }
var veggies: [VeggiesProtocol] { get set }
func prepare()
func bake()
func cut()
func box()
}
默认Pizza
class Pizza: PizzaProtocol {
var sauce: SauceProtocol = Sauce()
var dough: DoughProtocol = Dough()
var cheese: CheeseProtocol = Cheese()
var pepperoni: PepperoniProtocol = Pepperoni()
var clams: ClamsProtocol = Clams()
var veggies: [VeggiesProtocol] = []
var name: String = "Unknow Pizza"
func prepare() {
print("Preparing + \(name)")
print("Tossing dough...")
print("Adding sauce...")
print("Adding toppings...")
}
func bake() { print("Step1: Bake for 25 minutes for 350") }
func cut() { print("Step2: Cutting the pizza into diagonal slice") }
func box() { print("Step3: Place pizza in offical Pizzastore Box") }
}
Pizza店协议PizzaStoreProtocol
protocol PizzaStoreProtocol {
func createPizza(type: String) -> PizzaProtocol
}
Pizza店基类
//这里相当于Java中的抽象类
class PizzaStore: PizzaStoreProtocol {
//禁止子类重写,导致其它的操作
final func orderPizza(type: String) -> PizzaProtocol {
let pizza = createPizza(type: type)
//pizza的其它操作
pizza.prepare()
pizza.bake()
pizza.cut()
pizza.box()
return pizza
}
//swift没有抽象类,只在用协议实现,这里还得返回一个默认值
func createPizza(type: String) -> PizzaProtocol {
return Pizza()
}
}
具体Pizza店
class NYStylePizzaStore: PizzaStore {
var nyPizzaIngredientFactory = NYPizzaIngredientFactory()
override func createPizza(type: String) -> PizzaProtocol {
switch type {
case "cheese":
return NYStyleCheesePizza(nyPizzaIngredientFactory: nyPizzaIngredientFactory)
case "pepperoni":
return NYStylePepperoniPizza(nyPizzaIngredientFactory: nyPizzaIngredientFactory)
case "clam":
return NYStyleClamPizza(nyPizzaIngredientFactory: nyPizzaIngredientFactory)
case "veggie":
return NYStyleVeggiePizza(nyPizzaIngredientFactory: nyPizzaIngredientFactory)
default:
return Pizza()
}
}
}
Client实现
let newYorkPizzaStore = NYStylePizzaStore()
let newYorkpizza = newYorkPizzaStore.orderPizza(type: "cheese")
备注
- 抽象工厂使用对象组合:对象的创建被实现在工厂方法暴露的接口中
- 抽象工厂通过减少应用程序和具体类之间的依赖而松耦合
- 抽象工厂创建相关的对象家族,而不需要依赖它们的具体类
- 抽象工厂的定义的每个接口就相当于一个产品,每个产品的实现可以利用工厂模式
网友评论