设计模式系列文章
《iOS设计模式(1)简单工厂模式》
《iOS设计模式(2)工厂模式》
《iOS设计模式(3)适配器模式》
《iOS设计模式(4)抽象工厂模式》
《iOS设计模式(5)策略模式》
《iOS设计模式(6)模板模式》
前面在文章中我提到了自己新车上牌照,连引出了系列工厂模式,有兴趣的朋友可以往前翻。但是,我忘了跟大家讲讲我买车的经过了,所以今天补上。说到我买车的过程就不得不说说今天的主角建造者模式。我们还是先看看百度百科给它的定义吧:
1概念描述
设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。百度百科
很喜欢这句话,非常的简洁而又精准,短短几十个字就概括了建造者模式的定义。
2.实用场景
1 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2 当构造过程必须允许被构造的对象有不同表示时。百度百科
3.角色
1 Builder:为创建一个产品对象的各个部件指定抽象接口。
2 ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。
3 Director:构造一个使用Builder接口的对象。
4 Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。百度百科
什么意思呢?别着急,先听听我买车的经过吧,一会就自然而然的明白了上面枯燥的理论概念了。
话说自从小猿自从升级为boss有了小小猿后,越发的感觉没车实在是不方便。于是,决定购置人生中的第一辆车。某天,小猿头脑一热带着老婆孩子直奔别克4S店(不是打广告,小猿真的买的是别克)。到了4S店一辆辆崭新的汽车,看得眼花缭乱,随手拿了一个宣传页,上面是汽车的各种参数。
那问题来了:现场的汽车是真是的汽车,各种配置和零件统统齐全,但是宣传册上的汽车配置是这辆车全部的参数吗?对了,肯定不是了。汽车的生产、制造是非常复杂的,而宣传页只是向人们展示出客户最关心的部分参数。
现在可以理解上面的理论概念了吧?下面我们说一下建造者的角色
说世界上有个通用公司,他生产了很多叫别克品牌的汽车LHBuickCar,这个类的参数实在是太复杂了,专业人士都不一定能说的全他里面的配置参数。。。
- 1.Builder:为创建一个产品对象的各个部件指定抽象接口(LHBuickBuilder),宣传册的固定格式。
- 2.ConcreteBuilder:具体产品的建造类(LHBuickExcelleGTBuilder、LHBuickVeranoBuilder、LHBuickRegalBuilder、LHBuickLacrosseBuilder),可以理解成具体某辆车的宣传册。
- 3.Director:构造一个使用Builder接口的对象,这里指的就是4S店的销售。
- Product:表示被构造的复杂对象(我想了解的哪个配置的汽车)。
4.代码实现
我来到了别克4S店,目的就是想买一辆别克汽车Product(LHBuickCar)。
#import <Foundation/Foundation.h>
@interface LHBuickCar : NSObject
@property (nonatomic, copy)NSString *name;// 名字
@property (nonatomic, copy)NSString *level;// 级别
@property (nonatomic, copy)NSString *price;// 价格
// 还有等等好多好多参数,但是我只关心这些
@end
@implementation LHBuickCar
// 让他做跟自我介绍
- (NSString *)description{
return [NSString stringWithFormat:@"我是一辆:%@ %@车 价格:%@",self.name,self.level,self.price];
}
@end
刚进门,迎面就过来一个销售美女,她就是今天的主角Director(LHDirector4S),根据我的要求给我介绍不同的车辆。
#import <Foundation/Foundation.h>
#import "LHBuickCar.h"
#import "LHBuickBuilder.h"
@interface LHDirector4S : NSObject
// 根据客户的要求介绍一辆别克车
+ (LHBuickCar *)creatBuickCar:(LHBuickBuilder *)builder;
@end
#import "LHDirector4S.h"
@implementation LHDirector4S
+ (LHBuickCar *)creatBuickCar:(LHBuickBuilder *)builder{
LHBuickCar *buickCar = [builder makeBuickCar];
return buickCar;
}
@end
不怕大家笑话,可是我对车不懂啊,我也不知道我要买哪一款车,所以销售也不知道重点给我介绍哪一款。于是,销售给了我4款车的宣传册(LHBuickExcelleGTBuilder、LHBuickVeranoBuilder、LHBuickRegalBuilder、LHBuickLacrosseBuilder)。我大概看了一下,他的格式是一样的,无非就是具体的参数不一样。那我们可以先定义出这个宣传册的固定格式:LHBuickBuilder。
#import <Foundation/Foundation.h>
#import "LHBuickCar.h"
@interface LHBuickBuilder : NSObject
@property (nonatomic, copy)NSString *name;// 名字
@property (nonatomic, copy)NSString *level;// 级别
@property (nonatomic, copy)NSString *price;// 价格
- (LHBuickCar *)makeBuickCar;
@end
#import "LHBuickBuilder.h"
@implementation LHBuickBuilder
- (LHBuickCar *)makeBuickCar{
LHBuickCar *buickCar = [[LHBuickCar alloc] init];
buickCar.name = self.name;
buickCar.level = self.level;
buickCar.price = self.price;
return buickCar;
}
@end
下面是每款车宣传册的具体配置
别克英朗
#import "LHBuickBuilder.h"
@interface LHBuickExcelleGTBuilder : LHBuickBuilder
@end
#import "LHBuickExcelleGTBuilder.h"
@implementation LHBuickExcelleGTBuilder
- (instancetype)init
{
self = [super init];
if (self) {
self.name = @"别克英朗";
self.level = @"A级车";
self.price = @"10.99-15.99万";
}
return self;
}
@end
别克威朗
#import "LHBuickBuilder.h"
@interface LHBuickVeranoBuilder : LHBuickBuilder
@end
#import "LHBuickVeranoBuilder.h"
@implementation LHBuickVeranoBuilder
- (instancetype)init
{
self = [super init];
if (self) {
self.name = @"别克威朗";
self.level = @"A+级车";
self.price = @"13.59-19.99万";
}
return self;
}
@end
别克君威
#import "LHBuickBuilder.h"
@interface LHBuickRegalBuilder : LHBuickBuilder
@end
#import "LHBuickRegalBuilder.h"
@implementation LHBuickRegalBuilder
- (instancetype)init
{
self = [super init];
if (self) {
self.name = @"别克君威";
self.level = @"B级车";
self.price = @"17.89-27.99万";
}
return self;
}
@end
别克君越
#import "LHBuickBuilder.h"
@interface LHBuickLacrosseBuilder : LHBuickBuilder
@end
#import "LHBuickLacrosseBuilder.h"
@implementation LHBuickLacrosseBuilder
- (instancetype)init
{
self = [super init];
if (self) {
self.name = @"别克君越";
self.level = @"C级车";
self.price = @"22.58-33.98万";
}
return self;
}
@end
看了几眼就蒙了,不懂啊,我就跟美女说:我想用尽量少的钱买尽量舒适高档的车,预算15万左右(估计美女在心里嘲笑我:又来一个穷色(sai))。
于是美女二话不说,拿起别克威朗宣传册就开始滔滔不绝的给我讲解起来,什么性价比最好的A+级车(我哪里知道什么叫A/B/C级车啊)、价格符合预期、外形漂亮、内饰高档。。。
5分钟后,我得到了她所说的信息:(下面看客户端的调用)
#import "ViewController.h"
#import "LHBuickVeranoBuilder.h"
#import "LHDirector4S.h"
#import "LHBuickCar.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
LHBuickBuilder *builder = [[LHBuickVeranoBuilder alloc] init];
LHBuickCar *buickCar = [LHDirector4S creatBuickCar:builder];
NSLog(@"%@",buickCar.description);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
输出结果:
32335AAE-4AFC-4C15-BEF1-448BE0F04112.png
5.题外话
其实,我们去4S店,非得走这样的流程吗?不用,如果所有的信息我都在网上了解过了,我知道我要哪款车,也不需要销售美女给我介绍,我就只是去现场看看实车,那就没必要看那么多宣传册,也没必要听美女滔滔不绝的说话了。
在具体建造者只有一个的情况下,如果抽象建造者角色已经被省略掉,那么还可以省略掉指导者角色,让Builder自己扮演指导者和建造者双重角色。百度百科
所以美女你歇着吧,我自己直接看威朗的宣传册就可以了。
不知道我说明白了吗?不明白的留言或QQ(616867091)
网友评论
2 当构造过程必须允许被构造的对象有不同表示时。
这两句能解释下吗?我试着理解了下,不确定是否理解到位。感觉理解不充分的话,用起来会比较机械。。