设计模式03--抽象工厂模式
0、序
- 在上一篇文章《工厂方法模式》中,我们定义了奥迪工厂AudiFactory生产出来的就是奥迪汽车和 奔驰工厂BenzFactory生产出来的就是奔驰汽车,但是随着其发展,奥迪工厂不仅仅生产一种车了,而是生产种种系列车型,比如有SUV系列产品与MPV系列产品,那么此时我们的AudiFactory就不能满足需求了,那么该怎么办呢?
- 抽象工厂模式正好能解决上面的问题,让我们一起来看看抽象工厂。
- 在之前我们先记住上面的一个词系列产品;
1、抽象工厂模式简述
- 对一组具有 - 相同主题的工厂进行封装- 以上面的汽车为例,在抽象工厂模式中,会有SUV工厂和MPV工厂,还有一个大的抽象工厂,里面涵盖了SUV工厂和MPV工厂所有能做的事情。 
- 上面所说的SUV工厂、MPV工厂其实都是可以生产一系列产品的(SUV汽车或者MPV汽车),也就是 - 产品族的概念。而在工厂方法模式中,其工厂生产出来的产品是属于同一个- 产品等级(比如:不同厂商生产的汽车-奥迪汽车和奔驰汽车)。
 
 
2、抽象工厂模式角色划分
- 抽象工厂 - 抽象类,内部提供了所有工厂的接口
 
- 具体工厂 - 具体工厂:可生产所有的系列产品(产品族);
 
- 具体工厂:可生产所有的系列产品(
- 产品系列A - 抽象产品A:内部提供了A系列产品的共有功能;
- 具体产品A:A系列具体的单个产品;
- 注:当然,还有A系列的其他的产品,它们属于同一个产品等级;
 
- 产品系列B - 抽象产品B:内部提供了B系列产品的共有功能;
- 具体产品B:B系列具体的单个产品;
- 注:当然,还有B系列的其他的产品,它们属于同一个产品等级;
 
3、抽象工厂模式UML类图
4、抽象工厂模式示意代码
- 抽象工厂: - YCarAbsFactory- 内部提供了所有工厂的接口1 
 2
 3
 4@protocol YCarAbsFactory <NSObject> 
 + (id<YSuvCar>)creatSuvCar; // 创建SUV系列的车
 + (id<YMpvCar>)creatMpvCar; // 创建MPV系列的车
 @end
 
- 内部提供了所有工厂的接口
- 具体工厂 - 具体工厂1:YAudiCarFactory:可生产所有的系列产品(产品族);1 
 2
 3
 4
 5
 6
 7
 8@implementation YAudiCarFactory 
 + (id<YSuvCar>)creatSuvCar {
 return [[YAudiSuvCar alloc] init]; // 创建具体的奥迪SUV
 }
 + (id<YMpvCar>)creatMpvCar {
 return [[YAudiMpvCar alloc] init]; // 创建具体的奥迪MPV
 }
 @end
- 具体工厂2:YBenzCarFactory:可生产所有的系列产品(产品族);
 - 1 
 2
 3
 4
 5
 6
 7
 8- @implementation YBenzCarFactory 
 + (id<YSuvCar>)creatSuvCar {
 return [[YBenzSuvCar alloc] init]; // 创建具体的奔驰SUV
 }
 + (id<YMpvCar>)creatMpvCar {
 return [[YBenzMpvCar alloc] init]; // 创建具体的奔驰MPV
 }
 @end- 补充:可能还会有一个具体工厂3,比如:宝马工厂,宝马工厂同样能生产SUV的车和MPV的车,并且根据需要在内部实现创建具体的产品逻辑;
 
- 具体工厂1:
- 产品系列A - 抽象产品:YSuvCar:内部提供了A系列产品的共有功能;1 
 2
 3@protocol YSuvCar <NSObject> 
 - (void)suvRun;
 @end
- 具体产品a1:YAudiSuvCar1 
 2
 3
 4
 5@implementation YAudiSuvCar 
 - (void)suvRun {
 NSLog(@"奥迪SUV跑起来了");
 }
 @end
- 具体产品a2:YBenzSuvCar1 
 2
 3
 4
 5@implementation YBenzSuvCar 
 - (void)suvRun {
 NSLog(@"奔驰SUV跑起来了");
 }
 @end
- 注:上面的a1、a2属于同一个**产品族(SUV车系)的不同产品等级**(奥迪、奔驰);
 
- 抽象产品:
- 产品系列B - 抽象产品B: - YMpvCar:内部提供了B系列产品的共有功能;- 1 
 2
 3- @protocol YMpvCar <NSObject> 
 - (void)mpvRun;
 @end
- 具体产品b1: - YAudiMpvCar- 1 
 2
 3
 4
 5- @implementation YAudiMpvCar 
 - (void)mpvRun {
 NSLog(@"奥迪MPV跑起来了");
 }
 @end
- 具体产品b2: - YBenzMpvCar- 1 
 2
 3
 4
 5- @implementation YBenzMpvCar 
 - (void)mpvRun {
 NSLog(@"奔驰MPV跑起来了");
 }
 @end
- 注:上面的b1、b2属于同一个** - 产品族(MPV车系)的不同- 产品等级**(奥迪、奔驰);
 
- Client使用 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19- // 奥迪SUV 
 id<YSuvCar> audiSuv = [YAudiCarFactory creatSuvCar];
 [audiSuv suvRun];
 // 奥迪MPV
 id<YMpvCar> audiMpv = [YAudiCarFactory creatMpvCar];
 [audiMpv mpvRun];
 
 // 奔驰SUV
 id<YSuvCar> benzSuv = [YBenzCarFactory creatSuvCar];
 [benzSuv suvRun];
 // 奔驰MPV
 id<YMpvCar> benzMpv = [YBenzCarFactory creatMpvCar];
 [benzMpv mpvRun];
 // 运行结果:
 奥迪SUV跑起来了
 奥迪MPV跑起来了
 奔驰SUV跑起来了
 奔驰MPV跑起来了
5、抽象工厂模式与工厂方法模式对比
| 工厂方法模式 | 抽象工厂模式 | 
|---|---|
| 工厂类一般只有一个方法,创建一种产品 | 工厂类有多个方法,创建多系列产品 | 
| 只涉及产品等级 | 涉及产品等级与产品族 | 
| 增加子类即可添加新产品 | 必须修改父类接口才能添加新产品 | 
