定义
工厂方法模式定义了一个创建对象的接口
,但由于子类决定
要实例化的类是哪一个.工厂方法让类把实例化推迟
到子类.这里的决定
是指在编写创建者类
时,不需要知道实际的创建产品是哪一个.
个人理解
使用工厂模式方法,我们要创建对象只需要去依赖工厂模式的接口
就好了,维护工厂模式也仅仅需要去创建对象的接口
去维护就可以了,这体现了高聚合
的优点,同时利用多态
,我们根本不需要在创建对象时知道创建出来的具体类
而仅仅需要知道抽象类(基类)
就好了,这也体现了低耦合
,可以帮助我们更好地针对接口编程
,这让代码更具有弹性,可以应对未来的扩展
.工厂模式方法是通过继承
来实现的,只不过子类可能会覆写抽象类的
方法.
demo示意图
我们可以看到下图中的NYPizzaStore
和ChicagoPizzaStore
是两个用来生产Pizza
的具体工厂,NYPizzaStore
会生产纽约风味的Pizza
,ChicagoPizzaStore
会生产芝加哥风味的Pizza
,我们在获取Pizza
的时候,不需要知道这是什么风味的Pizza
,仅仅需要知道他确确实实是一个Pizza
就好了,这样也实现了解耦
,每个风味地域的Pizza
如果做法
和打包方式
都不同的话我们可以继承
也可以利用组合
.
文件目录介绍
PizzaStore
和Pizza
是两个抽象类(基类)
,我们通过继承他们来让工厂生产出不同风味不同品种的Pizza
.NYPizzaStore
和ChicagoPizzaStore
都是PizzaStore
的子类,通过接口来创建不同的Pizza
.
调用工厂生产产品
实例化不同的工厂,传入需要的pizza
类型,就能生产出不同的pizza,同时Pizza
基类的行为如果没有改变,那么子类也可以沿用.
//创建纽约风味pizza
NYPizzaStore *nyPizzaStore = [[NYPizzaStore alloc] init];
Pizza *nyCheesePizza = [nyPizzaStore orderPizzaWithPizzaType:cheesePizza];
//Pizza *nyPepperoniPizza = [nyPizzaStore orderPizzaWithPizzaType:pepperoniPizza];
//创建芝加哥风味pizza
ChicagoPizzaStore *chicagoPizzaStore = [[ChicagoPizzaStore alloc] init];
Pizza *chicagoCheesePizza = [chicagoPizzaStore orderPizzaWithPizzaType:cheesePizza];
PizzaStore
实现文件
我们具体类(子类)
的商店其实仅仅只是对createPizzaWithPizzaType
这个创建Pizza
的行为进行覆写
,至于提供披萨的这个行为,我们使用继承
将他交给子类去执行,利用多态
生产出抽象类
的Pizza
.
#import "PizzaStore.h"
@implementation PizzaStore
- (Pizza *)createPizzaWithPizzaType:(PizzaType)pizzaType{
return [Pizza new];
}
- (Pizza *)orderPizzaWithPizzaType:(PizzaType)pizzaType{
Pizza *pizza = [self createPizzaWithPizzaType:pizzaType];
return pizza.prepare.bake.cut.box;
}
@end
NYPizzaStore
的实现文件
我们可以看到通过这个接口
我们生产出了不同的Pizza
,如果将来需要维护扩展的话,因为降低了耦合
,提高了聚合
所以改起来还是比较轻松的,ChicagoPizzaStore
的实现与这个类似.
#import "NYPizzaStore.h"
#import "NYCheesePizza.h"
#import "NYPepperoniPizza.h"
@implementation NYPizzaStore
- (Pizza *)createPizzaWithPizzaType:(PizzaType)pizzaType{
switch (pizzaType) {
case cheesePizza:
return [NYCheesePizza new];
break;
case pepperoniPizza:
return [NYPepperoniPizza new];
break;
default:
return [Pizza new];
break;
}
}
@end
Pizza
抽象类的实现
这里提供了四个Pizza
的准备步骤,如果子类Pizza
的做法与抽象类不同的话,那么直接覆写
即可,例如芝加哥芝士披萨需要切小一点,纽约芝士披萨需要切大一点,那么直接在子类覆写即可.同时这里的写法可以在工厂抽象类(PizzaStore)
使用链式调用
,但这并不是工厂模式方法
的重点.
#import "Pizza.h"
@implementation Pizza
- (instancetype)prepare{
NSLog(@"开始原味pizza准备");
return self;
}
- (instancetype)bake{
NSLog(@"开始原味pizza烘烤");
return self;
}
- (instancetype)cut{
NSLog(@"开始原味pizza切");
return self;
}
- (instancetype)box{
NSLog(@"开始原味pizza打包");
return self;
}
@end