Comment Transformer vos boucles Objective-C en “collection pipelines” en utilisant le framework BlocksKit (ou Swift), par Mathieu Godart (votre serviteur). Cette présentation s’inspire de la série d’articles publiée par Martin Fowler, Refactoring with Loops and Collection Pipelines (http://martinfowler.com/articles/refactoring-pipelines.html).
1. Migration vers le patron
« Collection Pipeline »
en Objective-C
Mathieu Godart — @MonsieurDart
Jeudi 10 septembre 2015 @ CocoaHeads
2. 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
3. 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…
4. 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
5. 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é
6. 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];
}
7. 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];
}
8. 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];
}
9. 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];
}
10. 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];
}
18. 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