背景
DSL(Domain Specific Language),用于解决特定领域的语言. 链式调用就是类似RxJava那样使用连续的.方法来调用, 这样可使得调用逻辑清晰, 减少代码量.
比如Masonry的语法就是:
// Masonry
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top).with.offset(padding.top);
make.left.equalTo(superview.mas_left).with.offset(padding.left);
make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];
问题
页面需要显示订单头行+订单统计行+普通订单行.
基本思路:
- 我们最终需要得到
list_all<OrderItemModel>的列表 - 先往
list_all中添加4行头item. - 将通过服务器api获取的产品列表
list_a元素转成统一对象OrderItemModel生成list_b<OrderItemModel> list_b排序(先本品, 再赠品)- 在产品列表
list_b中添加订单统计头行 - 将
list_bappend到list_all后面形成最终展示数据源
期望的调用方式:
resultList = LoadPreList(list_a) // 3.接受网络获取的数据列表list_a
.convertToOrderItemModel(rulesBlock) // 3.将list_a转成list_a, 需外部自己实现
.sortAndAddTotalHeader() // 4. 5.将list按先本品, 后赠品的顺序排序, 再添加统计头信息;其实这一步对外可以省略, 因为无需传参
.appendTo(list_all); // 6.将完成后的list追加到只包含订单头行的list_all后面
实现
1. 初始化OrderUtil
LoadPreList接收一个NSMutableArray类型的参数, 并直接返回
OrderListUtils.h
#import
@class OrderListUtils;
OrderListUtils *LoadPreList(NSMutableArray *list_a);
@interface OrderListUtils : NSObject
@property NSMutableArray *preList;
@end
OrderListUtils.m
@implementation OrderListUtils
OrderListUtils *LoadPreList(NSMutableArray *list_a) {
OrderListUtils *orderListUtils = [[OrderListUtils alloc] init];
orderListUtils.preList = list_a;
return orderListUtils;
}
@end
使用c的方式定义方法, 可以直接用LoadPreList(list_a)的方式调用.
2. 实现任意对象转换到OrderItemModel
只要让外部实现id --> OrderItemModel即可.
要实现.调用方法, 并且使用()传参, 需使用block的方式实现.
LoadPreList(list_a)返回一个OrderListUtils对象, 所以我们在OrderListUtils里面定义一个名为convertToOrderItemModel的方法,这个方法返回一个ConvertOrderItemModel的block
OrderListUtils.h
typedef id(^ruleBlock)(id item);
typedef OrderListUtils *(^ConvertOrderItemModelBlock)(ruleBlock block);
@interface OrderListUtils : NSObject
// 将数据list里的item转成OrderItemModel的格式
- (ConvertOrderItemModelBlock)convertToOrderItemModel;
@end
OrderListUtils.m
// 将数据list里的item转成OrderItemModel的格式
- (ConvertOrderItemModelBlock)convertToOrderItemModel {
ConvertOrderItemModelBlock convertOrderItemModel = ^OrderListUtils *(ruleBlock block) {
NSMutableArray *items = @[].mutableCopy;
for (id item in self.preList) {
[items addObject:block(item)];
}
self.preList = items; //将preList指向转换好的列表
return self;
};
return convertOrderItemModel;
}
我们看这里的方法申明:
- (ConvertOrderItemModelBlock)convertToOrderItemModel;
这里方法名convertToOrderItemModel 等价于 返回值blockConvertOrderItemModelBlock. 我们可以称返回值blockConvertOrderItemModelBlock为代替block
方法实现里面套用外部传入的blockruleBlock将self.preList的每个元素都转换成OrderItemModel的类型
3. 对OrderItemModel类型的列表进行排序 并 添加统计行
由于这一步外部无需传入参数, 并且这一步是整个流程的必备步骤, 所以可以将这一步的操作放入步骤4里, 从而简化调用代码.
4. 组装最终list
本步骤接受一个只包含4个订单头信息的列表, 并将上一步所得的列表append到这个列表后面
定义出这个代替block:
typedef NSMutableArray *(^appendToBlock)(NSMutableArray *headerList);
- (appendToBlock)appendTo;
实现
- (appendToBlock)appendTo {
appendToBlock block = ^NSMutableArray *(NSMutableArray *headerList) {
int beginIndex = [headerList count] - 1;
return [self convertToOrderMainList:headerList headerListOrderItemBeginIndex:beginIndex preList:self.preList];
};
return block;
}
完整代码
OrderItemUtils.h
@class OrderListUtils;
@class OrderItemModel;
typedef id(^ruleBlock)(id item);
typedef OrderListUtils *(^ConvertOrderItemModelBlock)(ruleBlock block);
typedef NSMutableArray *(^appendToBlock)(NSMutableArray *headerList);
OrderListUtils *LoadPreList(NSMutableArray *list_a);
@interface OrderListUtils : NSObject
@property NSMutableArray *preList;
// 将数据list里的item转成OrderItemModel的格式
- (ConvertOrderItemModelBlock)convertToOrderItemModel;
// 将网络列表 排序, 添加统计行, 并添加到只包含订单头信息的列表中
- (appendToBlock)appendTo;
@end
OrderItemUtils.m
@implementation OrderListUtils
OrderListUtils *LoadPreList(NSMutableArray *list_a) {
OrderListUtils *orderListUtils = [[OrderListUtils alloc] init];
orderListUtils.preList = list_a;
return orderListUtils;
}
// 将数据list里的item转成OrderItemModel的格式
- (ConvertOrderItemModelBlock)convertToOrderItemModel {
ConvertOrderItemModelBlock convertOrderItemModel = ^OrderListUtils *(ruleBlock block) {
NSMutableArray *items = @[].mutableCopy;
for (id item in self.preList) {
[items addObject:block(item)];
}
self.preList = items; //将preList指向转换好的列表
return self;
};
return convertOrderItemModel;
}
- (appendToBlock)appendTo {
appendToBlock block = ^NSMutableArray *(NSMutableArray *headerList) {
int beginIndex = [headerList count] - 1;
return [self convertToOrderMainList:headerList headerListOrderItemBeginIndex:beginIndex preList:self.preList];
};
return block;
}
// 将OrderItemModel格式的list排序 并添加统计头
// beginIndex 为订单行项目开始的index
- (NSMutableArray *)convertToOrderMainList:(NSMutableArray *)headerList headerListOrderItemBeginIndex:(int)beginIndex preList:(NSMutableArray *)preList {
// pass
}
@end
