Migration vers le patron « Collection Pipeline » en Objective-C Mathieu Godart — @MonsieurDart Jeudi 10 septembre 2015 @ CocoaHeads
Migration vers le patron« Collection Pipeline »
en Objective-C
Mathieu Godart — @MonsieurDartJeudi 10 septembre 2015 @ CocoaHeads
L’INSPIRATION
• Martin Fowler
• Refactoring with Loops and Collection Pipelines
http://martinfowler.com/articles/refactoring-pipelines.html
• Many use cases in the article
• Here, only one case, translated into ObjC
L’IDÉE SOUS-JACENTE
• Traitement des collections d’objets :
• La boucle est la méthode la plus basique
• Mais ce n’est pas la seule : approche en « pipeline »
[Liste initiale] — fonction —> [Liste filtrée]
• Pas seulement pour la programmation fonctionnelle…
L’IDÉE SOUS-JACENTE
• ObjC (et Swift) possèdent ce qu’il faut pour ça :
• Lambdas : pour nous les blocs
• Bibliothèques : pour nous YOLOKit ou BlocksKit
BRIQUES DE BASE
• Les bibliothèques YOLOKit ou BlocksKit
• Fonctions de filtrage sur collections (NSArray, NSSet…)
• Autres fonctions de manipulation avec des blocs
• Chaînage des appels généralisé
CODE DE DÉPART
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company {
NSMutableArray *result = [NSMutableArray new];
for (MGAuthor *a in authors) {
if ([a.company isEqual:company]) {
var handle = a.twitterHandle;
if (handle != null) [result addObject:handle];
}
}
return [NSArray arrayWithArray:result];
}
CODE DE DÉPART
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company {
NSMutableArray *result = [NSMutableArray new];
for (MGAuthor *a in authors) {
if ([a.company isEqual:company]) {
var handle = a.twitterHandle;
if (handle != null) [result addObject:handle];
}
}
return [NSArray arrayWithArray:result];
}
VARIABLE TEMPORAIRE
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company{
NSMutableArray *result = [NSMutableArray new];
NSArray *loopStart = authors;
for (MGAuthor *a in loopStart) {
if ([a.company isEqual:company]) {
var handle = a.twitterHandle;
if (handle != null) [result addObject:handle];
}
}
return [NSArray arrayWithArray:result];
}
PREMIER FILTRAGE
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company{
NSMutableArray *result = [NSMutableArray new];
NSArray *loopStart = authors
.select(^(MGAuthor *a){ return [a.company isEqual:company];});
for (MGAuthor *a in loopStart) {
if ([a.company isEqualToString:company]) {
var handle = a.twitterHandle;
if (handle != null) [result addObject:handle];
}
}
return [NSArray arrayWithArray:result];
}
CE DONT ON A BESOIN
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company{
NSMutableArray *result = [NSMutableArray new];
NSArray *loopStart = authors
.select(^(MGAuthor *a){ return [a.company isEqual:company]; })
.map(^(MGAuthor *a){ return a.twitterHandle; });
for (NSString *handle in loopStart) {
var handle = a.twitterHandle;
if (handle != null) [result addObject:handle];
}
return [NSArray arrayWithArray:result];
}
CODE DE DÉPART
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company{
NSMutableArray *result = [NSMutableArray new];
NSArray *loopStart = authors
.select(^(MGAuthor *a){ return [a.company isEqual:company]; })
.map(^(MGAuthor *a){ return a.twitterHandle; })
.select(^(NSString *h){ return h != null; });
for (NSString *handle in loopStart) {
if (handle != null) [result addObject:handle];
}
return [NSArray arrayWithArray:result];
}
NETTOYAGE FINAL
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company{
NSMutableArray *result = [NSMutableArray new];
return authors
.select(^(MGAuthor *a){ return [a.company isEqual:company]; })
.map(^(MGAuthor *a){ return a.twitterHandle; })
.select(^(NSString *h){ return h != null; });
for (NSString *handle in loopStart) { [result addObject:handle];
}
return [NSArray arrayWithArray:result];
}
TA DA !- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company{
return authors
.select(^(MGAuthor *a){ return [a.company isEqual:company]; })
.map (^(MGAuthor *a){ return a.twitterHandle; })
.select(^(NSString *h){ return h != null; });
}
TA DA !- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company{
return authors
.select(^(MGAuthor *a){ return [a.company isEqual:company]; })
.map (^(MGAuthor *a){ return a.twitterHandle; })
.select(^(NSString *h){ return h != null; });
}
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company {
return authors
.select(^(MGAuthor *a){ return [a.company isEqual:company]; })
.map (^(MGAuthor *a){ return a.twitterHandle; })
.select(^(NSString *h){ return h != null; });
}
- (NSArray *)twitterHandles:(NSArray *)authors forCompany:(NSString *)company {
NSMutableArray *result = [NSMutableArray new];
for (MGAuthor *a in authors) {
if ([a.company isEqual:company]) {
var handle = a.twitterHandle;
if (handle != null) [result addObject:handle];
}
}
return [NSArray arrayWithArray:result];
}
ENCORE PLUS CONCIS EN SWIFT
-(阵列*)的⼿手:(阵列*)作者公司:(字符串*)公司 { 返回作家 。选择(^(作者* A){返回[公司是平等:公司];}) 。地图(^(作者* A){返回⼀一个句柄;}) 。选择(^(字符串* H){返回H =空;}); }
AUTRE FONCTIONS UTILES
• select, map, slice
• groupBy
• first, any, sort
• flatMap
• …
DU POUR ET DU CONTRE…
• Philosophie ou manière de penser différente
• Lourde barrière à l’entrée, mais peut s’avérer plus claire :
• À l’écriture, à la relecture et à la maintenance
• Favorise les variables immuables (immutable)
• Vous ouvre au fonctionnel… et au map-reduce
DES QUESTIONS ?DES REMARQUES ?
DES AVIS ?
MERCI LES AMIS…
Mathieu Godart — @MonsieurDartJeudi 10 septembre 2015 @ CocoaHeads