SlideShare une entreprise Scribd logo
1  sur  55
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.Juan Manuel
 
Curso AngularJS - 3. módulos y controladores
Curso AngularJS - 3. módulos y controladoresCurso AngularJS - 3. módulos y controladores
Curso AngularJS - 3. módulos y controladoresÁlvaro Alonso González
 
Introducción al desarrollo Web: Frontend con Angular 6
Introducción al desarrollo Web: Frontend con Angular 6Introducción al desarrollo Web: Frontend con Angular 6
Introducción al desarrollo Web: Frontend con Angular 6Gabriela Bosetti
 
Clean Code (EN ESPANOL)
Clean Code (EN ESPANOL)Clean Code (EN ESPANOL)
Clean Code (EN ESPANOL)Rodrigo Branas
 
JSR354: Moneda y Dinero - Taller
JSR354: Moneda y Dinero - TallerJSR354: Moneda y Dinero - Taller
JSR354: Moneda y Dinero - TallerAlexis Lopez
 
Integrando React.js en aplicaciones Symfony (deSymfony 2016)
Integrando React.js en aplicaciones Symfony (deSymfony 2016)Integrando React.js en aplicaciones Symfony (deSymfony 2016)
Integrando React.js en aplicaciones Symfony (deSymfony 2016)Ignacio Martín
 
Introducción a JQuery
Introducción a JQueryIntroducción a JQuery
Introducción a JQueryContinuum
 
Customizer: configurando un sitio en tiempo real
Customizer: configurando un sitio en tiempo realCustomizer: configurando un sitio en tiempo real
Customizer: configurando un sitio en tiempo realwpargentina
 
05. Creando e implementando objetos y métodos
05. Creando e implementando objetos y métodos05. Creando e implementando objetos y métodos
05. Creando e implementando objetos y métodosDanae Aguilar Guzmán
 
Integrando Game Center en iOS
Integrando Game Center en iOSIntegrando Game Center en iOS
Integrando Game Center en iOSmicroeditionbiz
 
Api De Google Calendar
Api De Google CalendarApi De Google Calendar
Api De Google Calendarjvelizster
 

Tendances (20)

Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
 
Curso AngularJS - 3. módulos y controladores
Curso AngularJS - 3. módulos y controladoresCurso AngularJS - 3. módulos y controladores
Curso AngularJS - 3. módulos y controladores
 
Introducción al desarrollo Web: Frontend con Angular 6
Introducción al desarrollo Web: Frontend con Angular 6Introducción al desarrollo Web: Frontend con Angular 6
Introducción al desarrollo Web: Frontend con Angular 6
 
Directivas en AngularJS
Directivas en AngularJSDirectivas en AngularJS
Directivas en AngularJS
 
Clean Code (EN ESPANOL)
Clean Code (EN ESPANOL)Clean Code (EN ESPANOL)
Clean Code (EN ESPANOL)
 
JSR354: Moneda y Dinero - Taller
JSR354: Moneda y Dinero - TallerJSR354: Moneda y Dinero - Taller
JSR354: Moneda y Dinero - Taller
 
Clase 6 objetos de javaScript
Clase 6 objetos de javaScriptClase 6 objetos de javaScript
Clase 6 objetos de javaScript
 
Clase 7 objetos globales de javaScript
Clase 7 objetos globales de javaScriptClase 7 objetos globales de javaScript
Clase 7 objetos globales de javaScript
 
Ajax
AjaxAjax
Ajax
 
Integrando React.js en aplicaciones Symfony (deSymfony 2016)
Integrando React.js en aplicaciones Symfony (deSymfony 2016)Integrando React.js en aplicaciones Symfony (deSymfony 2016)
Integrando React.js en aplicaciones Symfony (deSymfony 2016)
 
Clase 5 funciones en javaScript
Clase 5 funciones en javaScriptClase 5 funciones en javaScript
Clase 5 funciones en javaScript
 
Introducción a JQuery
Introducción a JQueryIntroducción a JQuery
Introducción a JQuery
 
Ajax
AjaxAjax
Ajax
 
Customizer: configurando un sitio en tiempo real
Customizer: configurando un sitio en tiempo realCustomizer: configurando un sitio en tiempo real
Customizer: configurando un sitio en tiempo real
 
calculadora en c sharp
calculadora en c sharpcalculadora en c sharp
calculadora en c sharp
 
05. Creando e implementando objetos y métodos
05. Creando e implementando objetos y métodos05. Creando e implementando objetos y métodos
05. Creando e implementando objetos y métodos
 
Integrando Game Center en iOS
Integrando Game Center en iOSIntegrando Game Center en iOS
Integrando Game Center en iOS
 
Api De Google Calendar
Api De Google CalendarApi De Google Calendar
Api De Google Calendar
 
Ejemplo de aplicación cliente-servidor en C#
Ejemplo de aplicación cliente-servidor  en C#Ejemplo de aplicación cliente-servidor  en C#
Ejemplo de aplicación cliente-servidor en C#
 
Introduccion a Jquery
Introduccion a JqueryIntroduccion a Jquery
Introduccion a Jquery
 

En vedette

10 tricks to get more app downloads
10 tricks to get more app downloads10 tricks to get more app downloads
10 tricks to get more app downloadsJavier Berlana
 
10 tips for a reusable architecture
10 tips for a reusable architecture10 tips for a reusable architecture
10 tips for a reusable architectureJorge Ortiz
 
Mobile Analytics Betabeers VLC
Mobile Analytics Betabeers VLCMobile Analytics Betabeers VLC
Mobile Analytics Betabeers VLCJavier Berlana
 

En vedette (6)

10 tricks to get more app downloads
10 tricks to get more app downloads10 tricks to get more app downloads
10 tricks to get more app downloads
 
10 tips for a reusable architecture
10 tips for a reusable architecture10 tips for a reusable architecture
10 tips for a reusable architecture
 
Mobile Analytics Betabeers VLC
Mobile Analytics Betabeers VLCMobile Analytics Betabeers VLC
Mobile Analytics Betabeers VLC
 
Groovy on Android
Groovy on AndroidGroovy on Android
Groovy on Android
 
Opinionated android
Opinionated androidOpinionated android
Opinionated android
 
Effective Android UI - spanish
Effective Android UI - spanishEffective Android UI - spanish
Effective Android UI - spanish
 

Similaire à cream code with objective-c

Intro a cakephp
Intro a cakephpIntro a cakephp
Intro a cakephpbetabeers
 
Funciones store proc_triggers
Funciones store proc_triggersFunciones store proc_triggers
Funciones store proc_triggersLuis Jherry
 
Programacion de base de datos - unidad 3 Programacion de base de datos
Programacion de base de datos - unidad 3 Programacion de base de datosProgramacion de base de datos - unidad 3 Programacion de base de datos
Programacion de base de datos - unidad 3 Programacion de base de datosJosé Antonio Sandoval Acosta
 
Funciones store proc_triggers
Funciones store proc_triggersFunciones store proc_triggers
Funciones store proc_triggersLuis Jherry
 
Taller introduccion symfony2
Taller introduccion symfony2Taller introduccion symfony2
Taller introduccion symfony2Mario IC
 
Angular 2 Campus Madrid Septiembre 2016
Angular 2 Campus Madrid Septiembre 2016Angular 2 Campus Madrid Septiembre 2016
Angular 2 Campus Madrid Septiembre 2016Micael Gallego
 
Teoria procedimientos almacenados
Teoria procedimientos almacenadosTeoria procedimientos almacenados
Teoria procedimientos almacenadoshirmaroxana13
 
Android Bootcamp - GTUG Uruguay
Android Bootcamp - GTUG UruguayAndroid Bootcamp - GTUG Uruguay
Android Bootcamp - GTUG Uruguaygtuguruguay
 
¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?Jorge Franco Leza
 
Curso iOS
Curso iOSCurso iOS
Curso iOSPlatzi
 
Desarrollando aplicaciones web usando Catalyst y jQuery
Desarrollando aplicaciones web usando Catalyst y jQueryDesarrollando aplicaciones web usando Catalyst y jQuery
Desarrollando aplicaciones web usando Catalyst y jQueryJavier P.
 
MyBatis como alternativa a Hibernate
MyBatis como alternativa a HibernateMyBatis como alternativa a Hibernate
MyBatis como alternativa a HibernateRubén Aguilera
 

Similaire à cream code with objective-c (20)

Intro a cakephp
Intro a cakephpIntro a cakephp
Intro a cakephp
 
Intro a cakephp
Intro a cakephpIntro a cakephp
Intro a cakephp
 
Funciones store proc_triggers
Funciones store proc_triggersFunciones store proc_triggers
Funciones store proc_triggers
 
Programacion de base de datos - unidad 3 Programacion de base de datos
Programacion de base de datos - unidad 3 Programacion de base de datosProgramacion de base de datos - unidad 3 Programacion de base de datos
Programacion de base de datos - unidad 3 Programacion de base de datos
 
Funciones store proc_triggers
Funciones store proc_triggersFunciones store proc_triggers
Funciones store proc_triggers
 
Taller introduccion symfony2
Taller introduccion symfony2Taller introduccion symfony2
Taller introduccion symfony2
 
Todomir
TodomirTodomir
Todomir
 
Metadata api en apex
Metadata api en apexMetadata api en apex
Metadata api en apex
 
Semana 4 Estructura y componentes SPA
Semana 4  Estructura y componentes SPASemana 4  Estructura y componentes SPA
Semana 4 Estructura y componentes SPA
 
Capa de persistencia con ecto
Capa de persistencia con ectoCapa de persistencia con ecto
Capa de persistencia con ecto
 
Angular 2 Campus Madrid Septiembre 2016
Angular 2 Campus Madrid Septiembre 2016Angular 2 Campus Madrid Septiembre 2016
Angular 2 Campus Madrid Septiembre 2016
 
7.1. procedimientos almacenados
7.1.  procedimientos almacenados7.1.  procedimientos almacenados
7.1. procedimientos almacenados
 
Teoria procedimientos almacenados
Teoria procedimientos almacenadosTeoria procedimientos almacenados
Teoria procedimientos almacenados
 
Android Bootcamp - GTUG Uruguay
Android Bootcamp - GTUG UruguayAndroid Bootcamp - GTUG Uruguay
Android Bootcamp - GTUG Uruguay
 
¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?
 
Curso iOS
Curso iOSCurso iOS
Curso iOS
 
Desarrollando aplicaciones web usando Catalyst y jQuery
Desarrollando aplicaciones web usando Catalyst y jQueryDesarrollando aplicaciones web usando Catalyst y jQuery
Desarrollando aplicaciones web usando Catalyst y jQuery
 
MyBatis como alternativa a Hibernate
MyBatis como alternativa a HibernateMyBatis como alternativa a Hibernate
MyBatis como alternativa a Hibernate
 
Taller de Base de Datos - Unidad 6 SQL procedural
Taller de Base de Datos - Unidad 6 SQL proceduralTaller de Base de Datos - Unidad 6 SQL procedural
Taller de Base de Datos - Unidad 6 SQL procedural
 
Segunda sesion
Segunda sesionSegunda sesion
Segunda sesion
 

cream code with objective-c

  • 1. Cream Code with Objective-C Javier Aznar de los Ríos @JaviAznar1 Enrique Fau de Casa Juana @kikefau
  • 2.
  • 3. ¿Qué es el Cream Code?
  • 4. /¿qué es cream code? Algunas claves ● Entendible ● Extensible ● Mantenible ● Actitud ● Refactorizar como parte del desarrollo ● Programas pequeños
  • 5. ¿Qué NO es el Cream Code?
  • 6. /¿qué no es cream code? Spaghetti Code ● Estructura compleja ● Difícil de entender ● Difícil de testear
  • 7.
  • 8. /¿qué no es cream code? Código duplicado ● Propenso a errores ● Difícil de mantener ● Oculta el propósito del código
  • 9.
  • 10. /¿qué no es cream code? Código complejo ● Difícil de entender ● Difícil de mantener ● Propenso a errores
  • 11.
  • 12. /¿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
  • 13.
  • 14. /¿qué no es cream code? Sin tests ● Código no probado ● Errores difíciles de localizar ● Producto final “no deseado”
  • 16. /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.
  • 17. /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
  • 18.
  • 19. ¿Cómo conseguir el cream code? Enrique Fau de Casa Juana @kikefau
  • 21. 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
  • 22. /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
  • 23. /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
  • 25. /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
  • 26. ● 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
  • 27. /MVC KVO interaction View Controller user Model View conoce tiene
  • 28. /MVVM View View Controller 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 @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
  • 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
  • 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 View Controller Container View Controller View Controller ViVeiwew C Conotnrotrlolellrer Child Delegate (Child) crea implementa define
  • 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
  • 45. /Testing ● Test unitarios (XCTest, OCmockito) ● Test de integración (KIF) ● Test de aceptación (UIautomation) ● Jenkins (Integración continua!!!) ● Test manuales (QA)
  • 46.
  • 48. /Patrones ● Model View Controller ● Model View View Model ● Singleton (AppDelegate) ● Delegado (@Protocol) ● Observer (NSNotificationCenter, KVO...) ● Command (NSInvocation) ● Factory, state, decorator...
  • 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