Cream Code with 
Objective-C 
Javier Aznar de los Ríos 
@JaviAznar1 
Enrique Fau de Casa Juana 
@kikefau
¿Qué es el Cream Code?
/¿qué es cream code? 
Algunas claves 
● Entendible 
● Extensible 
● Mantenible 
● Actitud 
● Refactorizar como parte del desarrollo 
● Programas pequeños
¿Qué NO es el Cream Code?
/¿qué no es cream code? 
Spaghetti Code 
● Estructura compleja 
● Difícil de entender 
● Difícil de testear
/¿qué no es cream code? 
Código duplicado 
● Propenso a errores 
● Difícil de mantener 
● Oculta el propósito 
del código
/¿qué no es cream code? 
Código complejo 
● Difícil de entender 
● Difícil de mantener 
● Propenso a errores
/¿qué no es cream code? 
Métodos con responsabilidad 
múltiple 
● Difícil de mantener 
● Difícil de entender 
● Código muy acoplado 
● Difícil de testear
/¿qué no es cream code? 
Sin tests 
● Código no probado 
● Errores difíciles de 
localizar 
● Producto final “no 
deseado”
Resumiendo...
/si es cream code 
Código de calidad 
● Modularizado, Extensible 
● DRY (Don’t repeat yourself) 
● KISS (Keep It Simple, Stupid) 
● Con tests 
● S.O.L.I.D.
/si es cream code 
S.O.L.I.D. (buenas prácticas) 
● Responsabilidad única 
● Abierto a extensiones, cerrado a modificaciones 
● Clases derivadas no modifican comportamiento 
de su clase base 
● Varias interfaces pequeñas es mejor que sólo 
una grande 
● Uso de abstracciones 
Robert C. Martin
¿Cómo conseguir el cream 
code? 
Enrique Fau de Casa Juana 
@kikefau
View Controllers
View Potingue Controller vergon/zVoiseow… cajón C ontroller 
desastre 
● Difícil de entender 
● Difícil encontrar código 
● Difícil de modificar / extender 
● Difícil de mantener 
● Imposible de testear 
● Conflictos
/View Controller/Responsabilidades 
Necesita saber lo que está pasando 
View Controller 
Eventos servidor 
Interacción de usuario 
Feedback de usuario 
Modifica el modelo 
Cambios del modelo Peticiones al servidor 
Sabe qué hacer en cada momento
/Crema de la buena 
Necesitamos crema de la buena 
● Adelgazar nuestros View Controllers 
● Inyección de dependencias 
● Testing (Unit testing, UI...) 
● Patrones de diseño 
● Libros y enlaces de interés
Necesitamos crema de la buena
/View Controllers a dieta 
Necesitamos crema de la buena 
● View & View Controller 
● MVC 
● Model View View Model 
● Lógica de dominio 
● Data Sources 
● Lógica de Servicios 
● View Controller Containment
● El controlador maneja una 
vista 
● Sabe qué mostrar, no 
cómo mostrarlo 
● La vista implementa los 
detalles de presentación 
(jerarquía, animaciones...) 
View Controller 
View 
eventos de 
usuario 
feedback 
/View & View Controller
/MVC 
KVO interaction 
View Controller 
user 
Model View conoce tiene
/MVVM 
View View Controller 
View Model 
NSDateFormatter 
NSStringWithFormat 
... 
Model 
tiene 
tiene actualiza 
actualiza
/Lógica del dominio 
@implementation PropertyViewController 
- (void)loadPropertyPictures 
{ 
self.pictures = [self.property getPictures]; 
} 
@end 
@implementation Property (Extension) 
- (NSArray *)getPictures 
{ 
NSString *strPredicate = @"type == %@"; 
NSPredicate *pred = [NSPredicate predicateWithFormat:formatString, @" 
picture"]; 
return [[self.multimedias filteredSetUsingPredicate:pred] allObjects]; 
} 
@end 
View Controller 
getPictures 
Property 
Property + 
Extension
/Data source 
@implementation DataSource 
- (NSInteger)tableView:(UITableView *)tableView 
numberOfRowsInSection:(NSInteger)section 
{ 
return [self.items count]; 
} 
- (UITableViewCell *)tableView:(UITableView *)tableView 
cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
id cell = [tableView dequeueReusableCellWithIdentifier… 
forIndexPath:indexPath]; 
self.configureCellBlock(cell, [self itemAtIndexPath:indexPath]); 
return cell; 
} 
- (NSObject *)itemAtIndexPath:(NSIndexPath *)indexPath 
{ 
return self.items[indexPath.row]; 
} 
Table View 
Controller 
Table View 
Data Source
/Web Service 
● El VC no debe contener 
lógica de Web Services 
● El controlador no sabe de 
dónde salen los objetos 
● La obtención de objetos 
debe ser asíncrona 
● Se comunicará a través de 
delegados, notificaciones o 
bloques 
View Controller 
getObjects 
Service
/Controller Containment
View Controller Containment 
● Disponible a partir de iOS 5 
● [VC1.view addSubView:VC2.view] ??? 
● viewWillAppear, rotaciones… 
● Nuevos métodos 
● addChildViewController 
● didMoveToParentViewController 
● removeFromParentViewController
/Controller Containment 
● El padre define las vistas 
contenedoras 
● Los hijos son notificados 
cuando son añadidos 
● El padre realiza las 
transiciones 
● Los hijos deben tener 
sentido por sí mismos 
View Controller 
Container 
View Controller 
(Child) 
View Controller 
(Child)
/Controller Containment 
View Controller 
Container 
View Controller 
View Controller 
ViVeiwew C Conotnrotrlolellrer 
Child Delegate (Child) 
crea 
implementa 
define
Inyección de dependencias
Inyección de dependencias 
● Dependencia: A depende de B, 
cuando A necesita de B para hacer su 
trabajo 
● Inyección: El objeto que usa A le 
dice a A quien es B
/Inyección de dependencias 
Necesitamos crema de la buena 
● Inyección por constructor 
● Inyección de propiedades 
● Inyección en métodos 
● Extraer método y sobreescribir la 
llamada
@implementation Example 
- (NSString *)getFormattedDate:(NSDate *)date 
{ 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"es"]]; 
dateFormatter.dateFormat = @"dd MMM"; 
return [dateFormatter stringFromDate:date]; 
} 
@end 
/Ejemplo
/Inyección por constructor 
@interface Example () 
@property(nonatomic, strong) NSDateFormatter *dateFormatter; 
@end 
@implementation Example 
- (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter 
{ 
self = [super init]; 
if (self) { 
_dateFormatter = dateFormatter; 
} 
return self; 
} 
- (NSString *)getFormattedDate:(NSDate *)date 
{ 
return [self.dateFormatter stringFromDate:date]; 
} 
@end
/Inyección de propiedades 
@interface Example () 
@property(nonatomic, strong) NSDateFormatter *dateFormatter; 
@end 
@implementation Example 
- (NSDateFormatter *)dateFormatter 
{ 
if (!_dateFormatter) { 
_dateFormatter = [[NSDateFormatter alloc] init]; 
[_dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"es"]]; 
_dateFormatter.dateFormat = @"dd MMM"; 
} 
return _dateFormatter; 
} 
- (NSString *)getFormattedDate:(NSDate *)date 
{ 
return [self.dateFormatter stringFromDate:date]; 
} 
@end
/Inyección en métodos 
@implementation Example 
- (NSString *)getFormattedDate:(NSDate *)date 
withDateFormatter:(NSDateFormatter *)dateFormatter 
{ 
return [dateFormatter stringFromDate:date]; 
} 
@end
/Extraer y sobreescribir 
@interface Example () 
@property(nonatomic, strong) NSDateFormatter *dateFormatter; 
@end 
@implementation Example 
- (NSString *)getFormattedDate:(NSDate *)date 
{ 
return [[self dateFormatter] stringFromDate:date]; 
} 
- (NSDateFormatter *)dateFormatter 
{ 
NSDateFormatter *df = [[NSDateFormatter alloc] init]; 
[df setLocale:[NSLocale localeWithLocaleIdentifier:@" 
es"]]; 
df.dateFormat = @"dd MMM"; 
return df; 
} 
@end 
@interface TestingExample : Example 
@end 
@implementation TestingExample 
- (NSString *)getFormattedDate:(NSDate *)date 
{ 
return [[self dateFormatter] stringFromDate:date]; 
} 
- (NSDateFormatter *)dateFormatter 
{ 
// Devuelve lo que quieras!!! 
} 
@end
Testing
/Testing 
● Test unitarios (XCTest, OCmockito) 
● Test de integración (KIF) 
● Test de aceptación (UIautomation) 
● Jenkins (Integración continua!!!) 
● Test manuales (QA)
Patrones
/Patrones 
● Model View Controller 
● Model View View Model 
● Singleton (AppDelegate) 
● Delegado (@Protocol) 
● Observer (NSNotificationCenter, KVO...) 
● Command (NSInvocation) 
● Factory, state, decorator...
Libros y enlaces
/Libros… peligrosos?
/Libros
/Enlaces de interés 
● www.objc.io 
● www.nshipster.com 
● www.raywenderlich.com 
● www.keyvanakbary.com 
● www.agbo.biz 
● www.ironhack.com
El resultado 
● Más legible 
● Fácil de modificar 
● Fácil de testear 
● Roles dentro del equipo 
● Menos conflictos 
● Y en general… más apetecible
Gracias!!! 
jobs: www.idealista.com/creamcode 
Javier Aznar de los Ríos 
@JaviAznar1 
Enrique Fau de Casa Juana 
@kikefau
¿Preguntas? 
jobs: www.idealista.com/creamcode 
Javier Aznar de los Ríos 
@JaviAznar1 
Enrique Fau de Casa Juana 
@kikefau

cream code with objective-c

  • 1.
    Cream Code with Objective-C Javier Aznar de los Ríos @JaviAznar1 Enrique Fau de Casa Juana @kikefau
  • 3.
    ¿Qué es elCream Code?
  • 4.
    /¿qué es creamcode? Algunas claves ● Entendible ● Extensible ● Mantenible ● Actitud ● Refactorizar como parte del desarrollo ● Programas pequeños
  • 5.
    ¿Qué NO esel Cream Code?
  • 6.
    /¿qué no escream code? Spaghetti Code ● Estructura compleja ● Difícil de entender ● Difícil de testear
  • 8.
    /¿qué no escream code? Código duplicado ● Propenso a errores ● Difícil de mantener ● Oculta el propósito del código
  • 10.
    /¿qué no escream code? Código complejo ● Difícil de entender ● Difícil de mantener ● Propenso a errores
  • 12.
    /¿qué no escream code? Métodos con responsabilidad múltiple ● Difícil de mantener ● Difícil de entender ● Código muy acoplado ● Difícil de testear
  • 14.
    /¿qué no escream code? Sin tests ● Código no probado ● Errores difíciles de localizar ● Producto final “no deseado”
  • 15.
  • 16.
    /si es creamcode Código de calidad ● Modularizado, Extensible ● DRY (Don’t repeat yourself) ● KISS (Keep It Simple, Stupid) ● Con tests ● S.O.L.I.D.
  • 17.
    /si es creamcode S.O.L.I.D. (buenas prácticas) ● Responsabilidad única ● Abierto a extensiones, cerrado a modificaciones ● Clases derivadas no modifican comportamiento de su clase base ● Varias interfaces pequeñas es mejor que sólo una grande ● Uso de abstracciones Robert C. Martin
  • 19.
    ¿Cómo conseguir elcream code? Enrique Fau de Casa Juana @kikefau
  • 20.
  • 21.
    View Potingue Controllervergon/zVoiseow… cajón C ontroller desastre ● Difícil de entender ● Difícil encontrar código ● Difícil de modificar / extender ● Difícil de mantener ● Imposible de testear ● Conflictos
  • 22.
    /View Controller/Responsabilidades Necesitasaber lo que está pasando View Controller Eventos servidor Interacción de usuario Feedback de usuario Modifica el modelo Cambios del modelo Peticiones al servidor Sabe qué hacer en cada momento
  • 23.
    /Crema de labuena Necesitamos crema de la buena ● Adelgazar nuestros View Controllers ● Inyección de dependencias ● Testing (Unit testing, UI...) ● Patrones de diseño ● Libros y enlaces de interés
  • 24.
  • 25.
    /View Controllers adieta Necesitamos crema de la buena ● View & View Controller ● MVC ● Model View View Model ● Lógica de dominio ● Data Sources ● Lógica de Servicios ● View Controller Containment
  • 26.
    ● El controladormaneja una vista ● Sabe qué mostrar, no cómo mostrarlo ● La vista implementa los detalles de presentación (jerarquía, animaciones...) View Controller View eventos de usuario feedback /View & View Controller
  • 27.
    /MVC KVO interaction View Controller user Model View conoce tiene
  • 28.
    /MVVM View ViewController View Model NSDateFormatter NSStringWithFormat ... Model tiene tiene actualiza actualiza
  • 29.
    /Lógica del dominio @implementation PropertyViewController - (void)loadPropertyPictures { self.pictures = [self.property getPictures]; } @end @implementation Property (Extension) - (NSArray *)getPictures { NSString *strPredicate = @"type == %@"; NSPredicate *pred = [NSPredicate predicateWithFormat:formatString, @" picture"]; return [[self.multimedias filteredSetUsingPredicate:pred] allObjects]; } @end View Controller getPictures Property Property + Extension
  • 30.
    /Data source @implementationDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.items count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { id cell = [tableView dequeueReusableCellWithIdentifier… forIndexPath:indexPath]; self.configureCellBlock(cell, [self itemAtIndexPath:indexPath]); return cell; } - (NSObject *)itemAtIndexPath:(NSIndexPath *)indexPath { return self.items[indexPath.row]; } Table View Controller Table View Data Source
  • 31.
    /Web Service ●El VC no debe contener lógica de Web Services ● El controlador no sabe de dónde salen los objetos ● La obtención de objetos debe ser asíncrona ● Se comunicará a través de delegados, notificaciones o bloques View Controller getObjects Service
  • 32.
  • 33.
    View Controller Containment ● Disponible a partir de iOS 5 ● [VC1.view addSubView:VC2.view] ??? ● viewWillAppear, rotaciones… ● Nuevos métodos ● addChildViewController ● didMoveToParentViewController ● removeFromParentViewController
  • 34.
    /Controller Containment ●El padre define las vistas contenedoras ● Los hijos son notificados cuando son añadidos ● El padre realiza las transiciones ● Los hijos deben tener sentido por sí mismos View Controller Container View Controller (Child) View Controller (Child)
  • 35.
    /Controller Containment ViewController Container View Controller View Controller ViVeiwew C Conotnrotrlolellrer Child Delegate (Child) crea implementa define
  • 36.
  • 37.
    Inyección de dependencias ● Dependencia: A depende de B, cuando A necesita de B para hacer su trabajo ● Inyección: El objeto que usa A le dice a A quien es B
  • 38.
    /Inyección de dependencias Necesitamos crema de la buena ● Inyección por constructor ● Inyección de propiedades ● Inyección en métodos ● Extraer método y sobreescribir la llamada
  • 39.
    @implementation Example -(NSString *)getFormattedDate:(NSDate *)date { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"es"]]; dateFormatter.dateFormat = @"dd MMM"; return [dateFormatter stringFromDate:date]; } @end /Ejemplo
  • 40.
    /Inyección por constructor @interface Example () @property(nonatomic, strong) NSDateFormatter *dateFormatter; @end @implementation Example - (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter { self = [super init]; if (self) { _dateFormatter = dateFormatter; } return self; } - (NSString *)getFormattedDate:(NSDate *)date { return [self.dateFormatter stringFromDate:date]; } @end
  • 41.
    /Inyección de propiedades @interface Example () @property(nonatomic, strong) NSDateFormatter *dateFormatter; @end @implementation Example - (NSDateFormatter *)dateFormatter { if (!_dateFormatter) { _dateFormatter = [[NSDateFormatter alloc] init]; [_dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"es"]]; _dateFormatter.dateFormat = @"dd MMM"; } return _dateFormatter; } - (NSString *)getFormattedDate:(NSDate *)date { return [self.dateFormatter stringFromDate:date]; } @end
  • 42.
    /Inyección en métodos @implementation Example - (NSString *)getFormattedDate:(NSDate *)date withDateFormatter:(NSDateFormatter *)dateFormatter { return [dateFormatter stringFromDate:date]; } @end
  • 43.
    /Extraer y sobreescribir @interface Example () @property(nonatomic, strong) NSDateFormatter *dateFormatter; @end @implementation Example - (NSString *)getFormattedDate:(NSDate *)date { return [[self dateFormatter] stringFromDate:date]; } - (NSDateFormatter *)dateFormatter { NSDateFormatter *df = [[NSDateFormatter alloc] init]; [df setLocale:[NSLocale localeWithLocaleIdentifier:@" es"]]; df.dateFormat = @"dd MMM"; return df; } @end @interface TestingExample : Example @end @implementation TestingExample - (NSString *)getFormattedDate:(NSDate *)date { return [[self dateFormatter] stringFromDate:date]; } - (NSDateFormatter *)dateFormatter { // Devuelve lo que quieras!!! } @end
  • 44.
  • 45.
    /Testing ● Testunitarios (XCTest, OCmockito) ● Test de integración (KIF) ● Test de aceptación (UIautomation) ● Jenkins (Integración continua!!!) ● Test manuales (QA)
  • 47.
  • 48.
    /Patrones ● ModelView Controller ● Model View View Model ● Singleton (AppDelegate) ● Delegado (@Protocol) ● Observer (NSNotificationCenter, KVO...) ● Command (NSInvocation) ● Factory, state, decorator...
  • 49.
  • 50.
  • 51.
  • 52.
    /Enlaces de interés ● www.objc.io ● www.nshipster.com ● www.raywenderlich.com ● www.keyvanakbary.com ● www.agbo.biz ● www.ironhack.com
  • 53.
    El resultado ●Más legible ● Fácil de modificar ● Fácil de testear ● Roles dentro del equipo ● Menos conflictos ● Y en general… más apetecible
  • 54.
    Gracias!!! jobs: www.idealista.com/creamcode Javier Aznar de los Ríos @JaviAznar1 Enrique Fau de Casa Juana @kikefau
  • 55.
    ¿Preguntas? jobs: www.idealista.com/creamcode Javier Aznar de los Ríos @JaviAznar1 Enrique Fau de Casa Juana @kikefau