INSTITUTO POLITÉCNICO NACIONAL

UNIDAD PROFESIONAL INTERDISCIPLINARIADE INGENIERÍAY CIENCIAS SOCIALESY ADMINISTRATIVAS

SECCIÓNDE ESTUDIOSDE POSGRADOE INVESTIGACIÓN

Estructura para el Procesamiento de Datos (Data Processing Framework)

TESIS

QUEPARAOBTENERELGRADODE

MAESTROEN CIENCIASEN INFORMÁTICA

PRESENTA

JESÚS CASILLAS AGUILAR

DIRECTORDE TESIS:

DR.MAURICIO J.PROCEL MORENO

MÉXICO, D.F. 2016

»

SIP-14 INSTITUTO POLITÉCNICO NACIONAL SECRETARÍA DE INVESTIGACIÓN Y POSGRADO

ACTA DE REVISIÓN DE TESIS

En la Ciudad de México, siendo las i8-.oo horas del día 30 del mes de

HAYO del 2016 se reunieron los miembros de la Comisión Revisora de Tesis, designada por el Colegio de Profesores de Estudios de Posgrado e Investigación de UPI ICSA para examinar la tesis titulada: "ESTRUCTURA PARA EL PROCESAMIENTO DE DATOS (DATA PROCESSING FRAMEWORK)".

Presentada por el alumno: CASILLAS AGUILAR JESÚS Apellido paterno Apellido materno Nombre(s) Con registro: B 1 3 1 1 7 6 aspirante de: MAESTRÍA EN CIENCIAS EN INFORMÁTICA Después de intercambiar opiniones, los miembros de la Comisión manifestaron APROBAR LA DEFENSA DE LA TESIS, en virtud de que satisface los requisitos señalados por las disposiciones reglamentarias vigentes.

LA COMISIÓN REVISORA

Director

DR. MAURICIO JORGE PROCEL MORENO

ev? rtflC ó-

DR. EDUARDO GUTIERREZ GONZALEZ^ DR. FAUSTINO RICARDO GARClA SOSA

VAZQUEZ TORRES M. EN MGORDILLOMEJIA

EL PRESIDENTE DEL COLEGIO DE P

U. P.M. C.S. A. SECCIÓN DE ESTUDIOS DE POSGRADO E INVESTIGACIÓN Je LAI. JAIME ARTURO MENESES GALVÁN

INSTITUTO POLITéCNICO NACIONAL

SECRETARíA DE INVESTIGACIóN Y POSGRADO

CARTA CESIóN DE DERECHOS

En la Ciudad de México, Distrito Federal el día 29 del mes de Junio del año 2016, el que suscribe Jesús Casillas Aguilar alumno del Programa de Maestría en Ciencias en Infor­ mática, con número de registro B131176, adscrito a la Sección de Estudios de Posgrado e Investigación de la UPIICSA, manifiesta que es el autor intelectual del presente trabajo de Tesis bajo la dirección del Dr. Mauricio J. Procel Moreno y cede los derechos del trabajo titulado "Estructura para el Procesamiento de Datos (Data Processing Framework*)", al Instituto Politécnico Nacional para su difusión, con fines académicos y de investigación.

Los usuarios de la información no deben reproducir el contenido textual, gráficas o datos del trabajo sin el permiso expreso del autor y/o director del trabajo. Este puede ser ob­ tenido escribiendo a la siguiente dirección: [email protected]. Si el permiso se otorga, el usuario deberá dar el agradecimiento correspondiente y citar la fuente del mismo.

Jesús Casillas Aguilar

A MIMADRE

Por su paciencia, respaldo constante y sabias enseñanzas. Y porque gracias a ella adquirí el gusto por la lectura.

A MI PADRE

Por su rectitud y generosidad que son todo un ejemplo a seguir. Y porque me enseñó a trabajar con perfeccionismo y creatividad.

A MIESPOSA

Por su apoyo incondicional y dedicación para nuestra familia. Y porque es mi fuente de inspiración para seguirme superando.

A MISHIJAS

Por aquellos fines de semana sin poder salir de paseo, y por aquellas noches sin tener historias antes de dormir, pues ese tiempo tenía que destinarse a “La Tesis de Papote”.

Contenido

Lista de Imágenes vii

Lista de Cuadros ix

Lista de Diagramas UML xi

Lista de Programas Java xiii

Lista de Configuraciones XML xv

Resumen 1

Abstract 3

Introducción 5

1 Marco Teórico 7 1.1 Origen de los Lenguajes de Programación ...... 9 1.1.1 Máquina Diferencial ...... 9 1.1.2 Máquina Analítica ...... 11 1.1.3 La Primer Programadora ...... 12 1.1.4 Tarjetas Perforadas ...... 13 1.1.5 Enigma ...... 15 1.1.6 Máquina Universal ...... 16 1.1.7 Bombe ...... 18 1.1.8 ENIAC ...... 19 1.1.9 EDVAC y ACE ...... 21 1.2 Primeros Lenguajes de Alto Nivel ...... 23 1.2.1 Short Code ...... 23 1.2.2 FORTRAN ...... 24 1.2.3 FLOW-MATIC y COBOL ...... 25 1.2.4 BASIC ...... 26

I ii CONTENIDO

1.3 Lenguajes Estructurados ...... 29 1.3.1 Pascal ...... 30 1.3.2 C ...... 31 1.4 Lenguajes Modulares ...... 33 1.4.1 Modula y Modula-2 ...... 34 1.5 Lenguajes Orientados a Objetos ...... 35 1.5.1 Smalltalk ...... 36 1.5.2 C++ ...... 38 1.5.3 Java ...... 39 1.6 Programación Orientada a Objetos ...... 43 1.6.1 Datos y Operaciones ...... 43 1.6.2 Interfaz e Implementación ...... 44 1.6.3 Objetos ...... 48 1.6.4 Clases ...... 51 1.7 Mecanismos de Abstracción ...... 53 1.7.1 Encapsulación ...... 53 1.7.2 Polimorfismo ...... 54 1.7.3 Sobrecarga ...... 56 1.7.4 Herencia ...... 56 1.8 Patrones de Diseño ...... 61 1.8.1 Historia de los Patrones de Diseño ...... 62 1.8.2 Organización y Lenguaje de Patrones ...... 64 1.8.3 La Importancia de los Patrones ...... 66 1.9 Clasificación de los Patrones de Diseño ...... 68 1.9.1 Patrones de Diseño Creacionales ...... 68 1.9.2 Patrones de Diseño Estructurales ...... 69 1.9.3 Patrones de Diseño de Comportamiento ...... 70 1.10 Consideraciones de la Orientación a Objetos ...... 71 1.10.1 Beneficios y Objetivos ...... 71 1.10.2 Reutilización ...... 73 1.10.3 Trampas Comunes ...... 75

2 Diseño de Software 77 2.1 Consideraciones de Diseño ...... 79 2.2 Estructuras de Programación ...... 81 2.2.1 Meta-programación ...... 81 2.2.2 Reflexión de código ...... 82 2.3 Herramientas de Diseño ...... 83 CONTENIDO iii

2.3.1 Lenguaje Unificado de Modelado (UML) ...... 83 2.3.2 Lenguaje de Etiquetado Extensible (XML) ...... 85 2.4 Estructuras de Datos ...... 87 2.4.1 Clase Columna ...... 87 2.4.2 Clase Tabla ...... 91 2.5 Modelo de Objetos ...... 93 2.5.1 Clase Parámetro ...... 93 2.5.2 Clase Solución ...... 95 2.5.3 Clase Epd ...... 97 2.6 Modelo EPD ...... 99 2.7 Arquitectura de Configuración ...... 100 2.7.1 Arquitectura Java para Enlazado de XML (JAXB) ...... 102 2.7.2 Estructura Basada en Soluciones ...... 106 2.7.3 Parámetros de Ejecución ...... 108 2.8 Lógica de Procesamiento ...... 111 2.9 Fórmulas de Procesamiento ...... 113 2.9.1 Transformación de Valores ...... 113 2.9.2 Filtrado de Valores ...... 116 2.10 Desarrollo Dirigido por la Configuración (CDD) ...... 118 2.10.1 Herramientas requeridas ...... 118 2.10.2 Reglas de desarrollo ...... 119 2.10.3 Beneficios ...... 120 2.10.4 Costos ...... 121 2.10.5 Limitaciones y soluciones de compromiso ...... 121

3 Implementación 123 3.1 Lectores de Datos ...... 125 3.1.1 Lector CSV ...... 126 3.1.2 Lector SQL ...... 130 3.1.3 Lector TXT ...... 133 3.1.4 Lector XML ...... 137 3.2 Procesadores de Datos ...... 141 3.2.1 Procesador Agrupar ...... 142 3.2.2 Procesador Clonar ...... 145 3.2.3 Procesador Clonar Tabla ...... 148 3.2.4 Procesador Comparar ...... 151 3.2.5 Procesador Conciliar ...... 156 3.2.6 Procesador Dividir ...... 162 iv CONTENIDO

3.2.7 Procesador Eliminar ...... 165 3.2.8 Procesador Eliminar Tabla ...... 168 3.2.9 Procesador Equivaler ...... 171 3.2.10 Procesador Filtrar ...... 174 3.2.11 Procesador Fusionar ...... 177 3.2.12 Procesador Insertar ...... 180 3.2.13 Procesador Ordenar ...... 183 3.2.14 Procesador Transformar ...... 185 3.2.15 Procesador Unir ...... 188 3.3 Publicadores de Datos ...... 192 3.3.1 Publicador CSV ...... 193 3.3.2 Publicador SQL ...... 196 3.3.3 Publicador TXT ...... 199 3.3.4 Publicador XML ...... 201 3.4 Interfaz de Usuario ...... 203 3.4.1 Línea de Comandos ...... 203 3.5 Casos de Uso ...... 205 3.5.1 Caso de Uso Migración ...... 205 3.5.2 Caso de Uso Reporte ...... 209 3.5.3 Caso de Uso Conciliación ...... 213

Conclusiones 221

A Anexo: Referencias del Lenguaje 225 A.1 Lenguaje Java ...... 227 A.1.1 Tipos de Datos ...... 227 A.1.2 Operadores ...... 228

B Anexo: Listados de Programas en Lenguaje Java 229 B.1 Estructuras de Datos ...... 231 B.1.1 Clase Columna ...... 231 B.1.2 Clase Tabla ...... 232 B.2 Modelo de Objetos ...... 233 B.2.1 Clase Parámetro ...... 233 B.2.2 Clase Solución ...... 234 B.2.3 Clase EPD ...... 235

C Anexo: Listados de Configuraciones en Lenguaje XML 237 C.1 Lectores ...... 239 CONTENIDO v

C.1.1 Lector CSV ...... 239 C.1.2 Lector SQL ...... 241 C.1.3 Lector TXT ...... 242 C.1.4 Lector XML ...... 244 C.2 Procesadores ...... 247 C.2.1 Procesador Agrupar ...... 247 C.2.2 Procesador Clonar ...... 248 C.2.3 Procesador Clonar Tabla ...... 249 C.2.4 Procesador Comparar ...... 250 C.2.5 Procesador Conciliar ...... 251 C.2.6 Procesador Dividir ...... 253 C.2.7 Procesador Eliminar ...... 254 C.2.8 Procesador Eliminar Tabla ...... 255 C.2.9 Procesador Equivaler ...... 256 C.2.10 Procesador Filtrar ...... 257 C.2.11 Procesador Fusionar ...... 258 C.2.12 Procesador Insertar ...... 259 C.2.13 Procesador Ordenar ...... 260 C.2.14 Procesador Transformar ...... 261 C.2.15 Procesador Unir ...... 262 C.3 Publicadores ...... 263 C.3.1 Publicador CSV ...... 263 C.3.2 Publicador TXT ...... 264 C.3.3 Publicador SQL ...... 265 C.3.4 Publicador XML ...... 266

Bibliografía 267 Libros ...... 267 Páginas Web ...... 269 vi CONTENIDO Lista de Imágenes

Imagen 1.1 Interfaz e Implementación ...... 45 Imagen 1.2 Un objeto ...... 49 Imagen 1.3 Objetos en una red ...... 50 Imagen 1.4 Una jerarquía de herencia ...... 57 Imagen 1.5 Patrones en un Edificio ...... 63 Imagen 1.6 Patrones en unas Columnas ...... 64 Imagen 1.7 Ensamblaje Espiga Compuesto ...... 66 Imagen 1.8 Ensamblaje Espiga ...... 67

Imagen 2.1 Ejemplo de la clase Tabla ...... 92 Imagen 2.2 Calendario de Días Inhábiles ...... 109 Imagen 2.3 Ejemplo de fórmula numérica en inserción de columna ...... 113 Imagen 2.4 Ejemplo de fórmula fecha en transformación de columna . . . . . 114 Imagen 2.5 Ejemplo de fórmula cadena en transformación de columna . . . . 115 Imagen 2.6 Ejemplo de fórmula fecha en filtrado de renglones ...... 116 Imagen 2.7 Ejemplo de fórmula numérica en filtrado de renglones ...... 117

Imagen 3.1 Ejemplo de la clase LectorCsv ...... 129 Imagen 3.2 Ejemplo de la clase LectorSql ...... 132 Imagen 3.3 Ejemplo de la clase LectorTxt ...... 135 Imagen 3.4 Ejemplo de la clase LectorXml ...... 138 Imagen 3.5 Ejemplo de la clase ProcesadorAgrupar ...... 143 Imagen 3.6 Ejemplo de la clase ProcesadorClonar ...... 146 Imagen 3.7 Ejemplo de la clase ProcesadorClonarTabla ...... 149 Imagen 3.8 Ejemplo de la clase ProcesadorComparar ...... 154 Imagen 3.9 Ejemplo de la clase ProcesadorConciliar ...... 160 Imagen 3.10 Ejemplo de la clase ProcesadorDividir ...... 163 Imagen 3.11 Ejemplo de la clase ProcesadorEliminar ...... 166 Imagen 3.12 Ejemplo de la clase ProcesadorEliminarTabla ...... 169 Imagen 3.13 Ejemplo de la clase ProcesadorEquivaler ...... 172 Imagen 3.14 Ejemplo de la clase ProcesadorFiltrar ...... 175

VII viii LISTA DE IMÁGENES

Imagen 3.15 Ejemplo de la clase ProcesadorFusionar ...... 178 Imagen 3.16 Ejemplo de la clase ProcesadorInsertar ...... 181 Imagen 3.17 Ejemplo de la clase ProcesadorOrdenar ...... 184 Imagen 3.18 Ejemplo de la clase ProcesadorTransformar ...... 186 Imagen 3.19 Ejemplo de la clase ProcesadorUnir ...... 190 Imagen 3.20 Ejemplo de la clase LectorCsv ...... 194 Imagen 3.21 Ejemplo de la clase LectorSql ...... 198 Imagen 3.22 Ejemplo de la clase LectorTxt ...... 200 Imagen 3.23 Ejemplo de la clase LectorXml ...... 202 Imagen 3.24 Ejemplo del Caso de Uso Migración ...... 205 Imagen 3.25 Ejemplo del Caso de Uso Reporte ...... 209 Imagen 3.26 Ejemplo del Caso de Uso Conciliación ...... 214 Lista de Cuadros

Cuadro 1.1 Patrones de Diseño ...... 68

Cuadro 2.1 Atributos de la Clase Columna ...... 87 Cuadro 2.2 Atributos de la Clase Tabla ...... 91 Cuadro 2.3 Elementos de la Clase Parametro ...... 93 Cuadro 2.4 Atributos de la Clase Solucion ...... 95 Cuadro 2.5 Operación de la Clase Solucion ...... 95 Cuadro 2.6 Atributos de la Clase Epd ...... 97 Cuadro 2.7 Operación de la Clase Epd ...... 98

Cuadro 3.1 Atributos de la Clase LectorCsv ...... 127 Cuadro 3.2 Atributos de la Clase LectorSql ...... 130 Cuadro 3.3 Atributos de la Clase LectorTxt ...... 133 Cuadro 3.4 Atributos de la Clase LectorXml ...... 137 Cuadro 3.5 Atributos de la Clase ProcesadorAgrupar ...... 142 Cuadro 3.6 Atributos de la Clase ProcesadorClonar ...... 145 Cuadro 3.7 Atributos de la Clase ProcesadorClonarTabla ...... 148 Cuadro 3.8 Atributos de la Clase ProcesadorComparar ...... 151 Cuadro 3.9 Atributos de la Clase ProcesadorConciliar ...... 157 Cuadro 3.10 Atributos de la Clase ParColumna ...... 158 Cuadro 3.11 Atributos de la Clase ProcesadorDividir ...... 162 Cuadro 3.12 Atributos de la Clase ProcesadorEliminar ...... 165 Cuadro 3.13 Atributos de la Clase ProcesadorEliminarTabla ...... 168 Cuadro 3.14 Atributos de la Clase ProcesadorEquivaler ...... 171 Cuadro 3.15 Atributos de la Clase ProcesadorFiltrar ...... 174 Cuadro 3.16 Atributos de la Clase ProcesadorFusionar ...... 177 Cuadro 3.17 Atributos de la Clase ProcesadorInsertar ...... 180 Cuadro 3.18 Atributos de la Clase ProcesadorOrdenar ...... 183 Cuadro 3.19 Atributos de la Clase ProcesadorTransformar ...... 185 Cuadro 3.20 Atributos de la Clase ProcesadorUnir ...... 189 Cuadro 3.21 Atributos de la Clase PublicadorCsv ...... 193

IX x LISTA DE CUADROS

Cuadro 3.22 Atributos de la Clase PublicadorSql ...... 196 Cuadro 3.23 Atributos de la Clase PublicadorTxt ...... 199 Cuadro 3.24 Atributos de la Clase PublicadorXml ...... 201

Cuadro A.1 Tipos de Datos en Java ...... 227 Cuadro A.2 Operadores en Java ...... 228 Lista de Diagramas UML

Diagrama 2.1 Ejemplo de Diagrama de Clase ...... 83 Diagrama 2.2 Ejemplo de Diagrama de Clase en Java ...... 84 Diagrama 2.3 Clase Columna ...... 87 Diagrama 2.4 Clase Tabla ...... 91 Diagrama 2.5 Clase Parametro ...... 93 Diagrama 2.6 Clase Solucion ...... 95 Diagrama 2.7 Clase Epd ...... 97 Diagrama 2.8 Modelo EPD ...... 99

Diagrama 3.1 Interface Lector ...... 125 Diagrama 3.2 Clase LectorCsv ...... 126 Diagrama 3.3 Clase LectorSql ...... 130 Diagrama 3.4 Clase LectorTxt ...... 133 Diagrama 3.5 Clase LectorXml ...... 137 Diagrama 3.6 Interface Procesador ...... 141 Diagrama 3.7 Clase ProcesadorAgrupar ...... 142 Diagrama 3.8 Clase ProcesadorClonar ...... 145 Diagrama 3.9 Clase ProcesadorClonarTabla ...... 148 Diagrama 3.10 Clase ProcesadorComparar ...... 151 Diagrama 3.11 Clase ProcesadorConciliar ...... 156 Diagrama 3.12 Clase ProcesadorDividir ...... 162 Diagrama 3.13 Clase ProcesadorEliminar ...... 165 Diagrama 3.14 Clase ProcesadorEliminarTabla ...... 168 Diagrama 3.15 Clase ProcesadorEquivaler ...... 171 Diagrama 3.16 Clase ProcesadorFiltrar ...... 174 Diagrama 3.17 Clase ProcesadorFusionar ...... 177 Diagrama 3.18 Clase ProcesadorInsertar ...... 180 Diagrama 3.19 Clase ProcesadorOrdenar ...... 183 Diagrama 3.20 Clase ProcesadorTransformar ...... 185 Diagrama 3.21 Clase ProcesadorUnir ...... 188 Diagrama 3.22 Interface Publicador ...... 192

XI xii LISTA DE DIAGRAMAS UML

Diagrama 3.23 Clase PublicadorCsv ...... 193 Diagrama 3.24 Clase PublicadorSql ...... 196 Diagrama 3.25 Clase PublicadorTxt ...... 199 Diagrama 3.26 Clase PublicadorXml ...... 201 Lista de Programas Java

Programa 2.1 Implementación de la clase Columna ...... 88 Programa 2.2 Inicialización de la clase Columna ...... 88 Programa 2.3 Implementación del atributo nombre en la clase Columna . . . . 89 Programa 2.4 Inicialización de los atributos en la clase Columna ...... 89 Programa 2.5 Implementación de constructores en la clase Columna ...... 90 Programa 2.6 Inicialización de la clase Columna con un constructor ...... 90 Programa 2.7 Inicialización de la clase Tabla ...... 92 Programa 2.8 Ejemplo de inicialización de la clase Parametro ...... 94 Programa 2.9 Inicialización de la clase Solucion ...... 96 Programa 2.10 Inicialización de la clase Epd ...... 98 Programa 2.11 Implementación de JAXB en la clase Parametro ...... 103 Programa 2.12 Implementación de JAXB en la clase Epd ...... 104 Programa 2.13 Proceso de enlazado XML mediante JAXB ...... 105 Programa 2.14 Implementación del método main() ...... 111 Programa 2.15 Implementación del método epd.procesar() ...... 111 Programa 2.16 Implementación del método solucion.procesar() ...... 112

Programa B.1 Implementación de la clase Columna ...... 231 Programa B.2 Implementación de la clase Tabla ...... 232 Programa B.3 Implementación de la clase Parametro ...... 233 Programa B.4 Implementación de la clase Solucion ...... 234 Programa B.5 Implementación de la clase Epd ...... 235

XIII xiv LISTA DE PROGRAMAS JAVA Lista de Configuraciones XML

Configuración 2.1 Implementación de la clase Epd ...... 100 Configuración 2.2 Esquema básico de una EPD ...... 100 Configuración 2.3 Esquema básico de la clase Parametro ...... 102 Configuración 2.4 Esquema básico de la clase Epd ...... 104 Configuración 2.5 Secciones de una EPD ...... 106 Configuración 2.6 Parámetros de una EPD ...... 108

Configuración 3.1 Caso de Uso Migración ...... 206 Configuración 3.2 Caso de Uso Reporte ...... 210 Configuración 3.3 Caso de Uso Conciliación ...... 215

Configuración C.1 Estructura de la clase LectorCsv ...... 239 Configuración C.2 Ejemplo de la clase LectorCsv ...... 240 Configuración C.3 Estructura de la clase LectorSql ...... 241 Configuración C.4 Ejemplo de la clase LectorSql ...... 241 Configuración C.5 Estructura de la clase LectorTxt ...... 242 Configuración C.6 Ejemplo de la clase LectorTxt ...... 243 Configuración C.7 Estructura de la clase LectorXml ...... 244 Configuración C.8 Ejemplo de la clase LectorXml ...... 245 Configuración C.9 Estructura de la clase ProcesadorAgrupar ...... 247 Configuración C.10 Ejemplo de la clase ProcesadorAgrupar ...... 247 Configuración C.11 Estructura de la clase ProcesadorClonar ...... 248 Configuración C.12 Ejemplo de la clase ProcesadorClonar ...... 248 Configuración C.13 Estructura de la clase ProcesadorClonarTabla ...... 249 Configuración C.14 Ejemplo de la clase ProcesadorClonarTabla ...... 249 Configuración C.15 Estructura de la clase ProcesadorComparar ...... 250 Configuración C.16 Ejemplo de la clase ProcesadorComparar ...... 250 Configuración C.17 Estructura de la clase ProcesadorConciliar ...... 251 Configuración C.18 Ejemplo de la clase ProcesadorConciliar ...... 252 Configuración C.19 Estructura de la clase ProcesadorDividir ...... 253 Configuración C.20 Ejemplo de la clase ProcesadorDividir ...... 253

XV xvi LISTA DE CONFIGURACIONES XML

Configuración C.21 Estructura de la clase ProcesadorEliminar ...... 254 Configuración C.22 Ejemplo de la clase ProcesadorEliminar ...... 254 Configuración C.23 Estructura de la clase ProcesadorEliminarTabla . . . . . 255 Configuración C.24 Ejemplo de la clase ProcesadorEliminarTabla ...... 255 Configuración C.25 Estructura de la clase ProcesadorEquivaler ...... 256 Configuración C.26 Ejemplo de la clase ProcesadorEquivaler ...... 256 Configuración C.27 Estructura de la clase ProcesadorFiltrar ...... 257 Configuración C.28 Ejemplo de la clase ProcesadorFiltrar ...... 257 Configuración C.29 Estructura de la clase ProcesadorFusionar ...... 258 Configuración C.30 Ejemplo de la clase ProcesadorFusionar ...... 258 Configuración C.31 Estructura de la clase ProcesadorInsertar ...... 259 Configuración C.32 Ejemplo de la clase ProcesadorInsertar ...... 259 Configuración C.33 Estructura de la clase ProcesadorOrdenar ...... 260 Configuración C.34 Ejemplo de la clase ProcesadorOrdenar ...... 260 Configuración C.35 Estructura de la clase ProcesadorTransformar ...... 261 Configuración C.36 Ejemplo de la clase ProcesadorTransformar ...... 261 Configuración C.37 Estructura de la clase ProcesadorUnir ...... 262 Configuración C.38 Ejemplo de la clase ProcesadorUnir ...... 262 Configuración C.39 Estructura de la clase PublicadorCsv ...... 263 Configuración C.40 Ejemplo de la clase PublicadorCsv ...... 263 Configuración C.41 Estructura de la clase PublicadorTxt ...... 264 Configuración C.42 Ejemplo de la clase PublicadorTxt ...... 264 Configuración C.43 Estructura de la clase PublicadorSql ...... 265 Configuración C.44 Ejemplo de la clase PublicadorSql ...... 265 Configuración C.45 Estructura de la clase PublicadorXml ...... 266 Configuración C.46 Ejemplo de la clase PublicadorXml ...... 266 Resumen

En el entorno computacional, desde su origen, los lenguajes de programación han sido el factor desencadenante de una evolución progresiva pero acelerada de la díada tecnológica compuesta por el hardware y el software; y ello también ha estado ligado con los logros en la optimización y el alcance de los diferentes tipos de soluciones informáticas implementadas en el lenguaje del momento.

Ha sido un largo camino desde los primeros lenguajes ensambladores, altamente crípti- cos e irremediablemente encadenados con la arquitectura propia de cada computadora, hasta los lenguajes orientados a objetos de hoy en día, enfocados en brindar un para- digma fundamentado en el lenguaje humano y en una abstracción más natural de sus equivalencias con los objetos del mundo real.

En el tema específico del presente trabajo de tesis, he conseguido aprovechar las capa- cidades de dinamismo creacional para instanciar objetos en el lenguaje Java, a fin de crear una estructura de meta-programación altamente flexible, pero al mismo tiempo, decididamente robusta y escalable.

Es así que la solución obtenida ha sido capaz de cubrir en su totalidad el cúmulo de necesidades de procesamiento detectadas en los requerimientos iniciales. Pero todavía más allá: representa el establecimiento de una firme cimentación sobre la que pueden edificarse soluciones más complejas sin perder sus propiedades originales de flexibilidad y robustez.

Entonces, lo que he logrado abarcar dentro del alcance primigenio del presente trabajo ha sido la implementación de un sistema específico de reconciliaciones de datos en un área operativa dentro de una institución financiera de banca privada en México.

Pero más allá de esa primera materialización que ya ha sido reseñada aquí, la Estruc- tura para el Procesamiento de Datos (Data Processing Framework) tiene todas las características de sencillez y versatilidad que seguramente la harán de gran utilidad en cualquier otro ámbito con necesidades similares.

1 2 RESUMEN Abstract

In the computing environment, since its inception, programming languages have been the trigger for a progressive but accelerated technological evolution for the dyad com- posed of hardware and software; and this has also been linked with the achievements in optimizing and scope of the different types of solutions implemented in the language of the moment.

It’s been a long way since the first assemblers, highly cryptic and hopelessly chained with the architecture of each computer, to today’s object-oriented languages, focused on providing a paradigm based on human language and in a more natural abstraction for their equivalences with objects in the real world.

In the specific topic of this thesis, I managed to leverage the capabilities of creational dynamism to instantiate objects in the Java language to create a highly flexible meta- programming structure, but at the same time decidedly robust and scalable.

So that the obtained solution has been able to fully cover the mass of processing needs identified in the initial requirements. But still further: it represents the establishment of a firm foundation on which can be built more complex solutions without losing its original properties of flexibility and robustness.

So what I’ve accomplished encompassed within the primal scope of this work has been the implementation of a specific set of data reconciliations in an operational area within a financial institution of private banking in Mexico.

But beyond that first realization that has already been reviewed here, the Data Proces- sing Framework (Estructura para el Procesamiento de Datos) has all the features of simplicity and versatility that surely will be very useful in any another area with similar needs.

3 4 ABSTRACT Introducción

El objetivo principal del presente trabajo es el diseño e implementación de una Estruc- tura para el Procesamiento de Datos (Data Processing Framework) que sea capaz de resolver necesidades y problemática propias de las áreas operativas en una compañía de Banca de Inversión, cuyo giro de negocio es el del sector financiero; donde se logró implementar exitosamente, siendo capaz de dar solución a los diferentes casos de uso en cada área operativa. En la práctica, el mayor logro para una versión de la Estruc- tura para el Procesamiento de Datos ha sido el haber reemplazado en su totalidad a “Intellimatch”: un sistema existente de reconciliaciones hecho por terceros, y que además de caro, brindaba tiempos de desarrollo excesivamente largos.

Esto ocurrió en el Área de Control de Productos Financieros (Product Control). Una particularidad de ésta área es que durante un día normal de operación, la mayoría de sus funciones están enfocadas en mantener una vigilancia constante entre las operacio- nes concretadas de Compras y Ventas por parte de los Negociadores (Traders) del Área Comercial (Front Office), y las operaciones de Pagos y Cobros del Área de Operaciones (Back Office).

Para poder cumplir sus funciones de vigilar la exactitud de las operaciones de ambas áreas, se requieren herramientas de reconciliación entre los datos provenientes tanto de los sistemas del Área Comercial como los del Área de Operaciones; en su momento, esas herramientas de reconciliación eran responsabilidad de Intellimatch.

Fue entonces que ocurrió un evento que sirvió como detonante para que la gerencia diera su autorización al desarrollo de una versión de la Estructura para el Procesamiento de Datos. Todo comenzó cuando el Área Comercial externó su interés en comenzar a ofrecer un nuevo producto a sus clientes, llamado “Swapciones”(“Swaptions”).

Cada vez que el Área Comercial solicita el desarrollo de un nuevo producto financiero, hay toda una serie de modificaciones a los sistemas existentes a fin de que sean capaces de llevar a cabo tanto las valuaciones del mismo, como una correcta contabilidad y reporte de pérdidas y ganancias a las entidades reguladoras como el Banco de México.

5 6 INTRODUCCIÓN

Una de las modificaciones más importantes tiene que ver con habilitar al Área de Con- trol de Productos Financieros para llevar a cabo las reconciliaciones de las operaciones utilizando el nuevo producto. Así fue que ésta área solicitó a Intellimatch hacer un aná- lisis del tiempo requerido para que le desarrollasen la reconciliación de las Swapciones. La estimación preliminar entregada por Intellimatch era de 10 meses de desarrollo.

Varias áreas expresaron su rechazo inicial a la propuesta de Intellimatch, pues era casi un año de espera antes de que el Área Comercial pudiera comenzar a ofrecer el producto a sus clientes, pero sin una reconciliación en proceso de desarrollo, no podría darse luz verde a las demás áreas para implementar el producto en su totalidad.

Al ver entonces la oportunidad de ofrecer una mejor opción, presenté una estimación rival para llevar a cabo el desarrollo interno, que disminuía el tiempo estimado de 10 a 6 meses, por un precio similar. De esos 6 meses de desarrollo, los primeros 4 meses estarían dedicados exclusivamente a construir el Núcleo (Kernel) de la Estructura para el Procesamiento de Datos. Es decir, el desarrollo de la Configuración, los Lectores, Procesadores y Publicadores.

Lo que hizo la diferencia y significó el éxito en la aceptación de la nueva propuesta, fue que los 2 meses restantes en el tiempo del desarrollo serían dedicados no sólo a configurar e implementar la reconciliación para las Swapciones, sino que como parte de la misma propuesta, se incluía el desarrollo y migración de los otros 19 productos que ya estaban siendo reconciliados por Intellimatch, entre ellos: Bonds, Capsfloors, Depos, Equity Options, FX, FX Forwards, Loans, Repos, Swaps, etc.

Ello significaba que: en tan sólo la quinta parte del tiempo requerido por Intellimatch para desarrollar únicamente 1 producto, la Estructura para el Procesamiento de Datos era capaz de conseguir el desarrollo y migración completos para 20 productos.

De esa forma, no sólo se garantizaba que sí sería posible poder ofrecerles a los clientes operaciones con Swapciones en un menor tiempo, mejorando las posibilidades de hacer crecer el negocio rápidamente. Además también eliminaba por completo la necesidad de seguir pagando la licencia anual de Intellimatch de varios miles de dólares, y permitía reemplazarlo por un desarrollo interno, mucho más barato en términos de desarrollo y de soporte.

Así se demostró el éxito rotundo de la idea original llevada a la práctica y sirvió para expandir el interés en utilizar la Estructura para el Procesamiento de Datos en otro tipo de desarrollos como la eliminación de herramientas tácticas basadas en hojas de cálculo, además del desarrollo de otras aplicaciones de procesamiento de datos (no solamente reconciliaciones), como herramientas de validación y de migración de datos. 1| Marco Teórico

7 8 1. MARCO TEÓRICO 1.1. ORIGEN DE LOS LENGUAJES DE PROGRAMACIÓN 9

1.1. Origen de los Lenguajes de Programación

Un Lenguaje de Programación es un lenguaje que se construye de manera formal, y que está diseñado para comunicar instrucciones a una máquina, en particular a una computadora. [97]

Los lenguajes de programación pueden ser utilizados para crear programas que contro- len el comportamiento de una máquina o para expresar Algoritmos, que son conjuntos autónomos de operaciones que deberán realizarse paso a paso. Existen todo tipo de al- goritmos definidos para llevar a cabo diferentes tareas, desde cálculos y procesamiento de datos hasta razonamiento automatizado. [34]

A la fecha, ya han sido creados miles de diferentes lenguajes de programación, y mu- chos más están siendo creados cada año. Muchos lenguajes de programación requieren que sus instrucciones se especifiquen en una forma imperativa (es decir, como una se- cuencia de operaciones a realizar), mientras que otros lenguajes utilizan otras formas de especificación de programas, tales como la forma declarativa (es decir, se especifica el resultado deseado, no la forma en cómo lograrlo). [23] [74] [108]

1.1.1. Máquina Diferencial

La historia de los lenguajes de programación comienza en 1822, cuando el matemático y científico británico inventó una máquina de diferencias mecánicas para calcular tablas de números, denominada máquina diferencial. En aquel entonces el cálculo de las tablas logarítmicas y de funciones polinómicas era una labor compleja y tediosa llevada a cabo manualmente por “computadoras” humanas. Por ello, eran propensas a errores provocados por la fatiga o aburrimiento que sufrían las personas encargadas de compilar las tablas matemáticas de la época.

Babbage, considerado por muchos como el “padre de la computadora”, estaba inten- tando encontrar un método por el cual una máquina pudiera hacer cálculos automáti- camente, eliminando errores. Su aversión al desorden y su conocimiento de las tablas logarítmicas fueron dos de los principales motivadores para su invención. Pero su mayor influencia fueron los trabajos de máquinas calculadoras realizadas por el matemático y filósofo francés Blaise Pascal y por el filósofo y matemático alemán Gottfried Leibniz. [48]

Pascal, en 1642, había inventado la Pascalina o “Rueda de Pascal”, que consistía de una caja de metal poco más pequeña que una caja de zapatos, con seis ruedas giratorias 10 1. MARCO TEÓRICO

en un extremo de la parte superior, y seis ventanas en la parte superior mostrando números del 0 al 9. Internamente tenía un mecanismo compuesto de ruedas y engranes que permitían hacer sumas y restas de manera directa, y multiplicaciones y divisiones mediante repetición. La principal motivación de Pascal para hacer su invento era un esfuerzo por intentar aliviar los exhaustivos e interminables cálculos y recálculos de impuestos adeudados y pagados que tenía que realizar su padre, Étiene Pascal, quien ostentaba el cargo de Comisionado Real de Impuestos en la ciudad francesa de Rouen. [43] [96]

Años más tarde, en 1670, Leibniz inventó la Stepped Reckoner o “Máquina de Leibniz”, enfocado en expandir el mecanismo de Pascal a fin de que también pudiera multiplicar y dividir. Su máquina fue la primera calculadora que podía realizar directamente todas las cuatro operaciones aritméticas. Estaba hecha de latón pulido y acero, montados en una caja de madera de roble, que en conjunto tenía una longitud de unos 67 centímetros. Se componía de dos secciones paralelas unidas: una sección de entrada de 8 dígitos en la parte delantera con 8 diales con perillas para establecer el número de operando; y una sección de acumulador en la parte trasera, que podía contener hasta 16 dígitos decimales con una manivela en la parte frontal para realizar el cálculo. [103]

Los motivos de Leibniz para su invención se resumen en su siguiente frase:

“Está por debajo de la dignidad de los hombres excelentes perder su tiempo en el trabajo del cálculo cuando cualquier campesino podría hacer un trabajo de la misma precisión con la ayuda de una máquina”. [69]

Fue en 1822, cuando Charles Babbage recibió el apoyo del gobierno británico para la realización de su máquina diferencial, otorgándole la cantidad de £1,700, pues al gobierno le interesaba hacer de la generación de tablas una tarea más rápida y eco- nómica. Sin embargo, veinte años después, en 1842, y luego de haber recibido diez veces la cantidad inicial, es decir £17,000, resultaba evidente el fracaso del proyecto inicial; culpa, en parte, de las técnicas metalúrgicas de la época, que no eran capaces de brindar de forma económica las piezas en la precisión y cantidades requeridas, por lo que la construcción de la máquina nunca fue completada. [56]

Además de ello, Babbage había hecho obsoleto el concepto inicial de la máquina diferen- cial, y se había enfocado en el desarrollo de la nueva máquina analítica, aprovechando el conocimiento y experiencia obtenidos con sus diseños iniciales. 1.1. ORIGEN DE LOS LENGUAJES DE PROGRAMACIÓN 11

1.1.2. Máquina Analítica

Su propuesta de la máquina analítica es lo que podría considerarse como la primera computadora mecánica de propósito general, y como se describió en 1873, incorporaba una unidad aritmética lógica, un control de flujo en forma de ramificaciones y bucles condicionales, y una memoria integrada. Es decir, que la estructura lógica de la máquina analítica fue esencialmente la misma que ha dominado el diseño de las computadoras en la era electrónica.

La entrada que recibiría la máquina consistía en programas y datos (“formulae” y “da- ta”) que debían proporcionarse a la máquina mediante tarjetas perforadas, un método utilizado en la época para dirigir telares mecánicos.

La salida de la máquina sería una impresora, un trazador de curvas y una campana. Y la máquina también sería capaz de perforar los números en las tarjetas para ser leídos más tarde; para ello utilizaba números ordinarios de punto fijo en base 10.

Tendría un almacenamiento (es decir, una memoria) capaz de almacenar 1,000 núme- ros de 40 dígitos decimales cada uno (aproximadamente 16.2 kB). La unidad aritmética (conocida como el “molino”) sería capaz de realizar todas las cuatro operaciones arit- méticas, además de poder hacer comparaciones y opcionalmente raíces cuadradas. Ini- cialmente fue concebida como una máquina diferencial curvada sobre sí misma, en una disposición generalmente circular, con el almacenamiento mayor saliendo por uno de sus lados. Al igual que la Unidad de Procesamiento Central (CPU: Central Process Unit) de una computadora moderna, el molino dependería de sus propios procedimientos internos, que serían almacenados en la forma de clavijas insertadas en tambores rotato- rios llamados “barriles”, para llevar a cabo algunas de las instrucciones más complejas que el programa del usuario pueda especificar.

El lenguaje de programación que utilizarían los usuarios era similar a los modernos lenguajes ensambladores. Y el lenguaje concebido permitía realizar bucles y bifurca- ciones. Se utilizaron tres tipos diferentes de tarjetas perforadas: uno para operaciones aritméticas, uno para constantes numéricas, y otro para las operaciones de carga y al- macenamiento, transfiriendo números del almacenamiento a la unidad aritmética o de regreso. Había tres lectores separados para los tres tipos de tarjetas. Babbage desarrolló unas dos docenas de programas para la máquina analítica entre 1837 y 1840, y un programa posteriormente. Estos programas procesaban polinomios, fórmulas iterativas, la eliminación de Gauss, y los números de Bernoulli. [35] 12 1. MARCO TEÓRICO

1.1.3. La Primer Programadora

En 1840, Babbage fue invitado a dar un seminario en la Universidad de Turín sobre su máquina analítica. Luigi Federico Menabrea, un joven ingeniero italiano, y futuro Primer Ministro de Italia, escribió la conferencia de Babbage en francés, y esta trans- cripción se publicó posteriormente en 1842. [85]

Un amigo de Babbage, el científico e inventor británico Charles Wheatstone encargó a la matemática y escritora británica que tradujera el documento de Me- nabrea al inglés. Durante casi el año que le llevó traducirlo, ella también complementó el escrito con notas propias, que fueron añadidas a la traducción original. [49]

Casi un siglo después, la máquina analítica de Babbage sería reconocida como el modelo primigenio de una computadora, y las notas de Lovelace como la descripción de una computadora y el software. En sus notas, Lovelace describe un algoritmo para que la máquina analítica calcule los números de Bernoulli. Éste se considera como el primer algoritmo específicamente adaptado para su aplicación en una computadora, y Ada ha sido frecuentemente citada como la primera programadora por este motivo. La máquina analítica no llegó a completarse por lo que su código nunca pudo probarse.

Lovelace enfatizó en sus notas la diferencia entre la máquina analítica y las anteriores máquinas de cálculo, particularmente en su capacidad de ser programada para resolver problemas de cualquier complejidad. Se dio cuenta de que el potencial del dispositivo se extendía mucho más allá del mero procesamiento de números.

Ella escribió:

“[La Máquina Analítica] podría actuar sobre otras cosas además de números, entre los que se encuentran objetos cuyas relaciones fundamentales mutuas podrían ser expresadas por las de la ciencia abstracta de las operaciones, las cuales deben ser también susceptibles de adaptaciones a la acción tanto de la notación del funcionamiento como del mecanismo de la máquina. Suponiendo, por ejemplo, que las relaciones fundamentales entre los sonidos de los tonos en la ciencia de la armonía y de la composición musical fueran susceptibles de dicha expresión y adaptaciones, la máquina podría componer piezas de música elaboradas y científicas con cualquier grado de complejidad o dimensión”. [31]

Este análisis fue un importante desarrollo de las ideas previas sobre las capacidades de los dispositivos de computación, y se anticipó a las implicaciones de la informática moderna cien años antes de que se hicieran realidad. 1.1. ORIGEN DE LOS LENGUAJES DE PROGRAMACIÓN 13

1.1.4. Tarjetas Perforadas

Después de Babbage, hubo una pérdida temporal de interés en las computadoras digita- les automáticas. Entre 1850 y 1900 se hicieron grandes avances en la física matemática, y se llegó a saber que los fenómenos dinámicos más observables puede ser identificados mediante ecuaciones diferenciales (lo que significa que la mayoría de los eventos que ocurren en la naturaleza pueden medirse o describirse en base a una u otra ecuación), de modo que contar con medios fáciles para su cálculo sería de gran ayuda.

Por otra parte, desde un punto de vista práctico, la disponibilidad de la energía de vapor provocó que la fabricación (calderas), el transporte (máquinas de vapor y barcos), y el comercio prosperaran y diera lugar a un período con una gran cantidad de logros de ingeniería. El diseño de los ferrocarriles, y la fabricación de barcos de vapor, las fábricas textiles, y los puentes requerían del cálculo diferencial para determinar cosas tales como el centro de gravedad, el centro de flotabilidad, el momento de inercia, y la distribución de tensiones.

Incluso para evaluar la potencia de salida de un motor de vapor se necesitaba de la integración matemática. Por lo tanto se fue generando la gran necesidad de una máquina que pudiera realizar rápidamente muchos cálculos repetitivos.

En Enero de 1889, la Oficina de Patentes de Estados Unidos autorizaba la patente de un ingeniero e inventor estadounidense con grado en Ingeniería de Minas por la Universidad de Columbia, de nombre Herman Hollerith.

Su patente ostentaba el título de: “El Arte de Compilar Estadísticas”, y decía:

“El método aquí descrito para la compilación de estadísticas, consiste en el registro de elementos estadísticos separados relacionados con el individuo me- diante agujeros o combinaciones de agujeros perforados en hojas de un material eléctricamente no conductor, y teniendo una relación específica entre sí y con un estándar, y a continuación, el recuento o totalización de tales elementos estadísticos por separado o en combinación por medio de contadores mecánicos accionando por electroimanes los circuitos a través de los cuales son contro- lados por las láminas perforadas, sustancialmente como y para el propósito establecido”. [71]

Siete años antes, en 1882, Hollerith había comenzado a dar clases de Ingeniería Mecá- nica en el Instituto de Tecnología de Massachusetts (MIT), donde también realizó sus primeros experimentos con tarjetas perforadas. Cuando presentó su solicitud de patente, ya había dejado la enseñanza y estaba trabajando para la Oficina del Censo de Estados 14 1. MARCO TEÓRICO

Unidos.

Ahí desarrolló un mecanismo que utilizaba conexiones eléctricas que activaban un con- tador, registrando la información. Partió de una idea clave, inspirada originalmente por la forma en que los boletos de ferrocarril permitían que el verificador codificara una descripción aproximada de la apariencia del pasajero (“cabello claro, ojos oscuros, na- riz grande, etc.”) con base en las ubicaciones de los agujeros en el boleto. Hollerith determinó que se podrían contar y ordenar mecánicamente los datos si se perforaban en lugares específicos de una tarjeta, en los renglones y columnas que hoy en día nos resultan tan familiares. [98]

Su invención le valió la obtención del título de doctorado por la Universidad de Co- lumbia, además de una serie de contratos con oficinas de censos y aseguradoras en todo el mundo, y la creación de su propia empresa llamada The Tabulating Machine Company, que más adelante, en 1911, se fusionó con otras tres compañías para formar la Computing-Tabulating-Recording Company, finalmente renombrada en 1924 como International Business Machines Corporation o IBM.

IBM fabricó y comercializó una variedad de máquinas de registro unitario para la crea- ción, clasificación y tabulación de tarjetas perforadas hasta la década de 1950. En comparación con las máquinas de hoy, estas computadoras eran lentas, procesando por lo general de 50 a 220 tarjetas por minuto, con cada tarjeta conteniendo unos 80 números decimales (caracteres). En ese momento, sin embargo, las tarjetas perforadas fueron un gran paso hacia adelante. Proporcionaron un medio para la entrada, pro- cesamiento y salida de datos; y también para el almacenamiento de memoria a gran escala. Durante más de 50 años después de su primer uso, las máquinas de tarjetas perforadas hicieron la mayor parte de la primera informática empresarial del mundo, y una cantidad considerable del trabajo de computación científica. 1.1. ORIGEN DE LOS LENGUAJES DE PROGRAMACIÓN 15

1.1.5. Enigma

En 1918, poco antes del fin de la Primera Guerra Mundial, un ingeniero eléctrico alemán llamado Arthur Scherbius patentó una máquina para el cifrado de mensajes basada en una combinación de subsistemas mecánicos y eléctricos. El subsistema mecánico de la máquina se componía de un teclado, un conjunto de discos llamados rotores dispuestos de forma adyacente a lo largo de un eje de rotación y uno de varios componentes paso a paso para activar al menos un rotor con cada pulsación de una tecla. Las partes mecánicas actuaban de una manera tal que formaban un circuito eléctrico variable. Cuando se pulsaba una tecla, uno o más rotores se movían para formar una nueva configuración del rotor, y se completaba un circuito. La corriente fluía a través de diversos componentes en la nueva configuración, y en última instancia, iluminando una lámpara de visualización, que mostraba la letra de salida. [36] [116]

Por ejemplo, al cifrar un mensaje que comenzara con “TEX...”, el operador primero pulsaba la tecla ‘T’, y podría iluminarse la lámpara con la letra ‘D’, por lo que la ‘D’ sería la primera letra del texto cifrado. El operador a continuación pulsaba la ‘E’, y luego la ‘X’ de la misma manera, y así sucesivamente. El receptor del mensaje codificado necesitaba conocer la configuración exacta de los rotores al momento de codificarlo con el fin de reconstituir el mensaje original.

Scherbius comenzó a comercializar la máquina en 1923 bajo el nombre de “Enigma”, con la esperanza de que las empresas comerciales se interesaran en las comunicaciones seguras. Al cabo de tres años fue adoptada por la Marina Alemana, seguida por el Ejército en 1928 y la Fuerza Aérea en 1933. Con los años la máquina original se fue haciendo más complicada conforme los expertos alemanes en códigos le añadieron conectores con circuitos electrónicos.

Gran Bretaña y sus aliados comprendieron desde un principio los problemas planteados por esta máquina en 1931, cuando un espía alemán les permitió hacerse de fotografías de los manuales de operación de Enigma. Inicialmente, sin embargo, ni los criptoana- listas franceses ni los británicos pudieron lograr avances para romper el cifrado de Enigma. Fue sólo hasta después de que entregaron los detalles a la Agencia Polaca de Cifrado que hubo un avance. Ayudados por sus relaciones cercanas con la industria de la ingeniería alemana, los polacos lograron reconstruir una máquina Enigma completa, con cableado interno, para intentar descifrar los mensajes de las fuerzas alemanas entre 1933 y 1938. [62] 16 1. MARCO TEÓRICO

1.1.6. Máquina Universal

El 1 de septiembre de 1939, y usando como pretexto un ataque simulado por ellos mismos a un puesto fronterizo, las tropas de Alemania invadieron el territorio de Polo- nia. Fue el detonante de la Segunda Guerra Mundial en Europa. Los alemanes estaban convencidos de que los mensajes generados por Enigma no se podían descifrar, por lo que utilizaron la máquina para todo tipo de comunicaciones en el campo de batalla, en el mar, en el cielo y, significativamente, dentro de sus servicios secretos. Estas iban desde señales de alto nivel, tales como informes detallados de situación preparados por los generales en los frentes de batalla, y las órdenes firmadas por el propio Hitler, hasta las minucias importantes de la guerra como informes meteorológicos e inventarios de los contenidos de los barcos de suministro. [67]

Varios meses antes, y con una invasión alemana inminente, los polacos optaron por compartir sus secretos con los británicos, y entonces una fea mansión Victoriana en Bletchley Park, Buckinghamshire, se convirtió en el cuartel general durante la guerra de los mejores descifradores de Gran Bretaña.

Entre esos grandes descifradores se encontraba el matemático y científico británico Alan Mathison Turing, quien en 1931 y con tan sólo 19 años ya había obtenido una beca para el King’s College en Cambridge, donde obtuvo el grado de Matemáticas con los más altos honores. Y aunque parecía que Turing ya estaba encaminado a una carrera distinguida en la matemática pura, su inusual interés en encontrar usos prácticos para las ideas matemáticas abstractas lo empujaron hacia una dirección completamente diferente. [33]

Para 1936, Turing ya había publicado un documento que actualmente se reconoce como la piedra angular de la informática.

En él, Turing analizó lo que significaba para un ser humano seguir un método o pro- cedimiento definido para realizar una tarea, y determinó que tenía que encontrar una manera de conseguir que las máquinas entendieran instrucciones como “sumar”, “res- tar”, “multiplicar”, “dividir”, y así sucesivamente... de la misma manera que lo hacen los humanos. [112]

En otras palabras, tenía que encontrar una manera de traducir instrucciones como éstas en un lenguaje que las máquinas pudieran entender. Y con una lógica impecable y perfecta, Turing hizo exactamente eso. 1.1. ORIGEN DE LOS LENGUAJES DE PROGRAMACIÓN 17

Estableció su razonamiento inicial basado en el concepto de una cinta de papel con lo que a simple vista podría parecernos tan sólo una serie aleatoria de ceros y unos:

0001001110110100000010010000000111101111000000001101000111001011001110010

Pero resulta que lo que para nosotros los humanos no tendría un significado en parti- cular, para una máquina de computación le representaría todo un preciso conjunto de instrucciones que podrían ser leídas una por una, y que le dirían a la máquina que se comportara de una manera determinada. Entonces, al traducir los ceros y unos de la cinta en instrucciones, la máquina sería capaz de entender el proceso que se requiere llevar a cabo, esto es, de manera equivalente a lo que entendería una computadora humana:

SUMAR 3 + 7

Esta cinta de papel que imaginó Turing es lo que ahora llamaríamos la memoria de la computadora. Pero Turing llegó todavía más lejos. Él se dio cuenta de que alimentarle instrucciones a la máquina de esta manera tendría una consecuencia sorprendente. Significaba que sólo se necesitaría una máquina para realizar casi cualquier tarea que se pudiera imaginar. [24]

Es un concepto muy simple. Con el fin de conseguir que la máquina hiciera algo nuevo, todo lo que se tendría que hacer era alimentarla con un nuevo conjunto de instrucciones, de información nueva. Cuanto más se quisiera que hiciera la máquina, cuanto más larga tendría que ser la cinta. Memorias más grandes podrían contener múltiples capas de instrucciones complejas para procesar y ordenar cualquier tipo de información posible.

Esta idea se conoce como la Máquina Universal de Turing, y que en realidad es el modelo de una computadora de propósito general. Turing fue una gran influencia en el desarrollo de la informática teórica, al proporcionar una formalización de los conceptos de algoritmo y computación. Por ello, Turing es ampliamente considerado como el padre de la ciencia de la informática teórica y también de la inteligencia artificial. [111]

Al día de hoy se utiliza el término Turing Completo al definir la capacidad de un sistema basado en instrucciones para simular una Máquina de Turing. Un lenguaje de programación que sea Turing Completo es teóricamente capaz de expresar todas las tareas realizables por las computadoras; casi todos los lenguajes de programación son Turing Completos. [110] 18 1. MARCO TEÓRICO

1.1.7. Bombe

En Bletchley Park, una vez que dio comienzo la guerra, Turing diseñó un dispositivo electromecánico de 2.1 metros de alto y ancho, y 0.61 metros de profundidad, con tres arreglos horizontales de 36 tambores, cada uno de los cuales se podían configurar en cualquiera de 26 posiciones (una por cada letra del alfabeto). El propósito de este dispositivo era fundamentalmente el de ser una máquina anti-Enigma, y fue nombrada “Bombe”. [45]

Sus bombes convirtieron a Bletchley Park en una fábrica de ruptura de códigos. Y para 1943 las máquinas de Turing estaban descifrando un asombroso total de 84,000 mensajes de Enigma cada mes (dos mensajes por minuto). [44]

Turing personalmente se encargó de romper el tipo de Enigma que fue utilizado por los submarinos que atacaban a los convoyes mercantes en el Atlántico Norte.

Fue una contribución crucial. Los convoyes partían de América del Norte llenos de grandes cargamentos de suministros esenciales para Gran Bretaña, pero los torpedos de los submarinos estaban hundiendo a tantos barcos que los analistas de Churchill aseguraban que Gran Bretaña pronto se moriría de hambre.

Churchill diría más tarde:

“La única cosa que siempre realmente me asustó durante la guerra fue la amenaza de los submarinos”. [21]

Justo a tiempo, Turing y su equipo fueron capaces de descifrar las comunicaciones entre los submarinos y sus controladores en Europa. Con los submarinos revelando sus posiciones, los convoyes podrían esquivarlos a través de la extensa área de desperdicios en que se había convertido el Atlántico.

Algunos historiadores estiman que la operación masiva de descifrado en Bletchley Park, en especial la que significó la ruptura del código Enigma de los submarinos, acortó la guerra en Europa tanto como de dos a cuatro años. Porque si Turing y su equipo no hubieran debilitado las posiciones de los submarinos en el Atlántico Norte, la invasión Aliada de Europa en 1944 (los desembarcos del día D) podrían haberse retrasado quizás por alrededor de un año o incluso por más tiempo, ya que el Atlántico Norte era la ruta por la que tenían que viajar las municiones, el combustible, los alimentos y las tropas con el fin de llegar a Gran Bretaña desde América.

En una estimación conservadora, cada año los combates en Europa traían en promedio alrededor de siete millones de muertes, por lo que la importancia de la contribución de 1.1. ORIGEN DE LOS LENGUAJES DE PROGRAMACIÓN 19

Turing se puede cuantificar más o menos en términos del número de vidas adicionales que podrían haberse perdido si no hubiera logrado lo que hizo. Es decir, que si el código Enigma de los submarinos no se hubiera descifrado, y la guerra hubiera continuado durante otros dos o tres años, otras 14 a 21 millones de personas podrían haber muerto. Estas cifras colosales nos dan una idea de la magnitud de la contribución de Turing. [117]

1.1.8. ENIAC

El inicio de la Segunda Guerra Mundial produjo una gran necesidad de capacidades de cómputo, especialmente para los militares. El Ejército de Estados Unidos estaba desarrollando un gran número de armas nuevas para colaborar con el esfuerzo de guerra y requería de los cálculos necesarios para generar sus correspondientes tablas de trayectoria y otros datos esenciales.

Por ello, en 1941, los principales esfuerzos de investigación y desarrollo en la Escuela Moore de Ingeniería Eléctrica, perteneciente a la Universidad de Pennsylvania, estaban enfocados en la balística.

Ese mismo año, el Físico John Mauchly ingresó a la Escuela Moore para tomar un curso de electrónica bélica y posteriormente aceptó un puesto de profesor. Allí conoció a un recién graduado de la misma escuela, el Ingeniero Eléctrico John Presper Eckert. Eckert convenció a Mauchly con la idea de que las válvulas de vacío se podrían volver fiables si se aplicaban las prácticas de ingeniería apropiadas. [78] [81]

En 1942 Mauchly elaboró y presentó una propuesta para la construcción de una compu- tadora electrónica de propósito general. La propuesta, que circuló dentro de la Escuela Moore (pero su importancia no fue reconocida inmediatamente), hizo hincapié en la enorme ventaja de velocidad que podría obtenerse mediante el uso de la electrónica digital, sin partes móviles. El teniente Herman Goldstine, quien era el enlace entre el Ejército de Estados Unidos y la Escuela Moore, recogió la idea y pidió a Mauchly que escribiera una propuesta formal. En abril de 1943, el Ejército firmó un contrato con la Escuela Moore para que construyera el Computador e Integrador Numérico Elec- trónico (ENIAC: Electronic Numerical Integrator And Computer). Mauchly, Eckert y otros ingenieros talentosos participaron en lo que se conoció como el confidencial “Proyecto PX”. Mauchly dirigió el diseño conceptual, mientras que Eckert lideró la ingeniería de hardware de ENIAC.

ENIAC contenía 17,468 válvulas de vacío, 7,200 diodos de cristal, 1,500 relevadores, 20 1. MARCO TEÓRICO

70,000 resistencias, 10,000 condensadores y aproximadamente 5,000,000 de conexiones soldadas a mano. Pesaba más de 27 toneladas, medía 2.4 m. de alto por, 0.9 m. de fondo y 30 m. de longitud, ocupaba una superficie de 167 m2 y consumía 150 kW de electricidad. Utilizaba las tarjetas perforadas de IBM para los procesos de entrada y salida.

Gracias a sus cálculos de alta velocidad, ENIAC podía resolver problemas que antes no habían podido ser resueltos. Era aproximadamente mil veces más rápido que la tecnología existente. Podía sumar 5,000 números o hacer 357 multiplicaciones de 10 dígitos en un segundo.

ENIAC podía programarse para realizar secuencias y bucles de sumas, restas, multi- plicaciones, divisiones, raíces cuadradas, funciones de entrada y salida, bifurcaciones condicionales y subrutinas. La tarea de tomar un problema y asignárselo a la máquina era compleja, y por lo general tomaba semanas. Después de que el programa se solucio- naba en papel, el proceso de ingresar el programa en ENIAC mediante la manipulación de sus interruptores y cables podría tomar días. Esto era seguido por un período de verificación y depuración, ayudado por la capacidad de ejecutar el programa paso a paso. [61]

Seis mujeres con grados en Matemáticas fueron las principales programadoras de ENIAC: Betty Snyder Holberton, Jean Jennings Barik, Kay McNulty Mauchly Antonelli, Marlyn Wescoff Meltzer, Ruth Lichterman Teitelbaum y Frances Bilas Spence. Ellas no sólo determinaron cómo introducir programas a ENIAC, sino que también desarro- llaron una comprensión de su funcionamiento interno. Las programadoras hacían la depuración de problemas arrastrándose dentro de la enorme estructura para localizar malas conexiones y válvulas dañadas. [40] [65] [77] [83] [87] [99]

En lugar de haber tenido que aprender un lenguaje de programación, las seis programa- doras tuvieron que estudiar los planos de ENIAC y su estructura física para determinar cómo manipular sus interruptores y cables. Aunque sus contemporáneos consideraban que programar era tan sólo una tarea de oficina y por lo tanto no hicieron un reconoci- miento público del impacto que tuvieron las programadoras en el éxito de su operación ni al momento de hacer el anuncio de ENIAC, en años posteriores Snyder, Jennings, McNulty, Wescoff, Lichterman y Bilas, han recibido un mayor reconocimiento por sus contribuciones a la informática. [22] 1.1. ORIGEN DE LOS LENGUAJES DE PROGRAMACIÓN 21

1.1.9. EDVAC y ACE

Las primeras máquinas de computación tenían los programas fijos. Por ejemplo, una calculadora de escritorio es una computadora de programa fijo. Puede calcular opera- ciones matemáticas básicas, pero no puede utilizarse como un procesador de textos o como una consola de videojuegos. Cambiarle el programa a una máquina de programa fijo requiere cambios en el cableado, en la estructura, o en el diseño de la máquina. Las primeras computadoras no eran tanto “programadas”, sino que más bien eran “dise- ñadas”. La “reprogramación”, cuando era posible en absoluto, era un proceso laborioso, partiendo de diagramas de flujo y notas en papel, seguido de detallados diseños de in- geniería, y a continuación, el arduo proceso de volver a cablear y reconstruir físicamente la máquina.

Con la propuesta de la computadora de programa almacenado esto cambió. Una compu- tadora de programa almacenado incluye en su diseño un conjunto de instrucciones, y puede almacenar en la memoria un conjunto de instrucciones (programa) que describen en detalle el proceso de cálculo. [104]

La base teórica para la computadora de programa almacenado había sido publicada por en su artículo de 1936. En 1945 Turing se incorporó al Laboratorio Nacional de Física (NPL: National Physical Laboratory) en Gran Bretaña y comenzó a trabajar en el desarrollo de una computadora digital electrónica de programa almacenado. Su informe de 1945 “Propuesta de Calculadora Electrónica” fue la primera especificación para un dispositivo de este tipo. [91]

Mientras tanto, el Matemático y Físico distribuyó en la Escuela Moore su primer borrador de un informe sobre la Computadora Electrónica Auto- mática Variable Discreta (EDVAC: Electronic Discrete Variable Automatic Computer) en 1945. Aunque sustancialmente similar al diseño de Turing y conteniendo comparativa- mente pocos detalles de ingeniería, la arquitectura de computadores que presentó se llegó a conocer como la “Arquitectura von Neumann”. En 1946, Turing presentó un documento más detallado al Comité Ejecutivo del Laboratorio Nacional de Física, pro- duciendo el primer diseño razonablemente completo de una computadora de programa almacenado, un dispositivo al que llamó el Motor de Computación Automática (ACE: Automatic Computing Engine). Sin embargo, el diseño del EDVAC mejor conocido de John von Neumann, quien conocía el trabajo teórico de Turing, recibió más publicidad, a pesar de su carácter incompleto y la cuestionable falta de acreditación del origen de algunas de las ideas. [28] [38] [60] [82] [114]

Turing estuvo consciente de que la velocidad y el tamaño de la memoria eran cruciales 22 1. MARCO TEÓRICO

y propuso una memoria de alta velocidad de lo que hoy se llamaría 25 KB, accedida a una velocidad de 1 MHz. El ACE implementaba llamadas a subrutinas, mientras que el EDVAC no lo hacía, y el ACE también utilizó Instrucciones Abreviadas de Compu- tadora (ACI: Abbreviated Computer Instructions), una forma temprana de lenguaje de programación.

A partir de ese momento, las computadoras de programa almacenado tuvieron una rápida evolución conforme sus diferentes componentes obtenían mejoras en velocidad, capacidades de almacenamiento, miniaturización; pero lo más importante: en disminu- ción de costos. [29] [66] [73] [109] [115] 1.2. PRIMEROS LENGUAJES DE ALTO NIVEL 23

1.2. Primeros Lenguajes de Alto Nivel

Algo que caracterizó a esas primeras computadoras modernas accionadas por energía eléctrica, y creadas durante la década de 1940, es que su velocidad y capacidad de memoria eran muy limitadas. Ello obligaba a los programadores a tener que escribir los programas en Lenguaje Ensamblador ajustado a mano, lo que requería una gran cantidad de esfuerzo intelectual y era propenso a errores. [37]

El lenguaje ensamblador es un “Lenguaje de Programación de Bajo Nivel” para compu- tadoras, en el que hay una correspondencia muy fuerte (por lo general de uno a uno) entre el lenguaje y la arquitectura de instrucciones del código máquina. Cada len- guaje ensamblador es específico de una arquitectura de computadora en particular, a diferencia de la mayoría de los lenguajes de programación de alto nivel, que suelen ser portables a través de múltiples arquitecturas, pero requieren ser interpretados o compilados. [97]

El concepto de “Lenguaje de Programación de Alto Nivel” hace referencia a un nivel más alto de abstracción que el lenguaje ensamblador. En lugar de tratar con registros, direcciones de memoria y pilas de llamadas, los lenguajes de alto nivel se ocupan de variables, matrices, objetos, aritmética compleja o expresiones booleanas, subrutinas y funciones, bucles, hilos, cierres, y otros conceptos abstractos de la informática, con un mayor enfoque en la facilidad de uso que en la eficiencia óptima del programa. A diferencia de los lenguajes ensambladores de bajo nivel, los lenguajes de alto nivel tienen pocos, si es que alguno, elementos del lenguaje que se traduzcan directamente en códigos nativos de operación de una máquina. [72]

1.2.1. Short Code

Short Code (Código Corto) fue uno de los primeros lenguajes de alto nivel que se haya desarrollado para una computadora electrónica. Fue propuesto por John Mauchly para su uso en el ENIAC en 1949, y fue adaptado durante los siguientes cuatro años para su uso en los equipos BINAC, UNIVAC I y UNIVAC II, donde también se le conoció como Brief Code (Código Breve).

A diferencia del código máquina, las instrucciones en Short Code representaban expre- siones matemáticas en lugar de instrucciones para la máquina. Las expresiones no eran representadas de forma directa y se requería un proceso de conversión manual. Los elementos de una expresión eran representados por códigos de dos caracteres y luego 24 1. MARCO TEÓRICO

divididos en grupos de 6 códigos con el fin de que se ajustaran a las palabras de 12 bytes que utilizaban las computadoras BINAC y UNIVAC. [86]

Además de la aritmética básica, Short Code permitía ramificaciones y llamadas a una biblioteca de funciones. Funcionaba de una forma conocida como programación auto- mática, en donde el código fuente no se compilaba sino que se ejecutaba a través de un intérprete para simplificar el proceso de programación. Eso sí, el tiempo de ejecución era alrededor de 50 veces más lento que el código máquina. [100]

1.2.2. FORTRAN

A finales de 1953, el matemático estadounidense John Warner Backus presentó una propuesta a sus superiores en IBM para desarrollar una alternativa más práctica que el lenguaje ensamblador utilizado para programar su computadora central IBM 704. [79]

Se trataba de un lenguaje de programación de propósito general especialmente adecua- do para el cálculo numérico y la computación científica. Llevaba por nombre “FORTRAN”, derivado de “FORmula TRANslation System” (“Sistema Traductor de Fórmulas”).

Cuatro años más tarde, Backus entregaba el primer compilador FORTRAN, que resultó ser el primer compilador con optimización integrada, ya que los usuarios eran reacios a utilizar un lenguaje de programación de alto nivel a menos que su compilador pudiera generar un desempeño comparable con el del lenguaje ensamblador codificado a mano.

FORTRAN reducía por un factor de 20 el número de sentencias de programación ne- cesarias para hacer funcionar una máquina, y por ello rápidamente ganó aceptación. El lenguaje fue ampliamente adoptado por los científicos para escribir programas nu- méricamente intensivos, lo que también alentó a los autores de compiladores para que produjeran compiladores que generasen código más rápido y más eficiente.

De manera significativa, la creciente popularidad de FORTRAN estimuló a que los demás fabricantes de computadoras también proporcionasen compiladores FORTRAN para sus máquinas, de modo que para 1963 ya existían más de 40 compiladores FORTRAN. Por estas razones, FORTRAN es considerado como el primer lenguaje de programación utilizado ampliamente y con soporte a través de una variedad de arquitecturas de computadora.

Años más tarde, diría en una entrevista lo que le motivó a crear FORTRAN:

“Gran parte de mi trabajo tiene su origen en el hecho de que soy perezoso. No me gustaba escribir programas, así que, cuando estaba trabajando en el IBM 1.2. PRIMEROS LENGUAJES DE ALTO NIVEL 25

701, escribiendo programas para el cálculo de trayectorias de misiles, fue que comencé a trabajar en un sistema de programación para que fuera más fácil la escritura de programas”. [64]

El desarrollo de FORTRAN se dio de manera simultánea con la evolución temprana de la tecnología de compilación, y muchos avances en la teoría y el diseño de compiladores fueron motivados específicamente por la necesidad de generar un código más eficiente para los programas hechos en FORTRAN.

1.2.3. FLOW-MATIC y COBOL

A finales de la década de 1950, los usuarios y fabricantes de computadoras se encon- traban cada vez más preocupados por el aumento en el costo de la programación. Para 1959, la programación de cualquier sistema de procesamiento de datos podría costar US$ 800,000 en promedio; y la labor de traducir esos mismos programas para que se ejecutasen en un hardware nuevo costaría US$ 600,000. En una época en que los nuevos lenguajes de programación estaban proliferando a un ritmo cada vez mayor, comenzó a expandirse la idea de que si se utilizara un lenguaje común orientado a los negocios, la conversión sería mucho más barata y más rápida.

En abril de 1959, esa idea se puso en acción. En una reunión informal en la Universi- dad de Pennsylvania en Filadelfia, un pequeño grupo de fabricantes de computadoras, grandes usuarios y académicos pidieron al Departamento de Defensa que encabezase el esfuerzo, ya que también a ellos les preocupaba poder tener la capacidad de correr los mismos programas de procesamiento de datos en equipos diferentes. FORTRAN, el único lenguaje dominante en esos momentos, carecía de las características que se necesitan para escribir este tipo de programas.

Al mes siguiente, el Departamento de Defensa convocó la primera Conferencia de Lenguajes para Sistemas de Datos (CODASYL: Conference on Data Systems Languages), que reunió a expertos informáticos de la industria y el gobierno para discutir, entre otros temas, acerca de un lenguaje común para negocios. Entre esos expertos se encontraba la Matemática y Almirante de la Marina Estadounidense . [51] [70]

Desde 1953, Hopper ya se había dado cuenta que los clientes de sistemas para el proce- samiento de datos empresariales no se sentían cómodos con la notación matemática de los lenguajes disponibles. Ella llegó a la conclusión de que los problemas de tratamiento de datos deberían expresarse utilizando palabras clave en idioma Inglés. A principios de 1955, ella y su equipo escribieron la especificación de un lenguaje de programación 26 1. MARCO TEÓRICO

con esas características e implementaron un prototipo. El lenguaje recibió el nombre de FLOW-MATIC, y el primer compilador se puso a disposición del público a principios de 1958. [63]

En CODASYL, Hopper se desempeñó como asesora técnica en el comité que elabo- ró la definición del nuevo lenguaje COBOL, acrónimo de “COmmon Business-Oriented Language” (“Lenguaje Común Encaminado a los Negocios”). El nuevo lenguaje en reali- dad terminó siendo una extensión del lenguaje FLOW-MATIC de Hopper con algunas ideas tomadas del lenguaje equivalente de IBM, COMTRAN. Concebido originalmen- te como un recurso provisional, el Departamento de Defensa con prontitud obligó a los fabricantes de computadoras a que lo proveyeran, lo que resultó en su adopción generalizada.

Los informáticos académicos no estaban interesados en general en las aplicaciones de negocio cuando COBOL fue creado y no participaron en su diseño. Efectivamente CO- BOL fue diseñado desde el principio como un lenguaje de programación para los hom- bres de negocios, con énfasis en las entradas y salidas, cuyos tipos de datos sólo eran números y cadenas de texto. COBOL ha recibido muchas críticas durante toda su vida, por tener un excesivo nivel de detalle, por su proceso de diseño y por tener un po- bre soporte para la programación estructurada, lo que ha resultado en la creación de programas monolíticos e incomprensibles.

Hoy en día COBOL sigue siendo ampliamente utilizado en aplicaciones heredadas fun- cionando en computadoras centrales, tales como trabajos a gran escala de procesamiento por lotes y de procesamiento de transacciones. Sin embargo, debido a la disminución de su popularidad y al retiro de los programadores con experiencia en COBOL, los programas han sido migrados a nuevas plataformas, reescritos en lenguajes modernos o reemplazados con paquetes de software. La mayoría de la programación en COBOL es ahora meramente para mantener las aplicaciones existentes. [50]

1.2.4. BASIC

Antes de mediados de la década de 1960, las únicas computadoras eran unidades cen- trales. Los usuarios enviaban sus procesos a los operadores de computadoras en tarjetas perforadas o medios similares. La computadora los almacenaba, y a continuación, utili- zaba un sistema de procesamiento por lotes para ejecutar toda esa cola de trabajos uno tras otro; permitiendo así tener altos niveles de utilización de estas costosas máquinas. A medida que se fue incrementando el rendimiento del hardware de computación durante la década de 1960, también se fue desarrollando el multi-procesamiento. Esto permitía 1.2. PRIMEROS LENGUAJES DE ALTO NIVEL 27 ejecutar en conjunto una mezcla de trabajos por lotes, pero la verdadera revolución fue el desarrollo del tiempo compartido.

El tiempo compartido permitía que varios usuarios remotos compartieran el uso de la computadora, interactuando con el equipo desde terminales con teclados e impresoras de teletipo, y más tarde pantallas de visualización, de una forma muy similar en la que se utilizarían más tarde las computadoras de escritorio o computadoras personales. [54]

El 1 de mayo de 1964 a las 4 de la mañana, en la computadora central de la Uni- versidad Darmouth en Hanover, New Hampshire, daba inicio la ejecución del primer programa en un lenguaje nuevo llamado BASIC, acrónimo de “Beginners All-purpose Symbolic Instruction Code” (“Código de Instrucciones Simbólicas de Todo Propósito para Principiantes”). Sus creadores fueron el húngaro-estadounidense John George Kemeny y el estadounidense Thomas Eugene Kurtz, ambos profesores, matemáticos, e informá- ticos. [80] [107]

En ese preciso instante, Kemeny y Kurtz no imaginaban que era el comienzo de algo mucho más grande. Ellos simplemente esperaban que fuera de ayuda para que los estudiantes aprendieran algo acerca de los equipos que estaban usando. Ambos se aseguraron de que su invención estuviera a disposición del público de inmediato y no obtuvieron ninguna ganancia real de ella. Los derechos de propiedad de BASIC le pertenecían la Universidad Dartmouth; sin embargo, la Universidad también hizo que BASIC estuviera disponible y libre para cualquiera que deseara utilizarlo. [53]

Ellos querían permitir que los estudiantes de campos distintos a la ciencia y las mate- máticas usaran computadoras. En ese momento, casi todo el uso que se les daba a las computadoras requería del conocimiento en la escritura de software personalizado, que era algo que sólo los científicos y matemáticos tendían a aprender. Además, ser capaz de utilizar una computadora para apoyar la enseñanza y la investigación era bastante novedoso en ese momento.

Desde su aparición, y hasta principios de la década de 1970, BASIC llegó a ser bastante popular al venir integrado de fábrica en las nuevas minicomputadoras de empresas como DEC y HP.

La introducción de las primeras microcomputadoras a mediados de la década de 1970 fue el inicio de un crecimiento explosivo para BASIC. Tenía la ventaja de que era bastante bien conocido por los jóvenes diseñadores y aficionados a las computadoras que adquirieron un interés por las microcomputadoras.

BASIC fue uno de los pocos lenguajes que era a la vez lo suficientemente de alto nivel 28 1. MARCO TEÓRICO

como para poder ser utilizado por aquellos que no tenían la formación necesaria y lo suficientemente pequeño como para caber en las microcomputadoras del momento, convirtiéndose así, en el lenguaje de programación estándar de facto en las primeras microcomputadoras. [39] 1.3. LENGUAJES ESTRUCTURADOS 29

1.3. Lenguajes Estructurados

En 1975, el holandés Edsger Wybe Dijkstra, físico teórico, científico de la computación y un férreo detractor de BASIC, hizo la siguiente afirmación:

“Es prácticamente imposible enseñarles buena programación a los estudian- tes que ya han tenido una exposición previa al BASIC: como programadores potenciales ellos ya están mentalmente mutilados sin esperanza alguna de re- generación”. [39]

Dijkstra fue uno de los miembros más influyentes de la generación fundadora de la informática, y ayudó a dar forma a la nueva disciplina, desde la perspectiva de la ingeniería hasta la perspectiva teórica. Muchos de sus trabajos son la fuente de nuevas áreas de investigación. Varios conceptos y problemas que ahora son estándares en la informática fueron identificados por primera vez por Dijkstra y/o tienen nombres acuñados por él.

Sus contribuciones fundamentales cubren diversas áreas de la informática, incluyendo la construcción de compiladores, sistemas operativos, sistemas distribuidos, programación secuencial y concurrente, paradigmas y metodologías de la programación, investigación de lenguajes de programación, diseño de programas, desarrollo de programas, verifica- ción de programas, los principios de la ingeniería de software, algoritmos de grafos, y bases filosóficas de la informática y la programación de computadoras.

En las décadas de 1950 y 1960, la programación de computadoras no era reconocida como una disciplina académica, y a diferencia de la física, no disponía de conceptos teóricos o de sistemas de codificación.

Dijkstra fue un gran impulsor para lograr que la programación de computadoras fuera aceptada como una disciplina científica. Su sólida formación en matemáticas y física le llevó a la aplicación de disciplinas similares a la lógica y la metodología matemáticas en la programación de computadoras. [59]

En 1968, la programación de computadoras estaba en un estado de crisis. Dijkstra per- tenecía a un pequeño grupo de académicos y programadores industriales que abogaban por un nuevo estilo de programación para mejorar la calidad de los programas; y sus críticas iban dirigidas principalmente a la instrucción GOTO, a la que señalaba como causante de conducir a la generación de un “código espagueti imposible de mantener”. Probablemente la más famosa crítica hacia la instrucción GOTO es una carta abierta escrita por él llamada: “La Instrucción GOTO se Considera Perjudicial”. En esa carta Dijkstra argumenta que las declaraciones GOTO sin restricciones deben ser abolidas de 30 1. MARCO TEÓRICO

los lenguajes de alto nivel, ya que complican la tarea de analizar y verificar la exactitud de los programas (en particular aquellos que involucran bucles). [68]

Dijkstra creó el término “Programación Estructurada” para definir un paradigma de programación orientado a mejorar la claridad, calidad y tiempo de desarrollo de un programa de computadora, mediante un amplio uso de subrutinas, estructuras de blo- ques, bucles for y while, en contraste con el uso de validaciones sencillas y saltos como la instrucción GOTO. Y durante la década de 1970 la programación estructurada fue la ideología imperante en la programación. [105]

Las ideas de Dijkstra sobre la programación estructurada ayudaron a sentar las bases para el nacimiento y el desarrollo de la disciplina profesional de la ingeniería de soft- ware, que permite a los programadores organizar y gestionar proyectos de software cada vez más complejos.

1.3.1. Pascal

El lenguaje Pascal, llamado así en honor del matemático y filósofo francés Blaise Pascal, fue creado y presentado en 1970 por el suizo Niklaus Emil Wirth, Doctor en Ingeniería Eléctrica e Informática por la Universidad de California, Berkeley.

La intención de Wirth era crear un lenguaje eficiente (con respecto tanto a la velocidad de compilación como al código generado) sobre la base de la programación estructurada, un concepto que se había popularizado recientemente y que él promovió en su libro “Algorithms + Data Structures = Programs” (“Algoritmos + Estructuras de Datos = Programas”). [92]

Además de vectores y arreglos bi dimensionales, Pascal introdujo conceptos y mecanis- mos que permitieron a los programadores definir sus propios tipos de datos complejos (estructurados), y también hizo más fácil la construcción de estructuras de datos diná- micas y recursivas tales como listas, árboles y gráficos. Esas estructuras podían hacer uso de características importantes como registros, enumeraciones, subintervalos, varia- bles dinámicamente asignadas con punteros asociados, y conjuntos. Para que esto fuera posible y significativo, Pascal tenía una fuerte tipificación en todos sus valores, lo que significa que un tipo de datos no podía convertirse o interpretarse como otro diferente sin una conversión explícita de por medio. Mecanismos similares son un estándar en muchos lenguajes de programación actuales.

A diferencia de FORTRAN y COBOL, Pascal se podía codificar en formato libre. Eso significa que podíamos poner tantas líneas en blanco y espacios en el programa como 1.3. LENGUAJES ESTRUCTURADOS 31 quisiéramos para que el programa fuera más fácil de leer.

Pascal resultó ser un buen lenguaje de programación de propósito general, ofreciendo soporte para el trabajo científico, así como para los negocios. Las capacidades de entrada y salida de Pascal no eran tan avanzadas como las de otros lenguajes de programación utilizados en los negocios, tales como COBOL, por lo que nunca fue un competidor capaz de desbancar a COBOL de su pedestal en el mundo de los negocios. Sin embargo, cuando se liberó, Pascal fue un lenguaje sólido que hizo bien su trabajo.

Pascal tuvo un aumento enorme y rápido en popularidad en la década de 1970. Su mayor ventaja fue que era el primer lenguaje importante que respaldaba los conceptos de programación estructurada que hacían a los programas más fáciles de mantener. La ideología de la programación estructurada estaba integrada en el diseño de Pascal, lo que significa que los programas de Pascal eran más fáciles de mantener que los programas escritos en otros lenguajes de la época.

Durante la década de 1970, se pensó que Pascal se convertiría en “el único lenguaje de programación que todos necesitaríamos”. Pascal nunca alcanzó esa ambiciosa meta. El uso de Pascal pareció disminuir igual de rápido que lo que creció. La década de 1970 vio un gran crecimiento en el uso de Pascal, y la década de 1980 lo vio declinar.

A pesar de su desaparición en la década de 1980, Pascal estableció el camino para que futuros lenguajes de programación también dieran su respaldo a los conceptos estructurados, a los programas fáciles de mantener, y a la codificación en formato libre. [95]

1.3.2. C

El lenguaje C fue desarrollado originalmente por el estadounidense Dennis MacAlistair Ritchie entre 1969 y 1973 en los Laboratorios Bell. Ritchie, con grados en Física y Matemáticas por la Universidad de Harvard, utilizó C para volver a implementar el sistema operativo Unix; junto con el mismo creador del sistema Unix original, el también estadounidense Kenneth Lane Thompson, con Maestría en Ingeniería Eléctrica e Informática por la Universidad de California, Berkeley. Unix fue uno de los primeros núcleos de sistema operativo implementados en un lenguaje diferente del ensamblador. [55] [84] [113]

C es un lenguaje de programación de propósito general, con respaldo a la programación estructurada, al ámbito variable de léxico y a la recursividad, mientras que su sistema de tipos de datos estáticos impide que se efectúen muchas operaciones no deseadas. 32 1. MARCO TEÓRICO

Al diseñar C, Ritchie pensó en un lenguaje que fuera compilado usando un compi- lador relativamente sencillo, que pudiera proporcionar un acceso de bajo nivel a la memoria, con construcciones del lenguaje que tuvieran una equivalencia eficiente con las instrucciones de la máquina, y que requiriera un soporte mínimo en tiempo de ejecución. Por lo tanto C encontró un uso duradero en aplicaciones que anteriormente habían sido codificadas en lenguaje ensamblador, tales como la programación de siste- mas operativos, así como varias aplicaciones software para computadoras que van desde supercomputadoras hasta sistemas embebidos.

A pesar de sus capacidades de bajo nivel, C también fue diseñado para fomentar la programación multiplataforma. Un programa en C que haya sido escrito de manera tal que fuera compatible con los estándares y enfocado en la portabilidad, podía ser compilado para funcionar en una amplia variedad de plataformas computacionales y sistemas operativos con pocos cambios en su código fuente.

Desde su creación, C se ha convertido en uno de los lenguajes de programación más utilizados de todos los tiempos, existiendo compiladores de lenguaje C de diferentes proveedores disponibles para la mayoría de las arquitecturas de computadora y sistemas operativos existentes. [47] 1.4. LENGUAJES MODULARES 33

1.4. Lenguajes Modulares

El paradigma de los lenguajes de programación estructurada presentó una serie de mejoras sobre el lenguaje máquina, incluyendo la adición de una estructura primordial: el procedimiento. Las funciones más pequeñas no sólo eran más fáciles de entender, sino que también eran más fáciles de depurar.

Por otra parte, la programación de procedimientos limitaba la reutilización de código. Y, con demasiada frecuencia, los programadores seguían produciendo código espagueti, es decir, un código cuya ruta de ejecución se parecía a un plato de espaguetis.

Finalmente, la naturaleza centrada en los datos de la programación de procedimientos causaba algunos problemas propios. Dado que los datos y los procedimientos estaban separados, era necesario que cada procedimiento supiera cómo manipular correctamente los datos.

Desafortunadamente, una función que tuviera un mal comportamiento podría introdu- cir errores si no manipulaba los datos a la perfección. Dado que cada procedimiento necesitaba duplicar el conocimiento de cómo acceder a los datos, un cambio en la representación de los datos requeriría cambios en cada lugar que se tuviera acceso a los datos. Por lo tanto, incluso un pequeño cambio podría conducir a una cascada de cambios a lo largo del programa, en otras palabras, una pesadilla de mantenimiento.

La “Programación Modular” fue un intento por mejorar algunas de las deficiencias encontradas en la programación de procedimientos.

La programación modular separaba los programas en un número de componentes o módulos que lo constituían. A diferencia de la programación de procedimientos, que separaba los datos de los procedimientos, los módulos combinaban ambos. Un módulo se componía de los datos y de los procedimientos para la manipulación de esos datos. Cuando otras partes del programa necesitaban utilizar un módulo, simplemente hacían uso de la interfaz del módulo. Debido a que los módulos escondían todos los datos internos del resto del programa, era fácil introducir la idea del estado: Un módulo era capaz de mantener la información del estado (valor) de cada uno de los datos que podía cambiar con el tiempo. [90] 34 1. MARCO TEÓRICO

1.4.1. Modula y Modula-2

Modula y Modula-2 son unos lenguajes de programación diseñados y desarrollados entre 1976 y 1985 por (creador del lenguaje Pascal) en el Instituto Federal Suizo de Tecnología de Zurich como una revisión de Pascal para servir como el lenguaje de programación exclusivo para el sistema operativo y el software de aplicación para la estación de trabajo personal Lilith. [88] [92] [95]

Sus conceptos principales fueron:

El módulo se consideraba como una unidad de compilación para llevar a cabo la compilación separada.

La subrutina era el bloque de construcción básico para los procesos concurrentes.

Se utilizarían tipos y procedimientos que permitieran el acceso a los datos especí- ficos de la máquina.

Gran parte de la sintaxis de Modula-2 está basada en el anterior y mejor conocido lenguaje de Wirth, Pascal. Modula-2 fue diseñado para ser muy similar a Pascal, con algunos elementos y ambigüedades sintácticas removidas y la adición importante del concepto de módulo, además del respaldo directo del lenguaje para la multiprograma- ción. [89]

Pero había un problema con la programación modular, pues adolecía de grandes defi- ciencias en sí misma:

Los módulos no eran extensibles, lo que significa que no se podían hacer cambios incrementales a un módulo sin tener que abrir el código y hacer los cambios directamente.

Tampoco se podía basar un módulo en otro que no fuera sólo a través de la delegación.

Y, a pesar de que un módulo podía definir un tipo, un módulo no podía compartir el tipo de otro módulo. 1.5. LENGUAJES ORIENTADOS A OBJETOS 35

1.5. Lenguajes Orientados a Objetos

De la misma forma en que cada uno de los primeros paradigmas de programación intentaron aprovechar las fortalezas y corregir los errores de los paradigmas anteriores, el paradigma de la “Programación Orientada a Objetos” tiene sus fundamentos en dos paradigmas: el de la programación de procedimientos y el de la programación modular.

La programación modular estructuraba un programa en una serie de módulos. Del mis- mo modo, la programación orientada a objetos divide un programa en una serie de objetos que interactúan. Al igual que los módulos escondían representaciones de datos detrás de sus procedimientos, los objetos encapsulan su estado detrás de su interfaz. La programación orientada a objetos toma prestado este concepto de encapsulación directamente de la programación modular. La encapsulación es muy diferente de la programación de procedimientos. La programación de procedimientos no encapsulaba los datos. En su lugar, los datos estaban completamente disponibles para que todos los procedimientos tuvieran acceso a ellos. A diferencia de la programación de pro- cedimientos, la programación orientada a objetos acopla fuertemente los datos y el comportamiento juntos en el objeto.

Aunque los objetos son similares en concepto a los módulos, se diferencian en una serie de aspectos importantes. En primer lugar, los módulos no admiten fácilmente ser extendidos. La programación orientada a objetos introduce el concepto de herencia para corregir esta deficiencia. La herencia nos permite extender fácilmente y mejorar nuestras clases. La herencia también nos permite clasificar nuestras clases.

Definir un programa en términos de objetos es una forma profunda de visualizar el software. Los objetos nos obligan a ver todo a un nivel conceptual de lo que hace un objeto: sus comportamientos. Visualizar un objeto desde el punto de vista conceptual implica alejarse del enfoque en cómo se hace algo: la implementación. Este modo de pensar nos obliga a pensar en los programas en términos naturales, del mundo real. En lugar de modelar nuestro programa como un conjunto de procedimientos y datos (términos del mundo de la informática) por separado, modelamos nuestro programa en los objetos. Los objetos permiten crear un modelo de nuestros programas en los nombres, verbos, y adjetivos del dominio de nuestro problema.

La programación orientada a objetos también aprovecha el concepto de polimorfismo, lo que ayuda a crear programas flexibles que no sean resistentes al cambio. El polimorfismo añade esta flexibilidad mediante la corrección del limitado sistema de tipificación de la programación modular. 36 1. MARCO TEÓRICO

Escribir una lista secuencial de llamadas de procedimientos para dirigir el flujo del pro- grama ya no es el objetivo de la programación bajo la orientación a objetos. En su lugar, los objetos interactúan entre sí con el fin de conducir el flujo general del programa. En cierto modo, un programa de programación orientada a objetos se convierte en una simulación de la vida del problema que se está tratando de resolver.

1.5.1. Smalltalk

En 1969, el estadounidense Alan Curtis Kay, con grados de Matemáticas y Biología Molecular por la Universidad de Colorado en Boulder, y Maestría y Doctorado en Inge- niería Informática por la Universidad de Utah, comenzó el desarrollo de un lenguaje de programación orientado a objetos, reflexivo y dinámicamente tipificado; la intención era crear un lenguaje para el “nuevo mundo” de la informática ejemplificado por la “sim- biosis hombre-máquina”. Fue presentado por primera vez en 1972 y recibió el nombre común de Smalltalk. [102]

La primera versión de Smalltalk se conoció como Smalltalk-71, y la mayoría de sus esquemas se clasificaron en seis ideas principales:

Todo es un objeto

Los objetos se comunican mediante el envío y recepción de mensajes (en términos de objetos)

Los objetos tienen su propia memoria (en términos de objetos)

Cada objeto es una instancia de una clase (que debe ser un objeto)

La clase mantienen el comportamiento compartido por sus instancias (en la forma de objetos en una lista de programas)

Para evaluar una lista de programas, se pasa el control al primer objeto y el resto es tratado como su mensaje

Los tres primeros principios siguen siendo los mismos en las distintas versiones de Smalltalk. Los tres últimos, de acuerdo con Kay, han cambiado con cada versión.

Kay publicó en 1993 un artículo llamado “La Historia Temprana de Smalltalk”, donde afirmó que los lenguajes de programación deberían clasificarse en dos grupos: [32]

“Los lenguajes de programación se pueden clasificar de varias maneras: impe- rativos, aplicativos, basados en la lógica, orientados a los problemas, etc. Pero todos ellos parecen ser una ‘aglutinación de funciones’ o una ‘cristalización 1.5. LENGUAJES ORIENTADOS A OBJETOS 37

de estilo’. COBOL, PL/1, Ada, etc., pertenecen a la primera clase; LISP, APL (y Smalltalk) son del segundo tipo. Es probable que no sea un accidente que todos los lenguajes aglutinantes parecen haber sido instigados por comités, y los lenguajes de cristalización por una sola persona.” [27]

En ese mismo artículo, explicó los fundamentos del diseño de Smalltalk:

“El diseño (y la existencia) de Smalltalk se debe a la idea de que todo lo que podemos describir puede ser representado por la composición recursiva de un solo tipo de bloque de construcción del comportamiento que oculta su combinación de estado y proceso dentro de sí mismo y que puede tratarse únicamente a través del intercambio de mensajes.” [27]

Los “bloques de construcción” a los que hace referencia en realidad son los “objetos” en la programación orientada a objetos. Kay continúa:

“En términos informáticos, Smalltalk es una recursividad de la noción de la pro- pia computadora. En lugar de dividir ‘cosas de computadora’ en cosas cada vez menos fuertes que el todo (como estructuras de datos, procedimientos y funcio- nes, los cuales son la parafernalia habitual de los lenguajes de programación) cada objeto Smalltalk es un recursividad de la totalidad de las posibilidades de la computadora. Por lo tanto, sus semánticas son un poco como tener miles y miles de computadoras todas enlazadas entre sí por una red muy rápida.” [27]

Kay vio a Smalltalk como “un nuevo paradigma de diseño” que permitía a los programa- dores profesionales resolver más fácilmente grandes problemas, al tiempo que permitía a los usuarios novatos hacer frente a los problemas pequeños. “El diseño orientado a objetos,” escribió Kay, “es un intento exitoso para mejorar cualitativamente la eficacia en la modelización de los cada vez más complejos sistemas dinámicos y de las relaciones de usuarios posibles gracias a la explosión del silicio”. [20]

En otras palabras, el desarrollo de Smalltalk en la década de 1970 fue más que la creación de sólo otro lenguaje de programación. Smalltalk marcó el comienzo de la era de la programación orientada a objetos e introdujo una serie de innovaciones que cambiaron la cara de la informática moderna y ayudó a precipitar el inicio de la computadora personal.

Smalltalk fue también uno de los lenguajes de programación más influyentes. Prácti- camente la totalidad de los lenguajes orientados a objetos que se produjeron después fueron influenciados por Smalltalk. 38 1. MARCO TEÓRICO

1.5.2. C++

En 1979, , un Informático de Dinamarca, comenzó el desarrollo del lenguaje “C con Clases”, que en 1983 pasaría a llamarse C++. El nombre se deriva del operador “++” (que incrementa el valor de una variable) del lenguaje C y de una convención de nomenclatura común de utilizar “+” para indicar un programa de computadora mejorado.

Su motivación para crear un nuevo lenguaje se originó a partir de su experiencia en la programación para su tesis de Doctorado; Stroustrup encontró que otro lenguaje, Simula, tenía características que eran muy útiles para el desarrollo de software de gran tamaño, pero el lenguaje era demasiado lento para el uso práctico, mientras que otro lenguaje, BCPL era rápido pero demasiado de bajo nivel como para que fuera adecuado para el desarrollo de software de gran tamaño.

Recordando su experiencia en el doctorado, Stroustrup se dispuso a mejorar el lenguaje C con características similares a Simula. Eligió C porque era de uso general, rápido, portátil y ampliamente utilizado. [42]

C++ le añadió al lenguaje C los conceptos característicos de la programación orientada a objetos. Incluyendo clases, que proporcionaban las cuatro características comúnmente presentes en lenguajes de programación orientada a objetos: abstracción, encapsula- ción, herencia y polimorfismo.

El diseño de C++ tuvo un sesgo hacia la programación de sistemas hardware y circuitos embebidos, de sistemas tanto con recursos limitados como de gran tamaño, con el rendimiento, la eficiencia y la flexibilidad de uso como sus aspectos más destacados de diseño. C++ también encontró su utilidad en muchos otros contextos, siendo sus puntos fuertes la infraestructura de software y aplicaciones de recursos limitados, que incluyen aplicaciones de escritorio, servidores (por ejemplo, el comercio electrónico, búsqueda en la web o servidores SQL), y aplicaciones de rendimiento crítico (por ejemplo, conmutadores telefónicos o sondas espaciales). [46] 1.5. LENGUAJES ORIENTADOS A OBJETOS 39

1.5.3. Java

Java es un lenguaje de programación de propósito general que es concurrente, basado en clases, orientado a objetos, y diseñado específicamente para tener el menor número posible de dependencias relacionadas con la implementación. Su objetivo es permitir a los desarrolladores de aplicaciones “escribir una vez, ejecutar en cualquier lugar”(WORA: Write Once, Run Anywhere), lo que significa que el código Java compilado puede ejecu- tarse en todas las plataformas que soporten Java sin necesidad de una recompilación. Las aplicaciones Java están típicamente compiladas a código de bytes (bytecode) que puede ejecutarse en cualquier Máquina Virtual Java (JVM: Java Virtual Machine), de forma independiente a la arquitectura de la computadora. [76]

Hubo cinco objetivos principales en la creación del lenguaje Java:

Debía ser “simple, orientado a objetos, y familiar”.

Debía ser “robusto y seguro”.

Debía ser “de arquitectura neutra y portátil”.

Se debía ejecutar con un “alto rendimiento”.

Debía ser “interpretado, con procesamiento en hilos, y dinámico”.

Las semillas de Java fueron plantadas en 1990 por el cofundador y jefe de investigación de Sun Microsystems, el estadounidense William Nelson “Bill” Joy, con Maestría en Ciencias en Ingeniería Eléctrica e Informática por la Universidad de California, Berkeley. [41]

En ese momento, Sun estaba compitiendo en un mercado relativamente pequeño de estaciones de trabajo mientras que Microsoft comenzaba su dominio en el mundo más convencional de la Computadora Personal (PC: Personal Computer) basada en Intel. Cuando Sun perdió el tren de la revolución de la PC, Joy se retiró a Aspen, Colorado, para trabajar en la investigación avanzada. Estaba comprometido con la idea de llevar a cabo tareas complejas con un software sencillo y fundó su laboratorio de investigación llamado “Aspen Smallworks”. [11]

De los miembros originales del pequeño equipo de programadores reunidos en Aspen, el canadiense James Arthur Gosling, con Doctorado en Informática por la Universidad Carnegie Mellon, será recordado como el padre de Java. [75]

Gosling ya había ganado un renombre por sí mismo en los años 80 como el autor de Gosling Emacs, la primera versión del popular editor Emacs que había sido escrito en C y corría bajo Unix. Gosling Emacs se hizo popular, pero pronto fue eclipsado por una 40 1. MARCO TEÓRICO

versión libre, GNU Emacs, escrita por el diseñador original de Emacs. En ese momento, Gosling se había trasladado al diseño de NeWS (Network extensible Window System) en Sun, que compitió brevemente con X Window System por el control de la interfaz gráfica de usuario del escritorio Unix en 1987. A pesar de que algunas personas po- drían argumentar que NeWS era superior a X, NeWS perdió porque Sun lo mantuvo propietario y no publicó el código fuente, mientras que los desarrolladores principales de X formaron el X Consortium y tomaron el camino contrario. [106]

Al diseñar NeWS, Gosling comprendió el poder de la integración de un lenguaje ex- presivo con una interfaz gráfica de ventanas consciente de la red. También enseñó a Sun que la comunidad de programadores de Internet en última instancia se negaría a aceptar las normas de propiedad, no importando lo bueno que puediera ser. Las semillas del sistema de licencias de Java y de código abierto (si bien no es “fuente abierta”) fueron sembradas por el fracaso de NeWS. Gosling trajo lo que había aprendido al incipiente proyecto de Bill Joy en Aspen. En 1992, su trabajo en el proyecto llevó a la fundación de la filial de Sun FirstPerson, Inc. Su misión era llevar a Sun al mundo de la electrónica de consumo.

El equipo de FirstPerson trabajó en el desarrollo de software para dispositivos de infor- mación, tales como teléfonos celulares y Asistentes Digitales Personales (PDA: Personal Digital Assistant). Su objetivo era permitir la transferencia de información y aplicaciones en tiempo real a través de redes económicas basadas en infrarrojos y las tradicionales basadas en paquetes. Las limitaciones de memoria y de ancho de banda motivaron el desarrollo de un código pequeño, eficiente. La naturaleza de las aplicaciones también exigió que fueran seguras y robustas. Gosling y sus compañeros de equipo comenzaron a programar en C++, pero pronto se vieron confundidos por un lenguaje demasiado complejo, difícil de manejar, e inseguro para la tarea. Decidieron empezar desde cero, y Gosling comenzó a trabajar en algo que calificó como “C++ menos menos”.

Con el hundimiento de la Apple Newton (la computadora de mano más antigua de Apple), se hizo evidente que la nave del PDA aún no había llegado, así que Sun cambió los esfuerzos de FirstPerson a la Televisión Interactiva (ITV: Interactive TV). El lenguaje de programación elegido para los decodificadores de ITV iba a ser el ancestro cercano de Java, un lenguaje llamado Oak. A pesar de su elegancia y capacidad de proporcionar interactividad segura, Oak no pudo salvar la causa perdida de ITV en ese momento. Los clientes no lo querían, y Sun pronto abandonó el concepto.

En ese momento, Joy y Gosling se reunieron para decidir sobre una nueva estrategia para su lenguaje innovador. Era 1993 y la explosión de interés en la Web presentaba una nueva oportunidad. Oak era pequeño, seguro, independiente de la arquitectura, 1.5. LENGUAJES ORIENTADOS A OBJETOS 41 y orientado a objetos. Daba la casualidad, de que estos también eran algunos de los requisitos para un lenguaje de programación universal expecializado en Internet. Sun cambió rápidamente su enfoque, y, con un poco de reorganización, Oak se convirtió en Java.

No sería exagerado decir que Java prendió como reguero de pólvora. Incluso antes de su primer lanzamiento oficial cuando Java todavía no era un producto, casi todos los actores importantes de la industria ya se habían subido al carro de Java. Entre los licenciatarios de Java estaban Microsoft, Intel, IBM, y prácticamente todos los principales fabricantes de hardware y software. Sin embargo, aún con todo este soporte Java se llevó una gran cantidad de golpes y experimentó algunos problemas de crecimiento durante sus primeros años.

Una serie de incumplimientos de contrato y demandas antimonopolio entre Sun y Mi- crosoft sobre la distribución de Java y su uso en Internet Explorer obstaculizaron su despliegue en el sistema operativo de escritorio más común del mundo: Windows. La participación de Microsoft con Java también se convirtió en un foco de una demanda federal más grande sobre graves prácticas de la empresa contrarias a la competencia, con el testimonio de la corte revelando los esfuerzos concertados del gigante del soft- ware para minar a Java mediante la introducción de incompatibilidades en su versión del lenguaje. Mientras tanto, Microsoft introdujo su propio lenguaje derivado de Java llamado C# (C-sharp) como parte de su iniciativa .NET echando fuera a Java de ser incluido en Windows. C# ha pasado a convertirse en un muy buen lenguaje por dere- cho propio, disfrutando de una mayor innovación en los últimos años de los que tiene Java.

Pero Java continúa extendiéndose en una amplia variedad de plataformas. Lo que resul- ta más interesante en la arquitectura de Java tiene que ver con el entorno autocontenido de su máquina virtual en la que se ejecutan las aplicaciones Java. Java fue diseñado cui- dadosamente de modo que esta arquitectura de soporte puede ser implementada ya sea en software, para plataformas de computación existentes, o en hardware personalizado. Las implementaciones de Java en hardware se utilizan en algunas tarjetas inteligentes y otros sistemas embebidos. Es posible incluso comprar dispositivos “portátiles”, tales como anillos y placas de identificación para mascotas, que tienen intérpretes de Java incrustados en ellos. Las implementaciones de Java en software están disponibles para todas las plataformas informáticas modernas y hasta en los dispositivos informáticos portátiles. Hoy en día, una rama de la plataforma Java es la base para el sistema ope- rativo Android de Google con el que funcionan miles de millones de teléfonos y otros dispositivos móviles. 42 1. MARCO TEÓRICO

En 2010, la corporación Oracle compró Sun Microsystems y se convirtió en el admi- nistrador del lenguaje Java. En un comienzo un tanto inestable a su posesión, Oracle demandó a Google por su uso del lenguaje Java en Android y en mayo de 2012, el jurado en este caso encontró que Google no infringió las patentes de Oracle, y el juez dictaminó que la estructura de las API de Java utilizadas por Google no eran suscepti- bles del derecho de autor. Las partes llegaron a un acuerdo de pagar cero dólares en daños y perjuicios legales por una pequeña cantidad de código copiado. El 9 de mayo de 2014, el Circuito Federal revocó parcialmente el fallo de la corte de distrito, fallando a favor de Oracle en el tema de los derechos de autor, y devolviendo la cuestión del uso justo al tribunal de distrito. Una petición de revisión fue denegada por el Tribunal Supremo de los Estados Unidos el 29 de junio de 2015. Un segundo juicio está progra- mado para el 9 de mayo de 2016, en el que Oracle está solicitando el pago de $ 9.3 billones de dólares por daños. [94]

En marzo del 2014, Oracle lanzó Java SE 8, la última versión de Java y la única versión soportada actualmente de forma gratuita por parte de Oracle, aunque versiones ante- riores reciben soporte por parte de Oracle y otras compañías sobre una base comercial. [76] 1.6. PROGRAMACIÓN ORIENTADA A OBJETOS 43

1.6. Programación Orientada a Objetos

Todos los días, los seres humanos nos enfrentamos constantemente a un sinfín de acontecimientos y sensaciones a los que debemos dar un significado.

Para lograrlo, debemos hacer uso de la abstracción, que implica sustraer por medio de una operación intelectual la estructura subyacente de los detalles superficiales y descubrir las conexiones fundamentales en juego.

Las abstracciones nos permiten revelar causas y efectos, exponer patrones y estructuras, y separar lo que es importante de lo que no lo es.

El enfoque de la orientación a objetos nos proporciona una abstracción de los datos en los que operamos; además, nos proporciona una agrupación concreta entre los datos y las operaciones que pueden efectuarse en los datos: dándole, de hecho, un comporta- miento a los datos. [1]

1.6.1. Datos y Operaciones

Los primeros lenguajes de programación dividieron al mundo de manera convencional en dos partes: los datos y las operaciones efectuadas en los datos.

Los datos están inmóviles y son inalterables, a menos que las operaciones puedan modificarlos.

Los procedimientos y funciones que operan sobre los datos no tienen ningún estado duradero propio; su utilidad radica sólo en su capacidad para afectar a los datos.

Esta división está fundamentada en la forma en que funcionan las computadoras, cu- ya arquitectura mantuvo desde el principio una separación entre los dispositivos de almacenamiento y los de procesamiento; por lo que no es algo que fácilmente pueda ignorarse o hacerse a un lado.

Así como ya se ha establecido una diferenciación ampliamente generalizada entre, por ejemplo, la materia y la energía, o entre los sustantivos y los verbos, de la misma forma es que se constituye el contexto de la orientación a objetos.

En algún momento, todos los programadores (aún aquellos programadores orientados a objetos) debemos diseñar las estructuras de datos que utilizarán nuestros programas y definir las funciones que actuarán sobre los datos. 44 1. MARCO TEÓRICO

Con un lenguaje de programación basado en procedimientos como C, eso es todo lo que hay que hacer. El lenguaje puede ofrecernos diversos tipos de apoyo para que podamos organizar los datos y las funciones, pero no va a dividir el mundo de forma diferente.

En un lenguaje de programación basado en procedimientos, las funciones y las estruc- turas de datos son los elementos básicos del diseño.

La programación orientada a objetos no entra tanto en conflicto con esta visión del mundo sino que la reestructura a un nivel más alto.

Agrupa las operaciones y los datos en unidades modulares llamadas objetos y nos permite combinar objetos en redes estructuradas para formar un programa completo.

En un lenguaje de programación orientado a objetos, los objetos y las correlaciones entre esos objetos son los elementos básicos del diseño.

Cada objeto tiene tanto un estado (datos) como un comportamiento (operaciones sobre los datos). En eso, no son muy diferentes de los objetos físicos ordinarios.

Es fácil ver cómo un dispositivo mecánico, tal como un reloj de bolsillo o un piano, encarnan tanto un estado como un comportamiento. Pero casi todo lo que está diseñado para hacer un trabajo también lo hace.

Incluso las cosas simples, sin partes móviles, como una botella ordinaria combinan un estado (qué tan llena está la botella, si está abierta o no, qué tan caliente está su contenido) con un comportamiento (su capacidad para verter sus contenidos a diferentes caudales, para poderla abrir o cerrar, para soportar altas y bajas temperaturas).

Es este parecido a las cosas reales lo que da a los objetos mucho de su poder y atractivo. Ellos pueden no sólo modelar los componentes de los sistemas reales, sino igualmente también pueden cumplir con funciones asignadas como componentes de sistemas de software.

1.6.2. Interfaz e Implementación

Para inventar programas, necesitamos ser capaces de captar las abstracciones y expre- sarlas en el diseño del programa. Y el trabajo de un lenguaje de programación es precisamente ayudarnos a hacer esto.

El lenguaje debe facilitarnos el proceso de invención y diseño permitiéndonos codificar abstracciones que revelen cómo funcionan las cosas. Debe permitir concretar las ideas 1.6. PROGRAMACIÓN ORIENTADA A OBJETOS 45 en el código que se escribe. Los detalles superficiales no deben ocultar la arquitectura del programa.

Todos los lenguajes de programación proporcionan dispositivos que ayudan a expresar abstracciones. En esencia, estos dispositivos son formas de agrupar los detalles de imple- mentación, ocultándolos, y dándoles, al menos en cierta medida, una interfaz común: así como un objeto mecánico separa su interfaz de su implementación, como se ilustra en la figura 1.1.

Figura 1.1 Interfaz e Implementación

Interfaz Implementación −→ ←−

Si observamos una unidad de este tipo desde su interior, como implementadores, nos interesaría saber de qué se compone y cómo funciona.

Observándola desde afuera, como usuarios, sólo nos interesaría saber qué es y qué hace.

Podemos observar más allá de los detalles y pensar únicamente en términos de la función que desempeña la unidad en un nivel superior.

Las principales unidades de abstracción en el lenguaje C son las estructuras y las funciones. Ambas, de diferentes maneras, ocultan los elementos de la implementación:

Por el lado de los datos del mundo real, las estructuras en el lenguaje C agrupan los elementos de datos en unidades mayores que puedan entonces ser manejadas como entidades individuales.

Mientras que algo de código debe profundizar dentro de la estructura y manipular los campos por separado, gran parte del programa puede considerarse como una sola cosa: no como una colección de elementos, sino como lo que esos elementos representan en conjunto.

Una estructura puede incluir a otras estructuras, por lo que un arreglo complejo de información puede ser construido a partir de capas simples. 46 1. MARCO TEÓRICO

En el moderno lenguaje C, los campos de una estructura viven en su propio espacio de nombres: es decir, sus nombres no entrarán en conflicto con los elementos de datos con nombres idénticos fuera de la estructura.

La partición del espacio de nombres del programa es esencial para mantener los detalles de implementación fuera de la interfaz. Imaginemos, por ejemplo, la enorme tarea de asignar un nombre diferente a cada pieza de datos en un programa grande y de asegurarse de que los nuevos nombres no entren en conflicto con los antiguos.

En la parte de los procedimientos del mundo real, las funciones encapsulan compor- tamientos que pueden utilizarse varias veces sin que tengan que implementarse de nuevo.

Los elementos de datos locales a una función, al igual que los campos dentro de una estructura, están protegidos dentro de su propio espacio de nombres.

Dado que las funciones pueden hacer referencia (llamar) a otras funciones, pueden construirse comportamientos complejos a partir de piezas más pequeñas.

Las funciones son reutilizables. Una vez definidas, se les puede llamar cualquier número de veces sin considerar nuevamente la implementación.

Las funciones en general más útiles se pueden recopilar en librerías y volver a utilizarse en muchas aplicaciones diferentes. Todo lo que los usuarios necesitan es la interfaz de la función, no el código fuente.

Sin embargo, a diferencia de los elementos de datos, las funciones no están divididas en espacios de nombres distintos. Cada función debe tener un nombre único. Aunque la función puede ser reutilizable, su nombre no lo es.

Las estructuras y las funciones del lenguaje C son capaces de expresar abstracciones significativas, pero mantienen la distinción entre los datos y las operaciones sobre los datos.

En un lenguaje de programación de procedimientos, las unidades superiores de abs- tracción aún viven en un lado u otro de la división entre datos y operaciones. Los programas diseñados siempre deben reflejar, al más alto nivel, la forma en que funcio- na la computadora.

Los lenguajes de programación orientados a objetos no pierden ninguna de las virtudes de las estructuras y de las funciones: van un paso más allá y añaden una unidad con capacidad de abstracción a un nivel superior, una unidad que esconde la interacción entre una función y sus datos. 1.6. PROGRAMACIÓN ORIENTADA A OBJETOS 47

Supongamos, por ejemplo, que tenemos un grupo de funciones que actúan sobre una estructura de datos en particular. Queremos hacer a esas funciones fáciles de usar, en la medida de lo posible, sacando la estructura de la interfaz. Así que agregamos unas pocas funciones adicionales para manejar los datos.

Todo el trabajo de manipular la estructura de datos: asignar la memoria para ella, ini- cializarla, obtener información de ella, modificar los valores dentro de ella, mantenerla actualizada, y liberar su memoria, se realiza a través de las funciones. Todo lo que el usuario hace es llamar a las funciones y pasarles la estructura.

Con estos cambios, la estructura se ha convertido en un símbolo opaco en el que otros programadores nunca tienen que ver en su interior. Pueden concentrarse en lo que hacen las funciones, no en cómo están organizados los datos. Hemos dado el primer paso hacia la creación de un objeto.

El siguiente paso es apoyar ésta idea en el lenguaje de programación y ocultar por completo la estructura de datos de modo que ni siquiera tenga que pasar entre las funciones.

Los datos se convierte en un detalle de implementación interna; todo lo que se exporta a los usuarios es una interfaz funcional. Dado que los objetos encapsulan completamente sus datos (los ocultan), los usuarios pueden pensar en ellos sólo en términos de su comportamiento.

Con este paso, la interfaz a las funciones se ha vuelto mucho más simple. Quien la llame no necesitan saber cómo están implementadas (qué datos utilizan). Es justo ahora llamar a esto un objeto.

La estructura de datos oculta unifica a todas las funciones que comparten el acceso a la misma. Así que un objeto es más que una colección de funciones aleatorias; es un conjunto de conductas relacionadas que se apoyan en los datos compartidos.

Para utilizar una función que pertenece a un objeto, primero debe crearse el objeto (lo que le otorga su estructura de datos interna) y, a continuación, decirle al objeto que función deberá realizar. Comenzamos a pensar en términos de lo que hace el objeto, en lugar de en términos de las funciones individuales.

Esta progresión de pensar en las funciones y las estructuras de datos hacia pensar en los comportamientos de los objetos es la esencia del aprendizaje de la programación orientada a objetos. Puede parecer poco familiar al principio, pero a medida que adqui- rimos experiencia con la programación orientada a objetos, encontraremos que es una forma más natural de pensar sobre las cosas. 48 1. MARCO TEÓRICO

La terminología de programación cotidiana está repleta de analogías con los objetos del mundo real de diversos tipos: listas, contenedores, tablas, controladores, incluso administradores. La implementación de tales cosas como objetos de programación se limita a extender la analogía de una manera natural.

Un lenguaje de programación puede ser juzgado por los tipos de abstracciones que nos permita codificar. No debemos distraernos por asuntos ajenos o sentirnos obligados a expresarnos en un vocabulario que no coincida con la realidad que estamos tratando de captar.

Si, por ejemplo, siempre debemos inclinarnos a la labor de mantener los datos correctos emparejados con los procedimientos correctos, estamos obligado en todo momento a estar al tanto de todo el programa a un bajo nivel de implementación.

Si bien es posible inventar programas a un alto nivel de abstracción, el camino de la imaginación a la aplicación puede llegar a ser bastante precario: y cada vez más difícil, conforme los programas se hacen más grandes y más complicados.

Al proporcionar otro, un mayor nivel de abstracción, los lenguajes de programación orientados a objetos nos brindan un vocabulario más amplio y un modelo más rico para programar.

1.6.3. Objetos

La idea de la programación orientada a objetos es la de combinar estado y comporta- miento (los datos y las operaciones sobre los datos) en una unidad de alto nivel, un objeto, y darle respaldo del lenguaje.

Un objeto es un grupo de funciones relacionadas y una estructura de datos que sirve a esas funciones.

Las funciones se conocen como métodos del objeto, y los campos de su estructura de datos son sus variables de instancia.

Los métodos se envuelven alrededor de las variables de instancia y las esconden del resto del programa, como ilustra la figura 1.2.

En la programación basada en procedimientos, era probable que los tipos de problemas con mayor grado de dificultad incluyeran grupos de funciones que trabajaban en un tipo particular de datos: es decir, “objetos” implícitos pero que no contaban con el respaldo del lenguaje. 1.6. PROGRAMACIÓN ORIENTADA A OBJETOS 49

Figura 1.2 Un objeto

La programación orientada a objetos hace explícitos a estos grupos de funciones y nos permite pensar en los términos del grupo, en lugar de sus componentes. El único camino a los datos de un objeto, la única interfaz, es a través de sus métodos.

Mediante la combinación de estado y comportamiento en una sola unidad, un objeto se transforma en algo más que sí mismo; el conjunto es realmente mayor que la suma de sus partes.

Un objeto es una especie de “subprograma” autosuficiente con jurisdicción sobre un área funcional específica. Está plenamente facultado para desempeñar un papel modular dentro de un diseño de programa de mayor tamaño.

Por ejemplo, si fuéramos a escribir un programa que modele el uso del agua en el hogar, podríamos inventar objetos para representar los distintos componentes del sistema de distribución de agua.

Uno podría ser un objeto Grifo que tendría métodos para iniciar y detener el flujo de agua, establecer la velocidad del flujo, devolver la cantidad de agua que se consumió en un período determinado, y así sucesivamente.

Para hacer este trabajo, un objeto Grifo necesitaría variables de instancia para realizar un seguimiento de si el grifo está abierto o cerrado, la cantidad de agua que se utiliza, y de dónde está viniendo el agua.

Es evidente que un objeto Grifo programático puede ser más inteligente que uno real (lo que sería análogo a tener un grifo mecánico con una gran cantidad de indicadores e instrumentos amarrados).

Pero incluso un grifo real, como cualquier componente del sistema, muestra tanto estado como comportamiento. Para modelar con eficacia un sistema, necesitamos unidades de programación, como objetos, que también combinen estado y comportamiento. 50 1. MARCO TEÓRICO

Un programa se compone de una red de objetos interconectados que se llaman una a otro para resolver una parte del rompecabezas (como se ilustra en la figura 1.3).

Cada objeto tiene un papel específico que desempeñar en el diseño general del programa y es capaz de comunicarse con otros objetos. Los objetos se comunican entre sí mediante la ejecución de los métodos públicos de cada objeto, es decir, los que expone para su ejecución a cualquier otro objeto que tenga acceso a su propia instancia.

Figura 1.3 Objetos en una red

Los objetos en la red no serán todos los mismos. Por ejemplo, además del objeto Grifo, el programa que modele el uso del agua también puede tener objetos Tubería que pueden entregar agua a los objetos Grifo y Válvula para regular el flujo a través de las tuberías.

Podría haber un objeto Edificio para coordinar un conjunto de tuberías, válvulas y grifos, algunos objetos Aparato (correspondientes a los lavavajillas, inodoros y lavado- ras) que pueden encender y apagar válvulas, y tal vez algunos objetos Usuario que trabajen con los dispositivos y los grifos.

Cuando se le pregunte a un objeto Edificio cuánta agua se está utilizando, puede pedirle a cada objeto Grifo y Válvula que reporte su estado actual. Cuando un usuario hace funcionar un dispositivo, el dispositivo tendrá que activar una válvula para obtener el agua que necesita. 1.6. PROGRAMACIÓN ORIENTADA A OBJETOS 51

1.6.4. Clases

Un programa puede tener más de un objeto del mismo tipo. El programa que modela el uso del agua, por ejemplo, podría tener varios grifos y tuberías y tal vez un puñado de dispositivos y usuarios.

Se dice que los objetos del mismo tipo son miembros de la misma clase. Todos los miembros de una clase son capaces de llevar a cabo los mismos métodos y tienen conjuntos coincidentes de las variables de instancia. También comparten una definición común; cada tipo de objeto se define una sola vez.

En ésto, los objetos son similares a las estructuras en el lenguaje C. Al declarar una estructura definimos un tipo. Por ejemplo, la declaración

struct clave { char *palabra; int contador; }; define el tipo de clave struct. Una vez definido, el nombre de la estructura se puede utilizar para producir cualquier número de instancias del tipo:

struct clave a, b, c, d; struct clave *p = malloc(sizeof(struct clave) * MAXIMO_ELEMENTOS);

La declaración es una plantilla para un tipo de estructura, pero no crea una estructura que el programa pueda utilizar. Se necesita un paso más para asignar la memoria para una estructura real de ese tipo, un paso que se puede repetir cualquier número de veces.

Del mismo modo, la definición de un objeto crea una plantilla para un tipo de objeto. Define una clase de objetos. La plantilla se puede utilizar para producir cualquier núme- ro de objetos similares: instancias de la clase. Por ejemplo, habría una sola definición de la clase Grifo. Usando esta definición, un programa podría asignar tantas instancias de Grifo como se necesiten.

Una definición de clase es como una definición de estructura en la que se establece una disposición de elementos de datos (variables de instancia) que se convierten en parte de cada instancia. Cada instancia ha asignado memoria para su propio conjunto de variables de instancia, que almacenan valores particulares a la instancia.

Sin embargo, una definición de clase se diferencia de una declaración de estructura en que también define métodos que especifican el comportamiento de los miembros de la 52 1. MARCO TEÓRICO

clase. Todas las instancias se caracterizan por su acceso a los métodos definidos por la clase. Dos objetos con estructuras de datos equivalentes pero diferentes métodos no pueden pertenecer a la misma clase. 1.7. MECANISMOS DE ABSTRACCIÓN 53

1.7. Mecanismos de Abstracción

Hasta este punto, los objetos se han presentado como unidades que expresan abstrac- ciones de alto nivel y como actores coherentes dentro de una aplicación.

Sin embargo, no podrían ser utilizados de esta manera sin el apoyo de diversos meca- nismos del lenguaje. Dos de los mecanismos más importantes son la encapsulación y el polimorfismo.

La encapsulación mantiene la implementación de un objeto fuera de su interfaz, y el polimorfismo resulta de dar a cada clase su propio espacio de nombres. Las secciones siguientes describen cada uno de estos mecanismos a su vez.

1.7.1. Encapsulación

Para diseñar con eficacia a cualquier nivel de abstracción, necesitamos ser capaces de dejar atrás los detalles de implementación y pensar en términos de unidades que agrupen esos detalles bajo una interfaz común.

Para que una unidad de programación sea realmente eficaz, la barrera entre la interfaz y la implementación debe ser absoluta. La interfaz debe encapsular la implementa- ción: es decir, esconderla de otras partes del programa. La encapsulación protege una implementación de acciones no intencionadas y de acceso inadvertido.

En un lenguaje basado en procedimientos, una función está claramente encapsulada; su implementación es inaccesible para otras partes del programa y está protegida de cualquiera de las acciones que pudieran llevarse a cabo fuera del cuerpo de la función.

En un lenguaje orientado a objetos, las implementaciones de métodos se encapsulan de manera similar, pero más importantes son las variables de instancia de un objeto. Están escondidas en el interior del objeto y son invisibles fuera de ella. La encapsulación de las variables de instancia a veces también se llama ocultamiento de información.

Podría parecer, a primera vista, que ocultar la información en las variables de instancia puede restringir nuestra libertad como programadores. En realidad, nos da más espacio para actuar y nos libera de las limitaciones que de otro modo nos podrían ser impuestas.

Si alguna parte de la implementación de un objeto pudiera filtrarse y llegar a ser accesible o ser del interés de otras partes del programa, ello ataría las manos tanto del implementador del objeto como de los que utilicen el objeto. Ninguno podría hacer modificaciones sin antes consultar con el otro. 54 1. MARCO TEÓRICO

Supongamos, por ejemplo, que estamos interesados en el objeto Grifo que está siendo desarrollado para el programa que modela el uso del agua y queremos incorporarlo en otro programa que estamos escribiendo.

Una vez que la interfaz para el objeto queda decidida, no tenemos que preocupar- nos cuando otros trabajan en ella, corrigen errores, y encuentran mejores formas de implementarla.

Obtenemos el beneficio de estas mejoras, pero ninguna de ellas afecta a lo que hacemos en nuestro programa. Porque dependemos únicamente de la interfaz, nada de lo que otros hagan puede afectar nuestro código.

Nuestro programa está aislado de la implementación del objeto.

Además, aunque aquellos que implementen el objeto Grifo podrían estar interesados en cómo utilizamos la clase y podrían tratar de asegurarse de que se adapte a nuestras necesidades, no tienen que preocuparse por la forma en que escribimos el código.

Nada de lo que hagamos puede afectar la implementación del objeto o limitar su libertad para hacer cambios a la implementación en futuras versiones. La aplicación está aislada de todo lo que nosotros u otros usuarios del objeto puedan hacer.

1.7.2. Polimorfismo

La capacidad de los diferentes objetos de responder, cada uno a su manera, a llamadas idénticas a alguno de sus métodos se denomina polimorfismo.

El polimorfismo resulta del hecho de que cada clase vive en su propio espacio de nom- bres. Los nombres asignados dentro de una definición de clase no entran en conflicto con los nombres asignados en cualquier lugar fuera de ella. Esto es cierto tanto para las variables de instancia en la estructura de datos de un objeto como en los métodos del objeto:

Al igual que los campos de una estructura en lenguaje C se encuentran en un espacio protegido de nombres, así también lo están las variables de instancia de un objeto.

Los nombres de los métodos también están protegidos. A diferencia de los nombres de las funciones en lenguaje C, los nombres de los métodos no son símbolos globales. El nombre de un método en una clase no puede entrar en conflicto con los nombres de los métodos en otras clases; dos clases muy diferentes pueden implementar métodos con nombres idénticos. 1.7. MECANISMOS DE ABSTRACCIÓN 55

Los nombres de los métodos son parte de la interfaz de un objeto. Cuando se quiere solicitar que un objeto haga algo, se hace una llamada al método que el objeto debe realizar.

Debido a que diferentes objetos pueden tener métodos con el mismo nombre, el sig- nificado de una llamada a un método debe ser entendido en relación con el objeto particular que recibe la llamada a su método. La misma llamada enviada a dos objetos diferentes puede invocar dos métodos distintos.

El principal beneficio del polimorfismo es que simplifica la interfaz de programación. Permite establecer convenciones que pueden ser reutilizadas clase tras clase.

En lugar de inventar un nuevo nombre para cada nueva función que agregamos a un programa, los mismos nombres pueden ser reutilizados. La interfaz de programación puede ser descrita como un conjunto de comportamientos abstractos, al margen de las clases que los implementan.

Por ejemplo, supongamos que deseamos reportar la cantidad de agua utilizada por un objeto Aparato durante un período determinado de tiempo. En lugar de definir un método cantidadConsumida para la clase Aparato, un método cantidadEntregadaEn- Grifo para una clase Grifo, y un método usoAcumulado para una clase Edificio, sólo tenemos que definir un método aguaUtilizada para cada clase. Esta consolidación reduce el número de métodos utilizados para lo que conceptualmente resulta ser la misma operación.

El polimorfismo también permite aislar al código en los métodos de diferentes objetos en lugar de agruparse en una única función que enumere todos los casos posibles. Esto hace que el código que escribamos sea más extensible y reutilizable.

Cuando llegue un caso nuevo, no tenemos que volver a implementar el código existente; sólo tenemos que añadir una clase nueva con un método nuevo, dejando sólo al código que ya está escrito.

Por ejemplo, supongamos que tenemos un código que hace una llamada al método de dibujado de un objeto. Dependiendo del objeto, el método puede producir una de dos posibles imágenes.

Cuando deseamos agregar un tercer caso, no tenemos que cambiar el método o alte- rar el código existente; sólo permitir que otro objeto pueda también hacer su propia implementación del método de dibujado. 56 1. MARCO TEÓRICO

1.7.3. Sobrecarga

Los términos polimorfismo y sobrecarga de parámetros se refieren básicamente a lo mismo, pero desde puntos de vista un poco diferentes. El polimorfismo toma un punto de vista pluralista y señala que varias clases pueden tener cada uno un método con el mismo nombre.

La sobrecarga de parámetros toma el punto de vista del nombre del método y señala que puede tener efectos diferentes en función de los parámetros que se le pasan.

La sobrecarga de operadores es similar. Se refiere a la capacidad de convertir los ope- radores del lenguaje (como == y + en lenguaje C) en métodos a los que se puedan asignar significados particulares para determinados tipos de objetos.

Java implementa el polimorfismo de los nombres de los métodos, pero no la sobrecarga de parámetros o de operadores.

1.7.4. Herencia

La manera más fácil de explicar algo nuevo es comenzar con algo ya comprendido. Si queremos describir lo que es una goleta, es de ayuda si nuestros oyentes ya saben lo que es un barco de vela. Si queremos explicar cómo funciona un clavicordio, es mejor si podemos asumir que nuestra audiencia ya ha observado el interior de un piano, o ha visto una guitarra siendo tocada, o al menos que está familiarizada con la idea de un instrumento musical.

Lo mismo es cierto si queremos definir un nuevo tipo de objeto; la descripción es más sencilla si se puede empezar a partir de la definición de un objeto existente.

Con esto en mente, los lenguajes de programación orientados a objetos nos permiten basar una definición de clase nueva en una clase ya definida. La clase base se denomina superclase; la nueva clase es su subclase. La definición de la subclase sólo especifica en qué se diferencía de la superclase; todo lo demás se toma para ser la misma.

Nada se copia de la superclase a la subclase. En cambio, las dos clases están conectados de manera que la subclase hereda todos los métodos y variables de instancia de su superclase, todo lo que queramos que nuestros oyentes comprendan de las goletas lo heredan de lo que ya saben acerca de los veleros.

Si la definición de la subclase estuviera vacía (si no se definen variables de instancia ni métodos propios), las dos clases serían idénticas (a excepción de sus nombres) y 1.7. MECANISMOS DE ABSTRACCIÓN 57 compartirían la misma definición. Sería como explicar lo que es un violín folclórico diciendo que es exactamente igual a un violín clásico.

Sin embargo, la razón por la que se declara una subclase no es para generar sinónimos; es para crear algo por lo menos un poco diferente de su superclase. Por ejemplo, es posible extender el comportamiento del violín para que pueda tocar música country, además de música clásica.

Cualquier clase puede ser utilizada como una superclase para una nueva definición de clase. Una clase puede ser al mismo tiempo una subclase de otra clase, y una superclase para sus propias subclases. De este modo, cualquier número de clases pueden vincularse en una jerarquía de herencia, tal como la representada en la figura 1.4.

Figura 1.4 Una jerarquía de herencia

Cada jerarquía de herencia empieza con una clase raíz que no tiene superclase. De la clase raíz, descienden las ramas de la jerarquía. Cada clase hereda de su superclase y, a través de su superclase, de todas las clases por encima de ella en la jerarquía. Cada clase hereda de la clase raíz.

Cada clase es la acumulación de todas las definiciones de clase en su cadena de heren- cia. En el ejemplo anterior, la clase D hereda tanto de C (su superclase) como de la clase raíz. Los miembros de la clase D tienen métodos y variables de instancia definidas en las tres clases: D, C, y la raíz.

Normalmente, cada clase tiene sólo una superclase y puede tener un número ilimitado de subclases. Sin embargo, en algunos lenguajes de programación orientados a objetos (aunque no en Java), una clase puede tener más de una superclase; puede heredarse a 58 1. MARCO TEÓRICO

través de múltiples fuentes.

En lugar de tener una única jerarquía con las ramas hacia abajo, como se muestra en la figura 1.4, la herencia múltiple permite a algunas ramas de la jerarquía (o de diferentes jerarquías) fusionarse.

Una subclase puede efectuar tres tipos de cambios a la definición que hereda a través de su superclase:

Puede ampliar la definición de clase que hereda añadiendo nuevos métodos y variables de instancia. Esta es la razón más común para definir una subclase. Las subclases siempre añaden nuevos métodos y añaden nuevas variables de instancia si los métodos lo requieren.

Puede modificar el comportamiento que hereda mediante la sustitución de un método existente con una versión nueva. Esto se hace simplemente implementando un método nuevo con el mismo nombre que uno que ha sido heredado. La versión nueva reemplaza la versión heredada. (El método heredado no desaparece, sino que sigue siendo válido para la clase que lo definió y otras clases que lo heredan.)

Puede refinar o extender el comportamiento que hereda mediante la sustitución de un método existente con una versión nueva, pero conservando aún la versión anterior mediante su incorporación en el método nuevo. Una subclase envía un mensaje para ejecutar la versión antigua en el cuerpo del método nuevo. Cada clase dentro de una cadena de herencia puede aportar parte de la conducta de un método. En la figura 1.4, por ejemplo, la clase D puede reemplazar un método definido en la clase C e incorporar la versión de C, mientras que la versión de C incorpora una versión definida en la clase raíz.

Así las subclases tienden a completar la definición de la superclase, haciéndola más específica y especializada. Añaden, y a veces reemplazan, código en lugar de eliminarlo. Tengamos en cuenta que los métodos generalmente no pueden ser desheredados y que las variables de instancia no pueden quitarse o anularse.

Los ejemplos clásicos de una jerarquía de herencia son tomados de las taxonomías de animales y plantas. Por ejemplo, podría haber una clase correspondiente a la de la familia de árboles Pináceas. Sus subclases podrían ser Abeto, Picea, Pino, Cicuta, Alerce, AbetoDouglas y Cedro; que corresponden a los distintos géneros que componen la familia.

La clase Pino podría tener las subclases PinoBlando y PinoDuro, con PinoBlanco, PinoAzúcarPinoPiñasErizadas como subclases de PinoBlando; y PinoPonderosa, Pi- 1.7. MECANISMOS DE ABSTRACCIÓN 59 noJack, PinoMonterrey y PinoRojo como subclases de PinoDuro.

Rara vez hay una razón para programar una taxonomía de este tipo, pero se trata de una buena analogía. Las subclases tienden a especializar una superclase o adaptarla para un propósito especial, tanto como una especie especializa un género.

Éstos son algunos de los usos típicos de la herencia:

La reutilización de código. Si dos o más clases tienen algunas cosas en común, pero también difieren en algunos aspectos, los elementos comunes se pueden poner en una sola definición de clase que las otras clases heredan. El código común es compartido y sólo necesita ser implementado una sola vez.

Por ejemplo, los objetos Grifo, Válvula y Tubería, definidos para el programa que modela el uso del agua, todos necesitan una conexión a una fuente de agua y deben ser capaces de registrar la velocidad del flujo. Estos elementos comunes se pueden codificar una sola vez, en una clase de la que hereden las clases Grifo, Válvula y Tubería. Un objeto Grifo puede decirse que es una especie de objeto Válvula, así que quizás la clase Grifo heredaría la mayor parte de lo que es de Válvula, y añadir poco de lo que le es propio.

La creación de un protocolo. Una clase puede declarar una serie de métodos que se espera que sean implementados por sus subclases. La clase podría tener ver- siones vacías de los métodos, o podría implementar versiones parciales que serían incorporadas en los métodos de la subclase. En cualquier caso, sus declaraciones establecen un protocolo que deben seguir todas sus subclases.

Cuando diferentes clases implementan métodos de nombre similar, un programa está en mejores condiciones para hacer uso del polimorfismo en su diseño. La crea- ción de un protocolo que deban implementar las subclases ayuda al cumplimiento de estos convenios.

La entrega de funcionalidad genérica. Un implementador puede definir una clase que contenga una gran cantidad de código básico y general para resolver un problema, pero eso no resuelve todos los detalles. Otros implementadores pueden crear subclases que adapten la clase genérica a sus necesidades específicas. Por ejemplo, la clase Aparato en el programa que modela el uso del agua podría definir un dispositivo genérico que utilice agua al que las subclases convertirían entonces en tipos específicos de aparatos.

La herencia es a la vez una manera de facilitar la tarea de programación de otra persona y una forma de separar los distintos niveles de la implementación. 60 1. MARCO TEÓRICO

Hacer ligeras modificaciones. Cuando la herencia es utilizada para entregar fun- cionalidad genérica, para establecer un protocolo o para la reutilización de código, se ideó una clase de la que se espera que otras clases hereden. Pero también se puede utilizar la herencia para modificar las clases que no estén destinadas a ser superclases. Supongamos, por ejemplo, que hay un objeto que funcionaría bien en nuestro programa, pero al que nos gustaría cambiar una o dos cosas de las que hace. Podemos hacer los cambios en una subclase.

Previsualización de posibilidades. Las subclases también pueden ser utilizadas para factorizar alternativas con fines de prueba. Por ejemplo, si una clase va a codificarse con una interfaz de usuario en particular, las interfaces alternativas pueden factorizarse en subclases durante la fase de diseño del proyecto. A conti- nuación, se puede demostrar cada alternativa a los usuarios potenciales para ver cuál prefieren. Cuando se hace la elección, la subclase seleccionada puede ser reintegrada en su superclase. 1.8. PATRONES DE DISEÑO 61

1.8. Patrones de Diseño

Los patrones de diseño son soluciones o plantillas que plantean la forma de resolver problemas específicos de diseño en la programación orientada a objetos.

En primera instancia, se podría pensar que simplemente se trata de componentes de software. Pero en realidad esa no resulta ser exactamente una metáfora apropiada para los patrones de diseño. Los componentes, ensamblados, y elementos similares, son elementos de reutilización, y ese no es necesariamente un asunto del que se ocupen los patrones de diseño.

Los patrones de diseño están enfocados en resolver cómo clases específicas, y cómo un código específico dentro de una base específica de código, se relacionan entre sí.

Además, estas recetas para la solución de problemas no tienen que ver con algorit- mos, por lo que no veremos, por ejemplo, un “Patrón Ordenamiento de Burbuja” (“Bubblesort Pattern”).

El ordenamiento de burbuja no es un patrón. Es un algoritmo definido. Un patrón estaría más centrado en cómo los diferentes elementos de clases se relacionan entre sí al estar siendo diseñados para hacer frente a un tipo de problema recurrente y muy común. Y se les dan nombres a estos patrones. Cada patrón presentado tiene un nombre, para poder hacer referencia a cada uno en particular, y así entender de lo que trata cada uno de ellos.

Y los patrones de diseño se centran de lleno en el ámbito del diseño de sistemas y aplicaciones. Hay algunos patrones de nivel superior, y algunos de nivel inferior. Así que se tienen patrones que abordan temas que se encuentran en las arquitecturas empresariales y de servicios, y conceptos de muy alto nivel por el estilo. También se tienen patrones que funcionan a un nivel muy, muy bajo, y tratan con cosas como la forma de crear estructuras de datos que se hagan a sí mismas de fácil acceso para el enlace de datos.

Hay todo tipo de patrones desde un bajo nivel hasta un alto nivel, y todos los demás en un rango intermedio. Y es importante señalar que estas son abstracciones por encima del código. Se utilizan ciertos términos al hablar de patrones, como visión, o modelo, y cuando una clase realmente se está creando dentro de una solución de software, no hay nada que diga que esa clase deba ser nombrada modelo.

Por lo tanto, esto es realmente una abstracción, una idea humana que se ubica por encima del código. Los archivos que contienen al código podrán nombrarse de cualquier manera. Y podrán contener métodos denominados de cualquier otra, pero al definir 62 1. MARCO TEÓRICO

cómo esas clases se unen para formar un patrón de diseño, el enfoque está en la estructura de las interfaces entre esas clases.

Se utiliza la palabra colaboradores cuando se habla de las relaciones entre las clases que participan en un patrón particular. Los colaboradores son clases que normalmente van a interactuar con el patrón, o que inclusive podrían estar en el mismo patrón.

Y es importante recordar que los patrones se enfrentan con problemas que ya han sido encontrados por alguien más. Y a todos nos gusta pensar que somos especiales, pero la verdad del asunto es que en algún lugar del camino, alguien probablemente ya ha visto este problema, o un problema muy similar al que nos estaremos centrado en un momento dado.

Particularmente, si nuestra labor es la misma que están haciendo la mayoría de los desarrolladores de software en el mundo, que es la de implementar formas por encima de datos, en el tipo de aplicaciones de línea de negocio. Si ese es el tipo de trabajo en el que resulta que estamos involucrados, los patrones de diseño nos prometen una mejora al brindarnos algunas plantillas que seguir para las cosas que ocurren a diario en el desarrollo de software.

Ahora los patrones, como ya se ha mencionado, no tienen que ver con algoritmos como el ordenamiento de burbuja, y tampoco tienen que ver con implementaciones específicas. Y eso es muy importante tenerlo en cuenta debido a que la intención de los patrones de diseño es la de darnos un punto de partida para resolver una solución.

Un patrón de diseño no prescribe cada línea de código que hay que escribir con el fin de resolver un problema en particular, porque, aún a pesar de que veamos estos patrones lógicos recurrentes en nuestro código, las situaciones realmente difieren.

1.8.1. Historia de los Patrones de Diseño

Ahora, ¿de dónde se originó toda esta idea de los patrones de diseño en un principio? Resulta que los patrones de diseño no se originaron con el desarrollo de software. De hecho, se originaron con un hombre llamado Christopher Alexander, quien era un exitoso arquitecto de edificios en el sentido clásico. Nada que ver con la arquitectura de software.

Este señor ha sido el responsable de más de 200 edificios en todo el mundo en Europa, el Sudeste de Asia y Japón. Ahora, en 1977, Christopher Alexander presentó un libro, “Un Lenguaje de Patrones: Ciudades, Edificios, Construcción” (“A Pattern Language: Towns, Buildings, Construction”). Y en este libro, el Sr. Alexander propone que hay 1.8. PATRONES DE DISEÑO 63 diferentes patrones de diseño arquitectónico que pueden ser reconocidos, y que se pueden reutilizar en donde se considere apropiado.

Como ejemplo, tenemos un edificio en la figura 1.5. Podemos reconocer de inmediato que sin duda la arquitectura general de este edificio es Romana Clásica de origen. Ahora ¿por qué podemos ver eso? Debido a que nuestros ojos están seleccionando ciertos patrones dentro de la imagen del edificio, donde por ejemplo podemos ver la forma triangular del techo en la parte superior, con el vértice justo en la parte media.

Figura 1.5 Patrones en un Edificio

Hay un patrón de ese techo, y resulta que hay varios patrones de techos en la arqui- tectura, y eso es una clasificación para tipos de patrones específicos. Además, podemos ver que el techo está sostenido por unas columnas, y que cada una de estas columnas tiene una parte superior y una parte inferior con características específicas de diseño, que se muestran en la figura 1.6, y que podemos tomar prestadas, y reutilizar esas características de diseño conforme vayamos construyendo un nuevo edificio.

Ese fue todo el concepto detrás del libro sobre lenguaje de patrones que escribió Chris- topher Alexander, y que resonó en las mentes de Kent Beck y Ward Cunningham, quienes tomaron su idea en torno a la clasificación de los patrones, y la aplicaron al desarrollo de software.

Ellos presentaron su trabajo en la Conferencia de Programación, Sistemas, Lenguajes y Aplicaciones Orientados a Objetos (OOPSLA: Object-Oriented Programming, Systems, Languages & Applications) en 1987. Así que los patrones tienen claramente una historia muy larga, y muy amplia hoy en día. 64 1. MARCO TEÓRICO

Figura 1.6 Patrones en unas Columnas

Probablemente una de las obras más seminales sobre el tema de los patrones de diseño en el desarrollo de software se trata del libro “Patrones de Diseño: Elementos de Software Reutilizable Orientado a Objetos” (“Design Patterns: Elements of Reusable Object-Oriented Software”), escrito y publicado en 1894 por la notoria “Pandilla de Cuatro” (“Gang of Four”), integrada por Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.

El libro, que ha sido una gran influencia en el campo de la ingeniería de software, también tiene una reputación de ser no sólo muy exhaustivo, sino también de ser un poco difícil de digerir. Es considerado una obra fundamental y frecuentemente se hace referencia a él, ya que fue el primero en traer muchos de los patrones de diseño formales que conocemos y usamos hoy en día de una forma documentada.

1.8.2. Organización y Lenguaje de Patrones

Al hablar de patrones, usaremos algo llamado lenguaje de patrones, y un lenguaje de patrones comienza en un nivel muy alto, al reconocer que hay ciertas categorías o clasificaciones de los patrones en sí mismos, y posteriormente se le asigna un nombre a cada patrón.

Así, por ejemplo, aquí tenemos una lista de patrones de diseño con nombre, todos los cuales de alguna forma entran en una clasificación, o categoría conocida como patrones creacionales:

Fábrica Abstracta (Abstract Factory)

Constructor Virtual (Builder)

Método de Fabricación (Factory Method)

Prototipo (Prototype) 1.8. PATRONES DE DISEÑO 65

Instancia Única (Singleton)

Ahora, los patrones creacionales están centrados sobre todo en la manera de crear instancias de objetos en tiempo de ejecución. Y las circunstancias de cómo lo hacen son definitivamente diferentes dependiendo de cuál es el problema que estamos tratando de resolver.

Cada uno de estos patrones se centra en un escenario diferente, e introduce una plantilla para la forma en que podríamos resolver ese escenario particular en nuestro código.

Una lista de las clasificaciones para los patrones de diseño se muestra a continuación, y como puede verse, se trata de una lista bastante larga, y sin duda esta lista que tenemos aquí no es exhaustiva:

Creacionales

Estructurales

Comportamiento

Seguridad

Concurrencia

Lenguaje Estructurado de Consultas (SQL)

Interfaz de Usuario

Relacional

Social

Distribuido

Desde luego que la lista no está completa, ya que el conjunto general de conocimientos en torno a los patrones de diseño de software está creciendo todo el tiempo, y exis- ten varios aspectos asociados con los patrones de diseño de software, tales como los patrones de diseño orientados a objetos.

Existen patrones para la programación funcional y también existen patrones para la programación en paralelo. Eso nos lleva a pensar que el conjunto de patrones de diseño se mantiene en constante crecimiento, probablemente por mucho tiempo, conforme el arte del desarrollo de software va madurando, y nos encontremos con cada vez más clasificaciones para los patrones de software, y con una mayor cantidad de los propios patrones de software. 66 1. MARCO TEÓRICO

1.8.3. La Importancia de los Patrones

Ya se ha mencionado lo que son los patrones de diseño y de dónde vienen, ahora bien, ¿porque deberían importarnos?

Una de las mayores razones por las que los patrones de diseño son importantes para nosotros es porque le da a nuestra profesión de desarrollo de software un lenguaje. Se trata de un lenguaje profesional que podemos utilizar con los demás.

Imaginemos, por ejemplo, a un grupo de carpinteros que se reúnen para realizar un trabajo en común. Estos carpinteros pueden haber sido formados en diferentes luga- res. Han asistido a diferentes escuelas de carpintería, y todos ellos tienen diferentes experiencias. Sin embargo, podemos estar seguros de que todos y cada uno de esos carpinteros sabrá, cuando miren a un dibujo como el de la figura 1.7, que están viendo un Ensamblaje Espiga.

Figura 1.7 Ensamblaje Espiga Compuesto

Existe un término para el tipo de unión que estamos viendo, el Ensamblaje Espiga, y los carpinteros lo saben. Ahora, si observamos detenidamente a este ensamblaje espiga en particular, veremos que no sigue la definición clásica de un ensamblaje espiga, como el que se muestra en la figura 1.8. Podemos reconocer el patrón de un ensamblaje espiga en lo que vemos. Además, a pesar de que ha habido una variación sobre el original después de que el carpintero se puso a trabajar en el ensamblaje de la figura 1.7, cualquier otro carpintero profesional será capaz de verlo y reconocerlo de inmediato como un ensamblaje espiga.

Esto hace que el trabajo dentro de un equipo absolutamente se acelere cuando los desarrolladores puedan mirarse el uno al otro, y simplemente decir: “¿Sabes?, debemos utilizar un Constructor Virtual aquí. Y aquí, debemos utilizar un Método de Fabri- 1.8. PATRONES DE DISEÑO 67

Figura 1.8 Ensamblaje Espiga

cación”, y si logramos entender lo que eso significa, nos ayudará a ser mucho más eficaces.

Esto nos lleva al establecimiento de la profesionalidad de nuestro oficio en la forma de un lenguaje compartido. Y uno de sus beneficios que no resulta menos importante, es la idea de que los patrones de diseño nos pueden ayudar a evitar que estemos constantemente reinventando soluciones que ya han sido resueltas.

Y es importante reconocer que estos patrones de diseño están destinados a propor- cionarnos un punto de partida, una plantilla, si se quiere, como en Microsoft Word cuando creamos un nuevo currículum. Todavía tenemos que completar más detalles de implementación. Sin embargo, tenemos un formato general, y una idea general de qué es lo que vamos a producir, y eso nos ayuda a ser mucho más eficaces al no tener que centrarnos en los detalles de bajo nivel.

Los patrones de diseño nos dan el mismo tipo de ventaja que obtenemos a partir de las plantillas. Ahora, da la casualidad de que lo que hacen los patrones de diseño es proporcionar una abstracción humana comprensible por encima de gran parte de nuestro código. Y al hacerlo, tiene el efecto secundario de mejorar en general el diseño de nuestro código, de nuestros sistemas y de nuestra arquitectura de la aplicación.

Cuando utilizamos patrones de diseño, a menudo obtenemos código que tiene una mucho mejor separación de objetivos, responsabilidades claras para cada una de las clases, y que es mucho más fácil de leer y mantener. Así que, en general, mejora la calidad del código en el que estamos trabajando cuando usamos los patrones para expresar nuestras soluciones. 68 1. MARCO TEÓRICO

1.9. Clasificación de los Patrones de Diseño

El conjunto de los patrones de diseño orientados al desarrollo de software en general se clasifican en tres grupos principales: Creacionales, Estructurales y de Comportamiento; enlistados en el cuadro 1.1.

Cuadro 1.1 Patrones de Diseño Clasificación Nombre Nombre Original (en Inglés) Fábrica Abstracta Abstract Factory Constructor Virtual Builder Creacionales Método de Fabricación Factory Method Prototipo Prototype Instancia Única Singleton Adaptador Adapter Puente Bridge Objeto Compuesto Composite Estructurales Decorador Decorator Fachada Facade Peso Ligero Flyweight Apoderado Proxy Cadena de Responsabilidad Chain of Responsibility Orden Command Intérprete Interpreter Iterador Iterator Mediador Mediator De Comportamiento Recuerdo Memento Observador Observer Estado State Estrategia Strategy Método Plantilla Template Method Visitante Visitor

1.9.1. Patrones de Diseño Creacionales

Estos patrones de diseño se encargan de la creación de instancias de clase. Este tipo de patrón puede ser dividido en patrones de creación de clases y en patrones de creación de objetos. Mientras que los patrones de creación de clases utilizan la herencia de manera efectiva en el proceso de creación de instancias, los patrones de creación de objetos utilizan la delegación de manera efectiva para lograr hacer el trabajo.

Fábrica Abstracta (Abstract Factory). Proporciona una interfaz para permitir la 1.9. CLASIFICACIÓN DE LOS PATRONES DE DISEÑO 69

creación de familias de objetos relacionados o dependientes sin tener que especi- ficar sus clases concretas.

Constructor Virtual (Builder). Mueve la lógica de construcción para un objeto fuera de la clase que será instanciada.

Método de Fabricación (Factory Method). Permite al desarrollador de una clase que defina la interfaz para la creación de un objeto mientras se retiene el control de cuáles clases instanciar.

Prototipo (Prototype). Provee objetos nuevos copiando un ejemplo en lugar de traer una instancia nueva, no inicializada de una clase.

Instancia Única (Singleton). Se asegura que una clase tenga sólo una instancia y proporciona un punto de acceso global a ella.

1.9.2. Patrones de Diseño Estructurales

Estos patrones de diseño se encargan de la composición de Clases y Objetos. Los pa- trones estructurales de creación de clases utilizan la herencia para componer interfaces. Los patrones estructurales de objetos definen maneras para componer objetos y obtener una nueva funcionalidad.

Adaptador (Adapter). Proporciona la interfaz que un cliente espera mientras utiliza los servicios de una clase con una interfaz diferente.

Puente (Bridge). Desvincula una abstracción de la implementación de sus opera- ciones abstractas, de modo que la abstracción y su implementación puedan variar de forma independiente.

Objeto Compuesto (Composite). Permite a los clientes tratar de manera uniforme tanto a objetos individuales como a composiciones de objetos.

Decorador (Decorator). Permite escribir variaciones nuevas de una operación en tiempo de ejecución.

Fachada (Facade). Proporciona una interfaz que haga que un subsistema sea fácil de usar.

Peso Ligero (Flyweight). Utiliza el intercambio para apoyar un gran número de objetos muy detallados de manera eficiente.

Apoderado (Proxy). Controla el acceso a un objeto, proporcionando un sustituto, o marcador de posición, para ello. 70 1. MARCO TEÓRICO

1.9.3. Patrones de Diseño de Comportamiento

Estos patrones de diseño se encargan de la comunicación entre objetos de Clases. Los patrones de comportamiento son aquellos patrones que tienen que ver más específica- mente con la comunicación entre objetos.

Cadena de Responsabilidad (Chain of Responsibility). Evita el acoplamiento del remitente de una solicitud con su receptor, dando a más de un objeto la oportunidad de manejar la petición.

Orden (Command). Encapsula una orden dentro de un objeto.

Intérprete (Interpreter). Nos permite escribir objetos ejecutables de acuerdo con un conjunto de reglas de escritura que nosotros definamos.

Iterador (Iterator). Provee una forma de acceder secuencialmente a los elementos de una colección.

Mediador (Mediator). Define un objeto que encapsula cómo interactúan un con- junto de objetos; esto promueve el bajo acoplamiento, evitando que los objetos se refieran el uno al otro de manera explícita, y nos permite variar su interacción de forma independiente.

Recuerdo (Memento). Provee almacenamiento y restitución del estado de un objeto.

Observador (Observer). Define una dependencia de uno a muchos entre los ob- jetos de manera que cuando un objeto cambia de estado, todos sus dependientes son notificados para que puedan reaccionar al cambio.

Estado (State). Distribuye la lógica específica del estado a través de las clases que representan el estado de un objeto.

Estrategia (Strategy). Encapsula enfoques alternativos, o estrategias, en clases separadas donde cada una implemente una operación común.

Método Plantilla (Template Method). Implementa un algoritmo en un método, posponiendo la definición de algunos pasos del algoritmo para que así otras clases los puedan redefinir.

Visitante (Visitor). Nos permite definir una operación nueva para una jerarquía sin modificar las clases de la jerarquía. 1.10. CONSIDERACIONES DE LA ORIENTACIÓN A OBJETOS 71

1.10. Consideraciones de la Orientación a Objetos

1.10.1. Beneficios y Objetivos

La programación orientada a objetos establece seis objetivos primordiales para el desa- rrollo de software; esforzándose por producir software que tenga las siguientes carac- terísticas:

Natural. La programación orientada a objetos produce un software natural. Los programas naturales son más comprensibles. En lugar de programar en términos de una matriz de datos o de una región de la memoria, podemos programar usando la terminología de nuestro problema en particular. No tenemos que enre- darnos en los detalles de la computadora mientras diseñamos nuestro programa. En lugar forzar que nuestros programas se ajusten al lenguaje del mundo de la computadora, La orientación a objetos nos da la libertad para expresar nuestro programa en los términos de nuestro problema.

La programación orientada a objetos nos permite dar forma a un problema a nivel funcional, no a nivel de la implementación. No es necesario que sepamos cómo funciona alguna pieza de software con el fin de utilizarla: sólo tenemos que concentrarnos en lo que hace.

Confiable. Con el fin de crear un software útil, necesitamos crear un software que sea tan confiable como otros productos, tales como refrigeradores y aparatos de televisión. Por ejemplo, podemos recordar ¿cuándo fue la última vez que se nos descompuso el horno de microondas?

Los programas orientados a objetos, bien diseñados y cuidadosamente escritos son confiables. Su naturaleza modular de objetos nos permite hacer cambios en una parte de nuestro programa sin afectar a otras partes. Los objetos aíslan el conocimiento y la responsabilidad en el lugar al que pertenecen.

Una forma de aumentar la fiabilidad es a través de pruebas exhaustivas. La orien- tación a objetos mejora las pruebas, ya que permite aislar el conocimiento y la responsabilidad en un solo lugar. Este aislamiento nos permite probar y validar ca- da componente de forma independiente. Una vez que validamos un componente, podemos utilizarlo con confianza.

Reutilizable. ¿Un constructor inventa un nuevo tipo de ladrillo cada vez que construye una casa? ¿Un ingeniero eléctrico inventa un nuevo tipo de resistencia cada vez que diseña un circuito? Entonces, ¿por qué los programadores insistimos 72 1. MARCO TEÓRICO

en “reinventar la rueda”? Una vez que hemos resuelto un problema, debemos volver a utilizar la solución.

Podemos volver a utilizar fácilmente las clases orientadas a objetos bien diseñadas. Al igual que con los módulos, podemos reutilizar objetos en muchos programas diferentes. A diferencia de los módulos, la programación orientada a objetos intro- duce la herencia para permitirnos ampliar los objetos existentes y el polimorfismo para permitirnos escribir un código genérico.

La orientación a objetos no nos garantiza un código genérico. La creación de clases bien elaboradas es una habilidad difícil que requiere concentración y una atención a la abstracción. Ello no siempre se nos facilita a los programadores.

A través de la programación orientada a objetos podemos modelar las ideas gene- rales y usar esas ideas generales para resolver problemas específicos. A pesar de que vayamos a construir objetos para resolver un problema específico, a menudo construiremos éstos objetos específicos utilizando piezas genéricas.

Mantenible. El ciclo de vida de un programa no termina cuando finalmente lo entregamos al usuario. En realidad, a partir de ese momento, debemos comenzar a darle mantenimiento a nuestra base de código. De hecho, entre el 60 % y 80 % del tiempo dedicado a trabajar en un programa es para darle mantenimiento. Es decir, que el desarrollo representa tan sólo el 20 % del tiempo destinado a crear un programa.

Un código orientado a objetos bien diseñado es fácil de mantener. Con el fin de corregir un error, sólo tenemos que corregir el problema en un solo lugar. Dado que un cambio en la implementación es transparente, todos los demás objetos se beneficiarán automáticamente de la mejora. El lenguaje natural del código debe permitir a otros desarrolladores que también entiendan la mejora que se implementó.

Extensible. Al igual que nosotros debemos darle mantenimiento a un programa, los usuarios nos van a pedir que les ayudemos a añadir nuevas funcionalidades a su sistema. A medida que construimos una biblioteca de objetos, también podemos querer ampliar la funcionalidad de nuestros propios objetos.

La programación orientada a objetos se ocupa de estas realidades. El software no es estático. El software debe crecer y cambiar con el tiempo con el fin de seguir siendo útil. La programación orientada a objetos nos brinda a los programadores un número de características con el fin de extender nuestro código. Estas caracte- rísticas incluyen la herencia, el polimorfismo, la sobrecarga, la delegación, y una 1.10. CONSIDERACIONES DE LA ORIENTACIÓN A OBJETOS 73

variedad de patrones de diseño.

Oportuno. El ciclo de vida de un proyecto de software moderno a menudo se mide en semanas. La programación orientada a objetos es de ayuda con estos ciclos de desarrollo rápido. La programación orientada a objetos recorta tiempo del ciclo de desarrollo al proporcionar un software confiable, reutilizable y fácilmente extensible.

Un software natural simplifica el diseño de sistemas complejos. Si bien no se puede ignorar un diseño cuidadoso, el software natural puede agilizar los ciclos de diseño, ya que podemos concentrarnos en el problema que se está tratando de resolver.

Cuando descomponemos un programa en una serie de objetos, el desarrollo de cada pieza puede realizarse en paralelo. Varios desarrolladores pueden trabajar en clases de forma autónoma. Tal desarrollo paralelo conduce a tiempos de desarrollo más rápidos.

1.10.2. Reutilización

Uno de los objetivos principales de la programación orientada a objetos es hacer que el código que se escriba sea lo más reutilizable posible: para que sirva en diferentes situaciones y aplicaciones de modo que podamos evitar volver a implementar algo que ya se ha hecho, así sea con ligeras diferencias.

La reutilización está influenciada por factores tales como los siguientes:

Qué tan confiable y libre de errores es el código

Qué tan clara es la documentación

Qué tan simple y sencilla es la interfaz de programación

Qué tan eficazmente realiza sus tareas el código

Qué tan completo es su conjunto de características

Estos factores no sólo se aplican al modelo de objetos. También pueden utilizarse para juzgar la reutilización de cualquier código: tanto funciones estándar en un lenguaje basado en procedimientos, así como las definiciones de clases en un lenguaje orienta- do a objetos. Las funciones eficientes y bien documentadas, por ejemplo, serían más reutilizables que aquellas sin documentar y poco confiables. 74 1. MARCO TEÓRICO

Sin embargo, una comparación general mostraría que las definiciones de clases se prestan más para volverse un código reutilizable de una forma en que las funciones no lo hacen.

Hay varias cosas que podían hacerse para que las funciones fueran más reutilizables: por ejemplo, pasar los datos como parámetros en lugar de asumir variables globales denominadas específicamente. Aun así, resulta que sólo un pequeño subconjunto de funciones podría generalizarse más allá de las aplicaciones para las que fueron dise- ñadas originalmente. Su reutilización estaba inherentemente limitada en al menos tres maneras:

Los nombres de las funciones son globales; cada función debe tener un nombre único. Este requisito de nomenclatura hace que sea difícil confiar en gran me- dida en el código de la biblioteca al construir un sistema complejo. La interfaz de programación sería difícil de aprender y tan extensa que no podría capturar fácilmente generalizaciones significativas.

Las clases, por otro lado, pueden compartir interfaces de programación. Cuando las mismas convenciones de nomenclatura se utilizan una y otra vez, se puede empaquetar una gran cantidad de funcionalidad en una interfaz relativamente pequeña y fácil de entender.

Las funciones se seleccionan de una biblioteca una a la vez. Depende de los programadores escoger y elegir las funciones individuales que necesitan.

Por el contrario, los objetos vienen como paquetes de funcionalidad, no como métodos y variables de instancia individuales. Proporcionan servicios integrados, por lo que los usuarios de una biblioteca orientada a objetos no quedarán empan- tanados armando sus propias soluciones a un problema.

Las funciones están típicamente ligadas a determinados tipos de estructuras de datos concebidas para un programa específico. La interacción entre los datos y la función es una parte inevitable de la interfaz. Una función es útil sólo para aquellos que están de acuerdo en utilizar el mismo tipo de estructuras de datos que acepta como parámetros.

Debido a que esconde sus datos, un objeto no tiene este problema. Esta es una de las principales razones de que las clases se puedan reutilizar más fácilmente que las funciones.

Los datos de un objeto están protegidos y no serán afectados por ninguna otra parte del programa. Por lo tanto los métodos pueden confiar en su integridad. Pueden es- 1.10. CONSIDERACIONES DE LA ORIENTACIÓN A OBJETOS 75 tar seguros de que el acceso externo no ha puesto los datos en un estado ilógico o insostenible.

Como resultado, una estructura de datos de objeto es más fiable que una pasada a una función, y los métodos pueden depender más de ello. Los métodos reutilizables son en consecuencia más fáciles de escribir.

Por otra parte, ya que los datos de un objeto están ocultos, una clase puede ser reim- plementada para utilizar una estructura de datos diferente sin afectar su interfaz. Todos los programas que utilizan la clase pueden seleccionar la nueva versión sin cambiar ningún código fuente; no se requiere una reprogramación.

1.10.3. Trampas Comunes

Existen cuatro trampas comunes en las que debemos evitar caer cuando utilicemos la programación orientada a objetos:

Pensar en la programación orientada a objetos como simplemente un lengua- je. A menudo la gente equipara lenguajes orientados a objetos con programación orientada a objetos. El error surge cuando suponemos que estamos programando de forma orientada a objetos, simplemente porque utilizamos un lenguaje orien- tado a objetos. Nada mas lejos de la verdad.

La programación orientada a objetos es mucho más que simplemente utilizar un lenguaje orientado a objetos o conocer un cierto conjunto de definiciones. Se puede escribir un código terrible no orientado a objetos en un lenguaje orientado a objetos. La verdadera programación orientada a objetos es un modo de pensar que nos reta a que veamos nuestros problemas como un grupo de objetos y a que utilicemos correctamente la encapsulación, la herencia y el polimorfismo.

Desafortunadamente, muchas empresas y programadores asumen que si simple- mente utilizan un lenguaje orientado a objetos podrán disfrutar de todos los beneficios que ofrece la programación orientada a objetos. Cuando fallan, tienden a culpar a la tecnología, no al hecho de que no capacitaron correctamente a sus empleados o que se engancharon a un concepto de programación popular sin comprender realmente lo que significaba.

Temerle a la reutilización. Debemos aprender a reutilizar el código. Aprender a reutilizar sin culpa es a menudo una de las lecciones más difíciles de aprender la primera vez que utilizamos la programación orientada a objetos. Tres problemas nos conducen a esta dificultad. 76 1. MARCO TEÓRICO

En primer lugar, a los programadores nos gusta crear. Si nos fijamos en la re- utilización de la manera equivocada, parecerá que se lleva con ella algunos de los placeres de hacer creaciones. Sin embargo, es necesario recordar que vamos a reutilizar piezas con el fin de crear algo más grande que la pieza que se está volviendo a utilizar. Puede que no nos parezca emocionante volver a utilizar un componente, sino que nos permitirá construir algo mejor.

En segundo lugar, muchos programadores sufren del sentimiento de “no fue es- crito aquí”, es decir, que no confían en el software que no haya sido escrito por ellos. Si una pieza de software está bien probada y cumple con nuestras necesi- dades, debemos volver a utilizarla. No deberíamos descartar un componente que tengamos a la mano, tan sólo por no haberlo escrito nosotros. Recordemos que la reutilización de un componente nos dejará más tiempo libre para destinarlo a escribir otro software todavía mejor.

Pensar en la orientación a objetos como una panacea. A pesar de que la programación orientada a objetos ofrece muchos beneficios, no es la panacea del mundo de la programación. Hay momentos en que no deberíamos utilizar la orientación a objetos. Todavía es necesario que actuemos con criterio en la selección de la herramienta adecuada para el trabajo en turno. Lo más importante, la programación orientada a objetos no garantiza el éxito de nuestro proyecto. Nuestro proyecto no tendrá éxito automáticamente sólo porque utilizamos un lenguaje orientado a objetos. El éxito sólo viene con una cuidadosa planificación, diseño y codificación.

Programación Egoísta. No debemos ser egoístas al programar. Del mismo modo que debemos aprender a reutilizar, también debemos aprender a compartir el código que creamos. Compartir significa que animaremos a otros desarrolladores a que usen nuestras clases. Sin embargo, el compartir también significa que haremos que sea fácil el que otros puedan reutilizar esas clases.

Debemos tomar en consideración a otros desarrolladores a la hora de programar. Hagamos interfaces limpias, comprensibles. Lo más importante, escribamos docu- mentación. Documentemos los supuestos, documentemos los parámetros de los métodos, documentemos tanto como sea posible. La gente no volverá a utilizar algo que no pueda encontrar o que no pueda entender. 2| Diseño de Software

77 78 2. DISEÑO DE SOFTWARE 2.1. CONSIDERACIONES DE DISEÑO 79

2.1. Consideraciones de Diseño

Al diseñar una Estructura para el Procesamiento de Datos (Data Processing Frame- work) lo primero a tomar en consideración es que debe permitir tanto a los diseñadores como a los programadores dedicar su tiempo a cumplir con los requerimientos especí- ficos del software (en los términos que el negocio estableciese) en lugar de tratar con los detalles de bajo nivel más estándares y más enfocados en proporcionar un sistema de trabajo, reduciendo así el tiempo de desarrollo general.

La mejor forma de lograr ese objetivo fundamental es partiendo de la separación virtual del código fuente en dos tipos diferentes de zonas: “zonas frías” y “zonas calientes”.

Las “zonas frías” de código, involucran todos los módulos de lectura, procesamiento y publicación, y se denominan de esa manera al mantenerse “congelados”, pues su funcionalidad mínima se ha establecido desde el principio y no requiere (en teoría) modificaciones mayores, lo que facilita su comprensión y documentación futura.

Las “zonas calientes” de código, involucran la configuración en el lenguaje XML, y que son denominadas así al permitir hacer cambios “en caliente” sin afectar los otros desarrollos existentes, además de permitir añadir funcionalidad adicional simplemente desarrollando y anexando nuevos procesadores de datos.

Una vez que se ha establecido la pertenencia de cada pieza de código a determinada zona, debe cuidarse que la implementación considere la mayor cantidad de casos de uso, para que no pierda su reusabilidad.

Esto es que por ejemplo, al desarrollar un lector de archivos separados por comas (CSV), su implementación considere todos los posibles casos, como el carácter que sirve de separador para las columnas de datos, que generalmente se trata del carácter coma (,), pero no necesariamente, pues podría tratarse de los caracteres | o \t. Entonces no debería codificarse pensando solamente en mantener fijo el carácter , sino que más bien debería ser lo suficientemente flexible como para aceptar cualquier carácter o secuencia de ellos.

Conforme la Estructura para el Procesamiento de Datos vaya evolucionando con dife- rentes implementaciones de necesidades específicas de procesamiento del negocio, se espera que el código fuente crezca, pero no de manera exponencial, pues debe ten- derse a crear una librería de módulos de procesamiento reutilizables que puedan ser utilizados una y otra vez en cada nuevo desarrollo.

Al mantener una configuración XML que se convierta en instancias de objetos en tiempo de ejecución nos brinda un enfoque diferente a la lógica tradicional de que cualquier 80 2. DISEÑO DE SOFTWARE

modificación a la lógica de procesamiento involucraba necesariamente un proceso de re-compilación del código fuente, que en la mayoría de los casos, era más propenso a acarrear nuevos errores por probables cambios intermedios a otras partes del código fuente.

A nivel de manejo de datos, dado que existen diferentes tipos de fuentes de datos, se ha decidido estandarizar el manejo de los datos a procesar mediante una estructura básica consistente de tablas y columnas, emulando una estructura de base de datos, pero mantenida al mínimo en lo que respecta a sus propiedades y funcionalidad, a fin de facilitar su implementación, pero permitiendo un manejo estable de los datos a la hora de ser procesados.

El resultado final también deberá ser capaz de ir evolucionando a partir de la re- factorización del código común ya existente en la empresa, en lugar de convertirse en una solución genérica que se vea forzada a adaptarse para cubrir cada caso de uso creado con cada nuevo requerimiento.

También deberá tratarse de un software elegante, en los términos de claridad, concisión y limpieza. Ello ayudará a que un nuevo programador encuentre siempre un código limpio y comprensible (y por lo tanto es fácilmente modificable), a diferencia de un código que simplemente funcione, pero que no tenga siquiera los estándares mínimos.

Esto último ayudará principalmente a que la Estructura para el Procesamiento de Datos logre superar la prueba del tiempo. Es decir, que sea capaz de evolucionar con buena apariencia de la misma forma que la tecnología subyacente en la que se construyó también vaya avanzando. 2.2. ESTRUCTURAS DE PROGRAMACIÓN 81

2.2. Estructuras de Programación

En el ámbito informático, en particular en el desarrollo de sistemas, una estructura de programación (Software Framework) es:

Una abstracción en la que el software que proporciona una funcionalidad genérica se puede cambiar de forma selectiva mediante código adicional escrito por el usuario, proporcionando así un software de aplicación específica.

Una plataforma universal de software reutilizable para desarrollar aplicaciones, productos y soluciones.

Las características principales de una estructura de programación son:

El flujo general de control del programa no está dictado por la entidad que lo invoca, sino por la estructura de programación.

Una estructura de programación tiene un comportamiento predeterminado.

Una estructura de programación puede ser ampliada por el usuario mediante reemplazos selectivos o puede especializarse mediante código de usuario que pro- porciona una funcionalidad específica.

El código de la estructura de programación, en general, no se supone que sea modificado, a menos de añadirle extensibilidad. Los usuarios pueden ampliar la estructura de programación, pero no deben modificar su código.

2.2.1. Meta-programación

La meta-programación consiste en escribir programas que escriben o manipulan otros programas (o a sí mismos) como datos, o que hacen en tiempo de compilación par- te del trabajo que, de otra forma, se haría en tiempo de ejecución. Esto permite al programador ahorrar tiempo en la producción de código.

La herramienta de meta-programación más común es el compilador, el cual permite al programador escribir un programa relativamente corto en un lenguaje de alto nivel para, posteriormente, escribir un programa equivalente en lenguaje ensamblador o lenguaje máquina. Esto, por lo general, significa un buen ahorro de tiempo si se compara con la posibilidad de escribir el programa en lenguaje máquina de forma directa.

En general, cualquier solución que manipule el código fuera de su uso “normal” es considerado meta-programación. Los enfoques basados en meta-programación tienden a 82 2. DISEÑO DE SOFTWARE

ser más complejos que las soluciones tradicionales (por ejemplo, bibliotecas y estructu- ras), pero al estar manipulando código a un nivel más fundamental, esto hace las cosas difíciles más fáciles y las cosas imposibles meramente improbables.

Todos los principales lenguajes modernos tienen algún nivel de apoyo a la meta- programación. Aprender las funciones de meta-programación de nuestro lenguaje prima- rio nos ahorrará un gran esfuerzo y abrirá nuevas vías para la búsqueda de soluciones.

2.2.2. Reflexión de código

La reflexión es la capacidad de un programa para inspeccionar su propia estructura interna y para modificar su estructura y comportamiento internos. Es un concepto útil cuando un programa tiene que ser muy adaptable y fácil de evolucionar frente a necesidades cambiantes. También es útil cuando un programa debe analizar su propio comportamiento por otras razones.

El patrón de arquitectura Reflexión, es útil cuando deseamos que la aplicación sea capaz de cambiarse a sí misma en tiempo de ejecución. Este patrón abre la puerta a aplicaciones que se adaptan cuando cambiamos de opinión acerca de lo que queremos que hagan.

La reflexión establece una distinción entre el nivel base del programa que no cambia y un nivel meta que sí cambia. El nivel base implementa la lógica de la aplicación y hace uso de la información desde el nivel meta. El nivel meta encapsula las partes internas de la aplicación que pueden cambiar en objetos meta. Los datos del nivel meta (los metadatos) describen los atributos y los comportamientos que pueden cambiar de una aplicación.

El nivel base de la aplicación interpreta los metadatos en tiempo de ejecución para adaptar la aplicación e incluir su nuevo comportamiento estructural. Para obtener una vista completa de la aplicación, debemos mirar tanto a los objetos a nivel base como a la configuración actual de los objetos meta.

La clase java.lang.Class, y el paquete de reflexión java.lang.reflect, ofrecen una serie de mecanismos para recopilar información de la Máquina Virtual de Java. Cono- cidos colectivamente como reflexión, estas funciones nos permiten cargar clases sobre la marcha, encontrar métodos y campos en las clases, para generar listados de ellos, y para invocar métodos de clases cargadas dinámicamente. Incluso existe un mecanismo para que pueda construirse una clase a partir de cero (bueno, en realidad, de una matriz de bytes), mientras que el programa se está ejecutando. 2.3. HERRAMIENTAS DE DISEÑO 83

2.3. Herramientas de Diseño

2.3.1. Lenguaje Unificado de Modelado (UML)

El Lenguaje Unificado de Modelado, o UML (Unified Modeling Language) es el lenguaje de modelado de sistemas de software más conocido y utilizado en la actualidad; está respaldado por el OMG (Object Management Group).

Es un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema. UML ofrece un estándar para describir un “plano” del sistema (modelo), incluyendo aspectos conceptuales tales como procesos de negocio, funciones del sistema, y aspectos concretos como expresiones de lenguajes de programación, esquemas de bases de datos y compuestos reciclados.

Es importante remarcar que UML es un “lenguaje de modelado” para especificar o para describir métodos o procesos. Se utiliza para definir un sistema, para detallar los artefactos en el sistema y para documentar y construir. En otras palabras, es el lenguaje en el que está descrito el modelo.

UML no puede compararse con la programación estructurada, pues UML significa Len- guaje Unificado de Modelado, no es programación, solo se diagrama la realidad de una utilización en un requerimiento. Mientras que, programación estructurada, es una forma de programar como lo es la orientación a objetos, la programación orientada a objetos viene siendo un complemento perfecto de UML, pero no por eso se toma UML sólo para lenguajes orientados a objetos.

UML cuenta con varios tipos de diagramas, los cuales muestran diferentes aspectos de las entidades representadas. El propósito del diagrama de clases es mostrar los tipos que serán modelados dentro del sistema. [25]

Diagrama 2.1 Ejemplo de Diagrama de Clase

La representación UML de una clase es un rectángulo que contiene tres compartimentos apilados verticalmente, como se muestra en el diagrama 2.1. El compartimento superior 84 2. DISEÑO DE SOFTWARE

muestra el nombre de la clase. El compartimento medio enumera los atributos de la clase. El compartimento inferior enumera las operaciones de la clase. Al dibujar un elemento de clase en un diagrama de clases, debemos utilizar el compartimento superior y los dos compartimentos de la parte inferior son opcionales (Los dos de abajo serían innecesarios en un diagrama que represente un mayor nivel de detalle en el que el objetivo sea mostrar sólo la relación entre las clases). El diagrama 2.1 muestra un vuelo de una aerolínea modelado como una clase UML. Como podemos ver, el nombre es Vuelo, y en el compartimento medio vemos que la clase Vuelo tiene tres atributos: numeroVuelo, horaSalida, y duracionVuelo. En el compartimento inferior vemos que la clase Vuelo tiene dos operaciones: retrasarVuelo y obtenerHoraLlegada.

El compartimento de atributos de una clase (el compartimento central) enumera cada uno de los atributos de la clase en líneas separadas. El compartimento de atributos es opcional, pero cuando se usa contiene cada atributo de la clase mostrado en un formato de lista. La línea utiliza el siguiente formato:

nombre : tipo del atributo

numeroVuelo : Entero

En los diagramas de clase de negocios, los tipos de atributos por lo general corresponden a las unidades que tienen sentido para los posibles lectores del diagrama (es decir, Minutos, Pesos, etc.).

Diagrama 2.2 Ejemplo de Diagrama de Clase en Java

Sin embargo, un diagrama de clases que será utilizado para generar código necesita clases cuyos tipos de atributos se limiten a los tipos proporcionados por el lenguaje de programación, o los tipos incluidos en el modelo que también se implementa en el sistema; como se muestra en el diagrama 2.2, donde los tipos de datos del diagrama 2.1 (Entero, Fecha y Minutos) han sido reemplazados por tipos propios del lenguaje Java (int y Date).

Las operaciones de la clase se documentan en el tercer compartimento (el más bajo) del 2.3. HERRAMIENTAS DE DISEÑO 85 rectángulo del diagrama de clase, que a su vez es opcional. Al igual que los atributos, las operaciones de una clase se muestran en formato de lista, con cada operación en su propia línea. Las operaciones se documentan utilizando la siguiente notación:

nombre( lista de parámetros ) : tipo del valor devuelto

retrasarVuelo( totalMinutos : int ) : Date

obtenerHoraLlegada() : Date

2.3.2. Lenguaje de Etiquetado Extensible (XML)

El Lenguaje de Etiquetado Extensible, o XML (eXtensible Markup Language) desarrollado por el World Wide Web Consortium (W3C) utilizado para almacenar datos en forma legible. Proviene del lenguaje SGML y permite definir la gramática de lenguajes espe- cíficos (de la misma manera que HTML es a su vez un lenguaje definido por SGML) para estructurar documentos grandes. A diferencia de otros lenguajes, XML da soporte a bases de datos, siendo útil cuando varias aplicaciones deben comunicarse entre sí o integrar información.

XML no ha nacido sólo para su aplicación para Internet, sino que se propone como un estándar para el intercambio de información estructurada entre diferentes plataformas. Se puede usar en bases de datos, editores de texto, hojas de cálculo y casi cualquier cosa imaginable. Se utiliza para describir la estructura de los datos de manera significativa. Dondequiera que los datos sean de entrada/salida, almacenados o transmitidos de un lugar a otro, es un ajuste potencial de las capacidades de XML. Tal vez las aplicaciones más conocidas son relacionados con la web.

XML es una tecnología sencilla que tiene a su alrededor otras que la complementan y la hacen mucho más grande y con unas posibilidades mucho mayores. Tiene un papel muy importante en la actualidad ya que permite la compatibilidad entre sistemas para compartir la información de una manera segura, fiable y fácil.

XML es un Lenguaje de Etiquetado Extensible muy simple, pero estricto que juega un papel fundamental en el intercambio de una gran variedad de datos. Es un lenguaje muy similar a HTML pero su función principal es describir datos y no mostrarlos como es el caso de HTML. XML es un formato que permite la lectura de datos a través de diferentes aplicaciones. 86 2. DISEÑO DE SOFTWARE

Las tecnologías XML son un conjunto de módulos que ofrecen servicios útiles a las de- mandas más frecuentes por parte de los usuarios. XML sirve para estructurar, almacenar e intercambiar información. 2.4. ESTRUCTURAS DE DATOS 87

2.4. Estructuras de Datos

Durante todo el ciclo de vida de una Estructura para el Procesamiento de Datos (Data Processing Framework), el elemento más importante a considerar es el conjunto de datos que serán leídos, procesados y publicados.

El diseño de los componentes para almacenar y manipular esos datos se basa en es- tructuras simples, pero flexibles y poderosas, pues brindan una manera ordenada de acceder a los datos y de hacer operaciones de manipulación sobre ellos.

2.4.1. Clase Columna

El primer componente dentro de la estructura de datos es la clase Columna, y su representación en lenguaje UML se muestra en el diagrama 2.3.

Diagrama 2.3 Clase Columna

Una columna de datos es el componente básico de almacenamiento en una EPD. En ella no se almacenan propiamente los datos, sino que contiene la información necesaria para identificar los detalles de una columna de datos; desde su nombre, el tipo de dato, hasta su posición dentro de una colección de datos, entre otros.

Cuadro 2.1 Atributos de la Clase Columna Atributo Tipo Descripción Alias con el que la columna será referenciada durante su pro- nombre String cesamiento posicion int Posición relativa de la columna dentro de la fuente de datos longitud int Cantidad de caracteres que ocupa el valor de la columna tipoDato String Nombre exacto del tipo de dato para el valor de la columna formato String Formato del valor de la columna, utilizado para fechas Cantidad de dígitos después del punto decimal, utilizado para decimales int valores numéricos 88 2. DISEÑO DE SOFTWARE

En el cuadro 2.1 se muestran los atributos que definen a la clase Columna.

El atributo nombre de tipo String es un alias con el que se hará referencia a la columna durante su procesamiento, por ejemplo: "Importe del Movimiento".

El atributo posicion de tipo int indica la posición relativa de la columna en la fuente de datos, por ejemplo: 3.

El atributo longitud de tipo int indica la Longitud en caracteres del valor almacenado, por ejemplo: 16.

El atributo tipoDato de tipo String es el nombre específico del tipo de dato almace- nado, por ejemplo: "Date".

El atributo formato de tipo String es el formato del dato y se utiliza para valores de tipo Date, por ejemplo: "dd-MM-yyyy".

El atributo decimales de tipo int es la cantidad de dígitos decimales y se utiliza para valores de tipo double, por ejemplo: 2.

Programa 2.1 Implementación de la clase Columna

public class Columna { public String nombre; public int posicion; public int longitud; public String tipoDato; public String formato; public int decimales; }

En el programa 2.1 se muestra la implementación de los atributos de la clase Columna.

Programa 2.2 Inicialización de la clase Columna

Columna columna = new Columna(); columna.nombre = "Fecha"; columna.posicion = 2; columna.longitud = 10; columna.tipoDato = "Date"; columna.formato = "dd/MM/yyyy"; columna.decimales = 0; 2.4. ESTRUCTURAS DE DATOS 89

La implementación básica de una clase incluye solamente la declaración de sus atributos públicos. Y la forma de inicializar los atributos públicos de una instancia de la clase Columna es mediante la asignación directa de cada valor a su propiedad correspondiente, como se muestra en el programa 2.2.

A fin de mantener el principio de encapsulación, como se vio en la sección 1.7.1, los atributos de la clase Columna se hacen privados y se implementan getters y setters para cada atributo, como se muestra en el programa 2.3.

Programa 2.3 Implementación del atributo nombre en la clase Columna

public class Columna { private String nombre;

public String getNombre() { return nombre; }

public void setNombre(String newNombre) { nombre = newNombre; } ... }

Al hacer una implementación de este tipo para la clase Columna se deja de tener acceso a sus atributos para inicializar directamente sus valores, y en lugar de ello la inicialización ahora deberá hacerse a través de los setters definidos para cada atributo, como se muestra en el programa 2.4.

Programa 2.4 Inicialización de los atributos en la clase Columna

Columna columna = new Columna(); columna.setNombre("Fecha"); columna.setPosicion(2); columna.setLongitud(10); columna.setTipoDato("Date"); columna.setFormato("dd/MM/yyyy"); columna.setDecimales(0);

Es posible simplificar la inicialización de los atributos de la clase Columna para evitar tener que indicar uno a uno los setters de cada atributo; en vez de ello puede utilizarse un constructor para la clase, o varios. A la implementación de más de un constructor diferente se le conoce como sobrecarga de constructores, como se vio en la sección 1.7.3.

En el programa 2.5 se muestra una implementación de la clase con dos constructores 90 2. DISEÑO DE SOFTWARE

diferentes, y como puede verse, el primer constructor no recibe parámetros e inicializará todos los atributos a sus valores iniciales por defecto, y el segundo constructor sí recibe como parámetros los valores especificados para inicializar a cada uno de los atributos de la clase Columna.

Programa 2.5 Implementación de constructores en la clase Columna

public class Columna { public String nombre; public int posicion; public int longitud; public String tipoDato; public String formato; public int decimales; ... public Columna() { this("", 0, 0, "", "", 0); }

public Columna(String newNombre, int newPosicion, int newLongitud, String newTipoDato, String newFormato, int newDecimales){ setNombre(newNombre); setPosicion(newPosicion); setLongitud(newLongitud); setTipoDato(newTipoDato); setFormato(newFormato); setDecimales(newDecimales); } }

También puede observarse cómo el primer constructor (el que no recibe parámetros) también hace uso del segundo constructor (el que sí recibe parámetros) para inicializar los atributos de la clase Columna con sus valores por defecto.

La inicialización de una instancia de la clase Columna se reduce a tan sólo una línea de código mediante el uso de un constructor, como puede verse en el programa 2.6.

Programa 2.6 Inicialización de la clase Columna con un constructor

Columna columna = new Columna("Fecha", 2, 10, "Date", "dd/MM/yyyy", 0);

La implementación completa de la clase Columna se puede ver en el programa B.1. 2.4. ESTRUCTURAS DE DATOS 91

2.4.2. Clase Tabla

A un nivel superior dentro de la estructura de datos se encuentra la clase Tabla, representada en el diagrama 2.4.

Diagrama 2.4 Clase Tabla

Una tabla de datos es el componente donde efectivamente se almacenan los datos desde el momento de su lectura y se preservan al ser modificados hasta el momento de ser publicados. También contiene al diccionario de datos, con información detallada de cada columna de datos.

En el cuadro 2.2 se muestran los atributos que definen a la clase Tabla.

Cuadro 2.2 Atributos de la Clase Tabla Atributo Tipo Descripción Alias con el que la tabla será referenciada durante su nombre String procesamiento Colección de columnas que contiene al diccionario de columnas List datos Colección de renglones donde se almacena la totali- renglones List dad de los datos

El atributo nombre de tipo String es un alias con el que se hará referencia a la tabla durante su procesamiento, por ejemplo: "Movimientos Bancarios".

El atributo columnas de tipo List es una colección de columnas de datos que en conjunto integran el diccionario de datos de la tabla.

El atributo renglones de tipo List es una colección de renglones de datos, y es donde efectivamente se almacenan los datos de la tabla.

El detalle de implementación de la clase Tabla puede verse en el programa B.2.

Un ejemplo de las estructuras de datos que pueden implementarse con la clase Tabla es la que se muestra en el cuadro 2.1, con las columnas Folio, Fecha, Concepto e 92 2. DISEÑO DE SOFTWARE

Importe; y contiene datos de ejemplo que hacen referencia a Movimientos Bancarios.

Figura 2.1 Ejemplo de la clase Tabla

Movimientos Bancarios Folio Fecha Concepto Importe A1200301 21/04/2014 Traspaso 1750.00 A1200302 22/04/2014 Retiro -520.50 A1200303 23/04/2014 Depósito 280.00

La forma de inicializar una instancia de la clase Tabla con la estructura y los datos del ejemplo anterior se muestra en el programa 2.7.

Programa 2.7 Inicialización de la clase Tabla

Listcolumnas = new ArrayList(); columnas.add(new Columna("Folio", 0, 8, "String", "", 0)); columnas.add(new Columna("Fecha", 1, 10, "Date", "dd/MM/yyyy", 0)); columnas.add(new Columna("Concepto", 2, 30, "String", "", 0)); columnas.add(new Columna("Importe", 3, 12, "double", "", 2));

Listrenglones = new ArrayList(); renglones.add(new String[] {"A1200301", "21/04/2014", "Traspaso", "1750.00"}); renglones.add(new String[] {"A1200302", "22/04/2014", "Retiro", "-520.50"}); renglones.add(new String[] {"A1200303", "23/04/2014", "Depósito", "280.00"});

Tabla tabla = new Tabla("Movimientos Bancarios", columnas, renglones); 2.5. MODELO DE OBJETOS 93

2.5. Modelo de Objetos

Las clases del modelo de objetos contienen la estructura necesaria para implementar tanto la configuración de las EPD como el flujo de su procesamiento.

2.5.1. Clase Parámetro

La clase Parametro contiene los parámetros configurados que se utilizarán en el ciclo de procesamiento, y se muestra en el diagrama 2.5.

Diagrama 2.5 Clase Parametro

En el cuadro 2.3 se muestran los elementos que definen a la clase Parametro.

Cuadro 2.3 Elementos de la Clase Parametro Nombre Tipo Descripción Nombre descriptivo con el que se identificará a la configuración nombre String de un parámetro específico tipo String Nombre exacto del tipo de dato para el valor del parámetro valor String Valor del parámetro correspondiente con su tipo de dato

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a la configuración de un parámetro específico, por ejemplo: "FechaAyer".

El atributo tipo de tipo String es el nombre específico del tipo de dato almacenado, por ejemplo: "Date".

El atributo valor de tipo String es el valor del parámetro correspondiente con su tipo de dato, por ejemplo: "{#FechaHoy# - 1, yyyyMMdd}".

En el programa B.3 se muestra la implementación de la clase Parametro, y a continua- ción un ejemplo de inicialización de una instancia de la misma clase, en el programa 2.8. 94 2. DISEÑO DE SOFTWARE

Programa 2.8 Ejemplo de inicialización de la clase Parametro

Parametro parametro = new Parametro("FechaAyer", "Date", "#FechaHoy# - 1, yyyyMMdd"); 2.5. MODELO DE OBJETOS 95

2.5.2. Clase Solución

La clase Solucion tiene como sus tres propiedades principales listas de instancias a las interfaces Lector, Procesador y Publicador; su representación en lenguaje UML se muestra en el diagrama 2.6.

Diagrama 2.6 Clase Solucion

Los atributos de la clase Solucion se muestran en el cuadro 2.4.

Cuadro 2.4 Atributos de la Clase Solucion Atributo Tipo Descripción Nombre descriptivo con el que se identificará a nombre String la configuración de una solución específica lectores List Colección de instancias de la clase Lector procesadores List Colección de instancias de la clase Procesador publicadores List Colección de instancias de la clase Publicador

El atributo nombre de tipo String es el nombre descriptivo con el que se identificará a la configuración de una solución específica, por ejemplo: "Actualización de Datos de Mercado".

El atributo lectores es una colección de instancias de la clase Lector conteniendo todos los lectores configurados para la obtención de los datos.

El atributo procesadores es una colección de instancias de la clase Procesador conte- niendo todos los procesadores configurados para la modificación de los datos.

El atributo publicadores es una colección de instancias de la clase Publicador conte- niendo todos los publicadores configurados para la difusión de los datos.

La operación de la clase Solucion se muestra en el cuadro 2.5.

Cuadro 2.5 Operación de la Clase Solucion Operación Parámetro Descripción Inicia el procesamiento de la solución con base procesar() tablas:List en sus parámetros configurados 96 2. DISEÑO DE SOFTWARE

La operación procesar() lanza el mensaje para dar inicio al procesamiento com- pleto de todos los lectores, procesadores y publicadores configurados en la so- lución, con base en sus parámetros configurados, y recibiendo una colección de instancias de la clase Tabla.

En el programa B.4 se muestra la implementación de la clase Solucion, y a continuación un ejemplo de inicialización de una instancia de la misma clase, en el programa 2.9.

Programa 2.9 Inicialización de la clase Solucion

Listlectores = new ArrayList(); Listprocesadores = new ArrayList(); Listpublicadores = new ArrayList();

lectores.add(new LectorCsv()); lectores.add(new LectorTxt()); procesadores.add(new ProcesadorFiltrado()); procesadores.add(new ProcesadorConciliacion()); publicadores.add(new PublicadorPlantilla()); Solucion solucion = new Solucion("Actualización de Datos de Mercado", lectores, procesadores, publicadores); 2.5. MODELO DE OBJETOS 97

2.5.3. Clase Epd

En su nivel superior, el modelo comienza con la clase principal Epd, que contiene todas las configuraciones requeridas para efectuar uno o múltiples procesamientos de datos; su representación en lenguaje UML se muestra en el diagrama 2.7.

Diagrama 2.7 Clase Epd

Los atributos de la clase principal Epd se muestran en el cuadro 2.6.

Cuadro 2.6 Atributos de la Clase Epd Atributo Tipo Descripción Nombre descriptivo con el que se identificará a la nombre String configuración de una EPD específica parametros List Colección de instancias de la clase Parametro soluciones List Colección de instancias de la clase Solucion

El atributo nombre de tipo String es el nombre descriptivo con el que se identificará a la configuración de una Estructura para el Procesamiento de Datos (EPD) específica, por ejemplo: "Procesos Regulatorios Diarios para Banco de México".

El atributo parametros es una colección de instancias de la clase Parametro conteniendo todos los parámetros configurados para la ejecución de los procesos.

El atributo soluciones es una colección de instancias de la clase Solucion conteniendo todas las soluciones configuradas para su procesamiento.

La operación de la clase Epd se muestra en el cuadro 2.7.

La operación procesar() lanza el mensaje para dar inicio al procesamiento completo de todas las soluciones configuradas en la EPD, con base en sus parámetros configurados, y recibiendo una colección de instancias de la clase Tabla. 98 2. DISEÑO DE SOFTWARE

Cuadro 2.7 Operación de la Clase Epd Operación Parámetro Descripción Inicia el procesamiento de las soluciones con procesar() tablas:List base en sus parámetros configurados

En el programa B.5 se muestra la implementación de la clase Epd, y a continuación un ejemplo de inicialización de una instancia de la misma clase, en el programa 2.10.

Programa 2.10 Inicialización de la clase Epd

Listparametros = new ArrayList(); parametros.add(parametro);

Listsoluciones = new ArrayList(); soluciones.add(solucion);

Epd epd = new Epd("Procesos Regulatorios Diarios para Banco de México", parametros, soluciones); 2.6. MODELO EPD 99

2.6. Modelo EPD

En el diseño del modelo de objetos para una Estructura para el Procesamiento de Da- tos (EPD) se establece una disposición jerárquica, con una clase principal en la parte superior, compuesta por otras clases derivadas.

El modelo de objetos para la EPD comienza con la clase principal Epd, mostrada en el diagrama 2.8.

Diagrama 2.8 Modelo EPD

Existe una relación de composición entre las clases Parametro y Solucion con la clase Epd, ya que ambas forman parte de ella y tienen dependencias en sus respectivos ciclos de vida. Y también existe una relación de composición entre las interfaces Lector, Procesador y Publicador con la clase Solucion, pues entre las tres definen el proceso completo de una solución. 100 2. DISEÑO DE SOFTWARE

2.7. Arquitectura de Configuración

La Configuración está basada principalmente en archivos XML conteniendo todo el detalle de la configuración (Parámetros y Soluciones), y mediante el uso de la tecnología JAXB, se generan las instancias de los objetos configurados en tiempo de ejecución, y se lanzan los procesos que componen la Estructura para el Procesamiento de Datos.

Configuración 2.1 Implementación de la clase Epd

... ...

En la configuración 2.1 se muestra la implementación de la clase Epd en el lenguaje XML.

Configuración 2.2 Esquema básico de una EPD

... ... ... ...

La Arquitectura de Configuración se define mediante un archivo en formato XML cuyo 2.7. ARQUITECTURA DE CONFIGURACIÓN 101 nodo principal es , el cual contiene solamente una sección de como primer nodo, y posteriormente puede contener cualquier cantidad de nodos , los cuales representan la unidad que contiene toda la funcionalidad para los diferentes casos de uso.

La estructura mostrada en la configuración 2.2 es un ejemplo a nivel general de la for- ma en que la arquitectura principal está constituida, donde a un nivel superior se define el nodo principal , el cual contiene la primera y única sección de , seguida de tres diferentes nodos , conteniendo cada uno de ellos toda la configuración necesaria para tres diferentes casos de uso: "Actualización de Datos de Mercado", "Conciliación Bancaria" y "Envío de Reportes Regulatorios". Cada caso de uso puede tener diferentes fuentes de datos, formas de procesamiento, y destinos de publicación, como se verá más adelante: 102 2. DISEÑO DE SOFTWARE

2.7.1. Arquitectura Java para Enlazado de XML (JAXB)

La Arquitectura Java para Enlazado de XML (JAXB: Java Architecture for XML Binding) es la Interfaz de Programación de Aplicaciones (API: Application Programming Interface) estándar de Java para Enlazado (Binding) de XML. Se trata de una extensión estándar del lenguaje incluida desde Java 6 y posteriores.

La ventaja principal de utilizar JAXB es que ya no es necesario hacer el desarrollo de un código potencialmente frágil de análisis sintáctico para XML. Simplemente se incluyen las anotaciones necesarias en las propias clases Java que permitan hacer el enlazado con la configuración XML.

JAXB proporciona una manera rápida y conveniente para enlazar esquemas XML con sus representaciones Java, por lo que resulta fácil incorporar funciones de datos y proce- samiento XML en las aplicaciones Java. Como parte de este proceso, JAXB proporciona métodos para efectuar el unmarshalling (disgregación) de documentos de instancia XML hacia árboles de contenido Java.

Esto permite que en tiempo de ejecución, JAXB pueda leer un documento XML y convertirlo a instancias de clases Java previamente desarrolladas, poblando el modelo de objetos y validando los datos para asegurarse de que coincide con el esquema de configuración.

La estructura XML factible de procesarse mediante JAXB que resulta ser la más sim- ple, es el esquema básico en XML que se muestra en la configuración 2.3, para una implementación de la clase Parametro que contiene el atributo nombre con el valor "Fecha de Ayer", el elemento tipo con el valor Date y el elemento valor con el valor #FechaHoy# - 1, yyyyMMdd.

Configuración 2.3 Esquema básico de la clase Parametro

#FechaHoy# - 1, yyyyMMdd

La implementación de JAXB para la clase Parametro se muestra en el programa 2.11, y se lleva a cabo añadiendo las sentencias import para las librerías XmlRootElement, Xm- lAttribute y XmlElement; luego, se añade la marca de elemento raíz @XmlRootElement a la clase Parametro para enlazarlo como el nodo raíz parametro de la configuración 2.3. Y finalmente los atributos nombre y tipo de la clase se marcan con @XmlAttribute, 2.7. ARQUITECTURA DE CONFIGURACIÓN 103 y el nodo o elemento valor se marcan con @XmlElement en las implementaciones set de cada propiedad.

Programa 2.11 Implementación de JAXB en la clase Parametro

import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement;

@XmlRootElement public class Parametro { String nombre; String tipo; String valor;

public String getNombre() { return nombre; } public String getTipo() { return tipo; } public String getValor() { return valor; }

@XmlAttribute public void setNombre(String nombre) { this.nombre = nombre; } @XmlAttribute public void setTipo(String tipo) { this.tipo = tipo; } @XmlElement public void setValor(String valor) { this.valor = valor; } }

Una estructura XML más compleja, pero que de igual manera puede procesarse con JAXB, es el esquema básico en XML que se muestra en la configuración 2.4, para una implementación de la clase Epd que contiene el atributo nombre con el valor "Estruc- tura para el Procesamiento de Datos", el elemento parametros conteniendo una lista de una o más implementaciones de la clase Parametro y el elemento soluciones conteniendo una lista de una o más implementaciones de la clase Solucion.

La implementación de JAXB para la clase Epd se muestra en el programa 2.12, y se lleva a cabo añadiendo las sentencias import para las librerías XmlRootElement, XmlAt- tribute, XmlElementWrapper y XmlAnyElement; luego, se añade la marca de elemento raíz @XmlRootElement a la clase Epd para enlazarlo como el nodo raíz epd de la confi- guración 2.4. Y finalmente el atributo nombre de la clase se marca con @XmlAttribute en su implementación set, y los nodos o elementos parametros y soluciones se mar- can directamente en la declaración simple de la propiedad, sin implementaciones get ni set, con @XmlElementWrapper y con @XmlAnyElement(lax=true). Estos dos marcadores 104 2. DISEÑO DE SOFTWARE

Configuración 2.4 Esquema básico de la clase Epd

... ...

especiales permiten hacer el enlazado hacia una lista de instancias de clase a diferencia de simplemente asignar un valor sencillo como se hace para un tipo de dato primitivo.

Programa 2.12 Implementación de JAXB en la clase Epd

import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlAnyElement;

@XmlRootElement public class Epd { String nombre;

public String getNombre() { return nombre; }

@XmlAttribute public void setNombre(String nombre) { this.nombre = nombre; } @XmlElementWrapper @XmlAnyElement(lax=true) public Listparametros; @XmlElementWrapper @XmlAnyElement(lax=true) public Listsoluciones; ... } 2.7. ARQUITECTURA DE CONFIGURACIÓN 105

El proceso de enlazado se corresponde de la siguiente manera:

1. El nodo raíz se corresponde con la clase Epd marcada como elemento raíz con @XmlRootElement.

2. El atributo nombre del nodo raíz se corresponde con la propiedad Nombre de la clase Epd marcada como atributo con @XmlAttribute.

3. Los nodos parametros y soluciones se corresponden con las propiedades Para- metros y Soluciones de la clase Epd respectivamente, marcadas como elemento con @XmlElement en las implementaciones get de cada propiedad.

En el programa 2.13 se muestra el proceso de enlazado XML mediante JAXB.

Programa 2.13 Proceso de enlazado XML mediante JAXB

public static void main(String[] args) { File file = new File("EPD.xml");

JAXBContext contextoJaxb = JAXBContext.newInstance(Epd.class); Unmarshaller disgregadorJaxb = contextoJaxb.createUnmarshaller(); Epd epd = (Epd) disgregadorJaxb.unmarshal(file);

Listtablas = new ArrayList<>(); epd.procesar(tablas); }

Se requieren solo tres líneas de código para llevar a cabo el unmarshalling del archivo XML hacia sus instancias de objetos Java.

Primero se crea el contexto basado en la clase principal:

JAXBContext contextoJaxb = JAXBContext.newInstance(Epd.class);

Luego se crea una instancia del unmarshaller:

Unmarshaller disgregadorJaxb = contextoJaxb.createUnmarshaller();

Y finalmente se lleva a cabo el unmarshalling o disgregado del archivo, proceso mediante el cual se carga el contenido del XML en la instancia epd con todas las propiedades en memoria conforme fueron configuradas desde su origen:

Epd epd = (Epd) disgregadorJaxb.unmarshal(file); 106 2. DISEÑO DE SOFTWARE

2.7.2. Estructura Basada en Soluciones

Cada se compone de tres secciones: , y ; y que se corresponden con el diagrama de flujo de la Estructura para el Procesamiento de Datos (EPD), donde se definen tres diferentes bloques de acción: Lector de Datos, Procesador de Datos y Publicador de Datos.

Dentro de cada una de esas secciones se agrupan una o más definiciones de clases de funcionalidad específica, como se muestra en la configuración 2.5.

Configuración 2.5 Secciones de una EPD

... ... ...

La sección contiene una o más definiciones de una clase específica , que podría tratarse de uno o más lectores de archivos por posición, CSV, XML o un lector de base de datos. Al término de la ejecución de cada clase se añadi- rán los datos obtenidos a una estructura interna de tablas, las cuales estarán disponibles para su lectura y utilización por las clases de tipo y .

La sección contiene una o más definiciones de una clase específi- ca , que podría tratarse de uno o más procesadores de transformación, fusión, división, filtrado, agrupación, comparación, conciliación; o de mapas de equiva- lencias. Al término de la ejecución de cada clase se añadirán los datos 2.7. ARQUITECTURA DE CONFIGURACIÓN 107 obtenidos a una estructura interna de tablas, las cuales estarán disponibles para su lectura y utilización por las clases de tipo .

La sección contiene una o más definiciones de una clase específica , que podría tratarse de uno o más publicadores de archivos por posición, CSV, XML o un publicador a base de datos. Al término de la ejecución de todas las clases se dará por concluido el ciclo completo de la EPD. 108 2. DISEÑO DE SOFTWARE

2.7.3. Parámetros de Ejecución

En la sección se configuran valores que pueden ser utilizados por todo el conjunto de soluciones definidas en el nodo principal , y puede contener tanto valores constantes como valores preconfigurados; y cualquiera de ellos podrá ser utilizado como variable meta sintáctica. En la configuración 2.6 se muestra un ejemplo de los parámetros que pueden implementarse en la arquitectura de una Estructura para el Procesamiento de Datos (EPD).

Configuración 2.6 Parámetros de una EPD

{#fechaHoy# - 1, yyyyMMdd} {#fechaHoy# - 1, yyyyMMdd} MEX,USA \\servidor\banco$\{#fechaAyer#, yyyy-MM-dd}\movimientos.csv Server=SERVIDOR_BANCO; Database=BASE_DATOS_BANCO; Uid=usr001; Pwd=pwd123; SELECT Folio, Fecha, Concepto, Importe FROM MovtosBanco WHERE Fecha >= '{#fechaAyerHabil#, dd-MM-yyyy}';

El parámetro es un ejemplo de valor preconfigurado, que está definido en 2.7. ARQUITECTURA DE CONFIGURACIÓN 109 el tipo "Date", y devuelve por defecto el valor de la fecha del día de hoy. Su carácter de variable meta sintáctica se lo brinda la característica de poder ser utilizado por cualquier configuración subsequente simplemente añadiéndole el nombre del parámetro con el siguiente formato: "#fechaHoy#".

En el parámetro se tiene un ejemplo de la utilización de como variable meta sintáctica, al contener en su propiedad una referencia al valor preexistente del parámetro , de esta forma: "{#fechaHoy# - 1, yyyyMMdd}". Se puede observar una doble funcionalidad en los parámetros de tipo fecha:

1. La capacidad de efectuar operaciones aritméticas simples en términos de suma y resta de días sobre el valor de la variable meta sintáctica.

2. La configuración de un formato específico de fecha para la cadena resultante, en este caso, cuatro dígitos para el año, dos dígitos para el mes, y dos dígitos para el día.

El parámetro tiene una funcionalidad similar al parámetro , pero añade una funcionalidad adicional en su propiedad con el valor "MEX,USA", lo que permite considerar los días inhábiles para ambos calendarios al momento de efectuar la operación aritmética de suma o resta de días al valor de la variable meta sintáctica. Un ejemplo de calendario con la combinación de días inhábiles se muestra en la figura 2.2.

Figura 2.2 Calendario de Días Inhábiles

Por ejemplo, si el valor de es 17-Sep-2015, la configuración mostrada para el parámetro devolvería 15-Sep-2015, pues considera el día inhábil del 16-Sep-2015 para el calendario de días inhábiles "MEX". 110 2. DISEÑO DE SOFTWARE

Si el valor de es 14-Sep-2015, el valor de sería 11- Sep-2015, pues por definición se consideran los días Sábado y Domingo como días inhábiles.

Si el valor de es 8-Sep-2015, el valor de sería 4-Sep- 2015, pues además se está considerando la fecha inhábil del 7-Sep-2015 para el calen- dario de días inhábiles "USA".

El parámetro utiliza la variable meta sintáctica como un modificador de su propiedad , que está configurado como una ruta de acceso a un archivo en un servidor:

\\servidor\banco$\{#fechaAyer#, yyyy-MM-dd}\movimientos.csv

Si el valor del parámetro es 17-Sep-2015, al ser reemplazado el valor de la variable meta sintáctica #fechaAyer#, el valor resultante de la propiedad quedaría así:

\\servidor\banco$\2015-09-16\movimientos.csv

El parámetro es un ejemplo de valor constante de tipo "String", pues al no incluir en su definición variables meta sintácticas, conserva su valor durante la ejecución del conjunto de soluciones definidas en el nodo principal . Server=SERVIDOR_BANCO; Database=BASE_DATOS_BANCO; Uid=usr001; Pwd=pwd123;

El parámetro utiliza la variable meta sintáctica como un modificador de su propiedad , que está configurado como un query a base de datos: SELECT Folio, Fecha, Concepto, Importe FROM MovtosBanco WHERE Fecha >= '{#fechaAyerHabil#, dd-MM-yyyy}'; Si el valor del parámetro es 17-Sep-2015, al ser reemplazado el valor de la variable meta sintáctica #fechaAyerHabil#, el valor resultante de la propiedad quedaría así: SELECT Folio, Fecha, Concepto, Importe FROM MovtosBanco WHERE Fecha >= '15-09-2015'; 2.8. LÓGICA DE PROCESAMIENTO 111

2.8. Lógica de Procesamiento

El método principal de la clase Epd se llama procesar(), y recibe como parámetro una lista de objetos de tipo Tabla. La lista de objetos de tipo Tabla es la estructura de datos donde se almacenan los datos leídos inicialmente por el método leerDatos() de cada uno de los objetos de tipo Lector. La lista de objetos de tipo Tabla se pasan entonces como parámetro al método procesarDatos() de cada uno de los objetos de tipo Procesador. Y finalmente, la lista de objetos de tipo Tabla se pasan como parámetro al método publicarDatos() de cada uno de los objetos de tipo Publicador.

Programa 2.14 Implementación del método main()

public static void main(String[] args) { File file = new File("EPD.xml");

JAXBContext contextoJaxb = JAXBContext.newInstance(Epd.class); Unmarshaller disgregadorJaxb = contextoJaxb.createUnmarshaller(); Epd epd = (Epd) disgregadorJaxb.unmarshal(file);

Listtablas = new ArrayList<>(); epd.procesar(tablas); }

Como se muestra en el programa 2.14, luego de crear una instancia del objeto de tipo Epd, e inicializarla mediante JAXB con la configuración existente en el archivo "EPD.xml", simplemente se llama al método procesar() de la instancia del objeto Epd, llamada epd.

Programa 2.15 Implementación del método epd.procesar()

public class Epd { public void procesar(Listtablas) { for (Solucion solucion: soluciones) { solucion.procesar(tablas); } } }

En el programa 2.15 se muestra cómo en el método procesar() de la clase Epd, un ciclo crea una instancia de lista de objetos de tipo Tabla, llamada tablas, y la envía 112 2. DISEÑO DE SOFTWARE

como parámetro al método procesar() de todas las soluciones existentes en la lista de objetos de tipo Solucion dentro de la propiedad epd.soluciones.

Programa 2.16 Implementación del método solucion.procesar()

public class Solucion { public void procesar(Listtablas) { for (Lector lector: lectores) { tablas = lector.leerDatos(tablas); } for (Procesador procesador: procesadores) { tablas = procesador.procesarDatos(tablas); } for (Publicador publicador: publicadores) { tablas = publicador.publicarDatos(tablas); } } }

Y finalmente, como se muestra en el programa 2.16, en el método procesar() de la clase Solucion se llevan a cabo tres diferentes ciclos. El primer ciclo se encarga de lla- mar al método leerDatos() de todos los objetos de tipo Lector dentro de la propiedad lectores. El segundo ciclo se encarga de llamar al método procesarDatos() de todos los objetos de tipo Procesador dentro de la propiedad procesadores. Y finalmente, el último ciclo se encarga de llamar al método publicarDatos() de todos los objetos de tipo Publicador dentro de la propiedad publicadores. Siempre pasándose entre sí como parámetro a la lista de objetos de tipo Tabla (tablas), a fin de mantener los datos actualizados con las modificaciones recientes. 2.9. FÓRMULAS DE PROCESAMIENTO 113

2.9. Fórmulas de Procesamiento

Con el uso de fórmulas es posible conducir los resultados del procesamiento y generar modificaciones específicas al conjunto de datos a fin de obtener mejores resultados, tanto a nivel de formato, como de la población requerida para el procesamiento y entrega final de resultados.

En los módulos de procesamiento ProcesadorFiltrar (sección 3.2.10), ProcesadorIn- sertar (sección 3.2.12) y ProcesadorTransformar (sección 3.2.14) pueden utilizarse fórmulas mediante la configuración de la propiedad valor, que puede contener tan- to valores constantes como valores preconfigurados utilizando las columnas existentes como variables meta sintácticas.

2.9.1. Transformación de Valores

Las fórmulas de transformación de valores podrían ser utilizadas como parte de la configuración de un ProcesadorInsertar (sección 3.2.12) para crear una columna nueva con valores obtenidos de los valores ya existentes de una o más columnas, como se muestra en la figura 2.3 con un ejemplo de inserción con fórmula numérica.

Figura 2.3 Ejemplo de fórmula numérica en inserción de columna

Importe Importe IVA 1750.00 1750.00 280.00 -520.50 -520.50 -83.28 280.00 280.00 44.80 -127.20 -127.20 -20.35 -300.00 → -300.00 -48.00 695.00 695.00 111.20 -500.00 -500.00 -80.00 -247.30 -247.30 -39.57 -300.00 -300.00 -48.00 1680.00 1680.00 268.80

La fórmula que se utiliza obtiene cada uno de los valores en la columna Importe y los multiplica por el valor constante de 0.16, que es el porcentaje para el cálculo del IVA:

{[Importe] * 0.16} 114 2. DISEÑO DE SOFTWARE

El nombre de la columna se encierra entre corchetes para indicar que los valores a uti- lizar para el cálculo serán los que correspondan a cada renglón en la tabla: [Importe].

Los operadores pueden ser cualquier operador Aritmético ('+', '-', '*', '/' y ' %') descritos en el cuadro A.2.

El resultado obtenido por cada renglón de la tabla será insertado como parte de la nueva columna IVA.

Las fórmulas de transformación de valores también podrían ser utilizadas como parte de la configuración de un ProcesadorTransformar (sección 3.2.14) para modificar el contenido de una columna existente en base a su propio contenido, o con valores obtenidos de los valores ya existentes de una o más columnas, como se muestra en la figura 2.4 con un ejemplo de transformación con fórmula fecha.

Figura 2.4 Ejemplo de fórmula fecha en transformación de columna

Fecha Fecha 21/04/2016 2016-04-21 22/04/2016 2016-04-22 23/04/2016 2016-04-23 23/04/2016 2016-04-23 23/04/2016 → 2016-04-23 24/04/2016 2016-04-24 24/04/2016 2016-04-24 24/04/2016 2016-04-24 25/04/2016 2016-04-25 25/04/2016 2016-04-25

La fórmula que se utiliza obtiene cada uno de los valores en la columna Fecha y los transforma asignándoles un formato diferente de fecha: yyyy-MM-dd:

{[Fecha], yyyy-MM-dd}

El nombre de la columna se encierra entre corchetes para indicar que los valores a transformar serán los que correspondan a cada renglón en la tabla: [Fecha].

En el caso de las columnas de tipo fecha, los formatos se asignan después del carácter ',', y utilizan "yyyy" para el año, "MM" para el mes, y "dd" para el día.

En la figura 2.5 se muestra un ejemplo de transformación con fórmula cadena.

La fórmula que se utiliza obtiene cada uno de los valores en la columna Folio y los transforma concatenándoles un prefijo constante: 'ID-': 2.9. FÓRMULAS DE PROCESAMIENTO 115

Figura 2.5 Ejemplo de fórmula cadena en transformación de columna

Folio Folio 1200301 ID-1200301 1200302 ID-1200302 1200303 ID-1200303 1200304 ID-1200304 1200305 → ID-1200305 1200306 ID-1200306 1200307 ID-1200307 1200308 ID-1200308 1200309 ID-1200309 1200310 ID-1200310

{'ID-' + [Folio]}

El nombre de la columna se encierra entre corchetes para indicar que los valores serán los que correspondan a cada renglón en la tabla: [Folio].

El operador de concatenación es el mismo que el operador Aritmético que se utiliza para la suma: '+' descrito en el cuadro A.2. El resultado obtenido para cada renglón de la tabla será modificado en la misma columna Folio. 116 2. DISEÑO DE SOFTWARE

2.9.2. Filtrado de Valores

Las fórmulas de filtrado de valores podrían ser utilizadas como parte de la configuración de un ProcesadorFiltrar (sección 3.2.10) para acotar una población de datos con base en un rango de valores para una columna existente, como se muestra en la figura 2.6 con un ejemplo de filtrado con fórmula fecha.

Figura 2.6 Ejemplo de fórmula fecha en filtrado de renglones

Fecha Importe 21/04/2016 1750.00 Fecha Importe 22/04/2016 -520.50 22/04/2016 -520.50 23/04/2016 280.00 23/04/2016 280.00 23/04/2016 -127.20 23/04/2016 -127.20 23/04/2016 -300.00 → 23/04/2016 -300.00 24/04/2016 695.00 24/04/2016 695.00 24/04/2016 -500.00 24/04/2016 -500.00 24/04/2016 -247.30 24/04/2016 -247.30 25/04/2016 1680.00 25/04/2016 -300.00

La fórmula que se utiliza filtra cada uno de los valores en la columna Fecha para que cumplan primero la condición de ser mayores que #2016-04-21# (valor constante), y después la condición de ser menores o iguales que #fechaHoy# (valor variable, en este caso es igual que #2016-04-24#):

{[Fecha] > #2016-04-21# && [Fecha] <= #fechaHoy#}

El nombre de la columna se encierra entre corchetes para indicar que los valores serán los que correspondan a cada renglón en la tabla: [Fecha].

Los operadores pueden ser cualquier operador de Igualdad, Relacional y Condicional ('==', '!=', '>', '>=', '<', '<=', '&&' y '||') descritos en el cuadro A.2. La tabla resultante mostrará solo aquellos registros que cumplan con el filtro especificado, es decir, desde el valor mínimo #2016-04-22# hasta el valor máximo #2016-04-24#.

En la figura 2.7 se muestra un ejemplo de filtrado con fórmula numérica que podría ser utilizada en el ProcesadorFiltrar (sección 3.2.10):

La fórmula que se utiliza filtra cada uno de los valores en la columna Importe para que cumplan la condición de ser mayores que 0.00 (valor constante):

{[Importe] > 0.00} 2.9. FÓRMULAS DE PROCESAMIENTO 117

Figura 2.7 Ejemplo de fórmula numérica en filtrado de renglones

Fecha Importe 21/04/2016 1750.00 22/04/2016 -520.50 23/04/2016 280.00 Fecha Importe 23/04/2016 -127.20 21/04/2016 1750.00 23/04/2016 -300.00 → 23/04/2016 280.00 24/04/2016 695.00 24/04/2016 695.00 24/04/2016 -500.00 25/04/2016 1680.00 24/04/2016 -247.30 25/04/2016 1680.00 25/04/2016 -300.00

El nombre de la columna se encierra entre corchetes para indicar que los valores serán los que correspondan a cada renglón en la tabla: [Importe].

Los operadores pueden ser cualquier operador de Igualdad, Relacional y Condicional ('==', '!=', '>', '>=', '<', '<=', '&&' y '||') descritos en el cuadro A.2. La tabla resultante mostrará solo aquellos registros que cumplan con el filtro especificado, es decir, todos aquellos valores mayores que cero, desde 280.00 hasta 1750.00. 118 2. DISEÑO DE SOFTWARE

2.10. Desarrollo Dirigido por la Configuración (CDD)

Puede compararse la duplicación de código con un accidente a punto de ocurrir, a la espera de alguien que haga una modificación y se olvide de llevarla a las fuentes duplicadas. El problema resultante puede ser importante o de menor importancia, pero no importa la magnitud, la duplicación sigue siendo una fuente de problemas.

La diferencia entre el desarrollo dirigido por la configuración y el desarrollo dirigido por el modelo es que el primero no se limita al modelo de código como clases, campos y relaciones. El Desarrollo Dirigido por la Configuración, o CDD (Configuration-Driven Development) abarca todo lo que puede configurarse dentro de una aplicación. Por ejemplo, si la arquitectura dicta que las reglas de negocio particulares deben aplicarse de forma coherente en la aplicación, podemos utilizar los archivos de configuración para configurar y aplicar dichas normas.

En el desarrollo dirigido por la configuración, los desarrolladores hacen todas las modi- ficaciones principalmente en archivos XML. Todos los demás archivos relacionados con la aplicación leen su configuración de esos archivos, ya sea en tiempo de ejecución o al haber seleccionado partes generadas en tiempo de compilación.

2.10.1. Herramientas requeridas

Las siguientes herramientas son esenciales para el desarrollo dirigido por la configura- ción:

1. Herramientas para la edición

En la mayoría de los casos, un simple editor de texto es suficiente para modificar y evolucionar los archivos XML. Un buen editor XML validará la sintaxis conforme se está modificando el archivo y simplifica la edición de etiquetas XML.

2. Herramientas para la lectura

Para obtener algún beneficio de los archivos XML, necesitamos una herramienta que pueda dirigir los archivos XML directamente a la aplicación. Por ejemplo, podríamos utilizar la librería de Java Betwixt para llenar los archivos Java con el contexto de la configuración de XML.

3. Herramientas para generar artefactos

Una vez que leemos los archivos de configuración, el siguiente paso lógico es ali- 2.10. DESARROLLO DIRIGIDO POR LA CONFIGURACIÓN (CDD) 119

mentar las otras partes del producto con esa información. Tenemos varias opciones en este punto. La primera consiste en incrustar los archivos de configuración en el software en sí para que se lean en tiempo de ejecución. Otra forma es generar código y documentación utilizando herramientas tales como el motor Java Velocity de Apache Commons.

2.10.2. Reglas de desarrollo

Existen ciertas reglas conocidas que aplican al desarrollo de software en general, aunque se aplican de manera diferente en el desarrollo de software dirigido por la configuración.

1. Mantenerlo sencillo

Los archivos de configuración deben ser fáciles de entender y de evolucionar. Si bien esto suena obvio, los usuarios experimentados en XML suelen utilizar características avanzadas que no encajan bien con el enfoque CDD, tales como sintaxis que hacen al XML difícil de leer y entender.

2. Evolucionar según sea necesario

Ninguna plantilla predefinida de XML va a cumplir con las necesidades de cada desarrollador. La solución a este problema consiste en adaptar el diseño de XML para satisfacer nuestras necesidades. Dependiendo del dominio o la arquitectu- ra de software, los atributos XML utilizados en las clases o las definiciones de campo pueden variar mucho. Debemos tener en cuenta que esta evolución evita- rá que los usuarios rompan la regla de “mantenerlo sencillo”. En cada caso de implementación, será fácil encontrar que hay muchos parámetros de configura- ción que resultan inútiles en el contexto de casi cualquier otro producto. Ninguna herramienta en el mercado podría haber simplificado la implementación.

3. Validar pronto y frecuentemente

El sentido común dicta que los errores detectados de forma temprana en el pro- ceso de desarrollo son los más baratos de resolver. Siguiendo este principio, tiene sentido que validemos la configuración tan pronto y tan ampliamente como sea posible. Por ejemplo, podríamos utilizar un archivo XSD o DTD para validar la estructura XML de los archivos de configuración. Si necesitamos aplicar reglas personalizadas de validación, no debemos dudar en desarrollar nuestras propias herramientas de validación. Mientras que el tiempo dedicado a escribir esas he- rramientas no sea tiempo dedicado a trabajar en el producto final, es una buena inversión. 120 2. DISEÑO DE SOFTWARE

Antes de adoptar un nuevo enfoque, es una buena idea tener en mente una visión general de los beneficios, así como lo que costará y lo que no se debe esperar de él.

2.10.3. Beneficios

1. La reducción de la duplicación

La primera ventaja de esta técnica evidentemente es la reducción de la duplicación de información, lo que mejora la mantenibilidad y la calidad general del producto.

2. El no tener dependencia de un proveedor

Al utilizar exclusivamente herramientas básicas para editar XML, no nos atamos a nosotros mismos a cualquier herramienta específica de un proveedor. Podemos encontrar una gran cantidad de herramientas de código abierto disponibles para leer y editar archivos XML.

3. El mantener un control de la configuración fuente

Algunas soluciones en el mercado almacenan sus salidas en formatos XML propie- tarios que son casi imposibles de enlazar. Las referencias entre esos archivos XML también causa problemas. Es ineficiente tener sólo un miembro del equipo con los derechos para modificar un archivo de configuración en un momento dado. Los archivos XML editados por humanos tienen la ventaja de trabajar de la mano con herramientas de control de la configuración fuente como CVS, Subversion, o Clearcase en entornos multiusuario.

4. La herramienta adecuada para el trabajo adecuado

La mayoría de las herramientas en el mercado le hacen frente a unas necesidades muy comunes, pero cada proyecto tiene necesidades específicas. Esto hace que sea difícil, o incluso imposible, encontrar herramientas que coincidan con todas esas necesidades. Los archivos de configuración personalizados tienen la ventaja de que contienen sólo la información que es relevante para el proyecto.

5. Independencia tecnológica

Algunas herramientas existentes utilizan archivos de configuración para aislar la aplicación de la tecnología subyacente. Por ejemplo, Hibernate almacena las rela- ciones entre la base de datos y los objetos en archivos de configuración, lo que a su vez aísla al usuario de la implementación de base de datos específica del proveedor. Mientras que esta independencia es raramente perfecta, la abstracción 2.10. DESARROLLO DIRIGIDO POR LA CONFIGURACIÓN (CDD) 121

tecnológica es generalmente vista como algo positivo, ya que puede ayudar a evolucionar la aplicación en el futuro.

2.10.4. Costos

1. Montaje de la estructura

El costo inicial de montar la estructura no es despreciable. Incluso con las he- rramientas adecuadas, los problemas son inevitables. El desarrollo dirigido por la configuración es sobre todo adecuada para proyectos de medianos a grandes.

2. Complejidad del proceso de construcción

Al generar partes de la aplicación a partir de archivos de configuración, el proceso de construcción puede llegar a ser complicado. Con una adecuada automatización de la construcción, este precio sigue siendo relativamente bajo.

2.10.5. Limitaciones y soluciones de compromiso

1. Complejidad de las reglas de negocio

Los conceptos básicos se hacen equivalentes fácilmente con los archivos de con- figuración, pero las reglas de negocio complejas son totalmente otro asunto. Si las reglas complejas vuelven muy a menudo en nuestra aplicación con pequeñas variaciones, entonces es posible crear archivos de configuración que sólo alma- cenen esas variaciones. Por el bien de la eficiencia, lo mejor es dejar las reglas de negocio complejas para el propio código y tener conceptos repetitivos en los archivos de configuración.

2. Costo de infraestructura

Para los proyectos pequeños, el costo de montar la infraestructura podría ser mayor que el costo del proyecto en sí. Además, los proyectos pequeños no suelen sufrir de redundancia de información. 122 2. DISEÑO DE SOFTWARE 3| Implementación

123 124 3. IMPLEMENTACIÓN 3.1. LECTORES DE DATOS 125

3.1. Lectores de Datos

El modelo de objetos para los lectores de datos parte de una interface llamada Lector, representada en el diagrama 3.1.

Diagrama 3.1 Interface Lector

Aquí se aplica el principio de la herencia (sección 1.7.4), pues los lectores tienen que implementar la operación leerDatos() de la interface Lector, heredando así el com- portamiento para leer los datos.

Y también se aplica el principio del polimorfismo (sección 1.7.2), pues cada uno de los tres lectores del diagrama 3.1 (LectorCsv, LectorSql y LectorTxt) tiene propiedades diferentes, según las necesidades de cada lector. 126 3. IMPLEMENTACIÓN

3.1.1. Lector CSV

Para realizar la lectura de una estructura de datos basada en un archivo de texto separado por comas (CSV), se utiliza la clase LectorCsv representada en el diagrama 3.2.

Diagrama 3.2 Clase LectorCsv

En el cuadro 3.1 se enlistan los atributos que definen a la clase LectorCsv.

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase LectorCsv:

El atributo rutaArchivo de tipo String es la ubicación del archivo mediante la ruta de acceso y el nombre completo del archivo CSV:

data/movimientos.csv

El atributo caracterSeparador de tipo char es el carácter que deberá utilizar el lector CSV para llevar a cabo la separación de las columnas de datos:

, 3.1. LECTORES DE DATOS 127

Cuadro 3.1 Atributos de la Clase LectorCsv Atributo Tipo Descripción Descripción de la instancia de la clase nombre String LectorCsv rutaArchivo String Ubicación del archivo CSV Carácter para separación de columnas de caracterSeparador char datos Carácter para identificar valores de cade- caracterComillas char nas Carácter para identificar caracteres de es- caracterEscape char cape Cantidad de líneas de encabezado a igno- lineasEncabezado int rar Indica si valores cadena vienen rodeados valorEntreComillas boolean del carácter comillas Indica si eliminar espacios al inicio o al eliminarEspacios boolean final de valores cadena Indica si conservar comillas al inicio y al conservarComillas boolean final de valores cadena Indica si excluir líneas indicadas como en- excluirEncabezado boolean cabezado Indica si conservar caracteres de salto de conservarSaltosLinea boolean línea dentro de valores cadena Contiene una lista de instancias de la cla- columnas List se Columna

El atributo caracterComillas de tipo char es el carácter que deberá utilizar el lector CSV para identificar los valores de cadenas:

"

El atributo caracterEscape de tipo char es el carácter que deberá utilizar el lector CSV para identificar los caracteres de escape, como tabuladores (\t) o saltos de línea (\n):

\

El atributo lineasEncabezado de tipo int es la cantidad de líneas de encabezado que incluye el archivo, a fin de ignorarla(s) durante el procesamiento:

1

El atributo valorEntreComillas de tipo boolean indica si los valores de tipo cadena vendrán rodeados del carácter comillas, para poder separar los valores cadenas de las comillas, si así se especifica: 128 3. IMPLEMENTACIÓN

false

El atributo eliminarEspacios de tipo boolean indica si los espacios al inicio o al final de los valores de tipo cadena deberán eliminarse:

true

El atributo conservarComillas de tipo boolean indica si las comillas al inicio y al final de los valores de tipo cadena deberán conservarse:

false

El atributo excluirEncabezado de tipo boolean indica si las líneas indicadas como encabezado deberán excluirse del procesamiento:

false

El atributo conservarSaltosLinea de tipo boolean indica si los caracteres de salto de línea dentro de los valores de tipo cadena deberán conservarse:

false

El atributo columnas de tipo List contiene la configuración de las columnas de datos en el archivo CSV, mediante una lista de instancias de la clase Columna. ...

El atributo columnas.nombre de tipo String es un alias con el que se hará referencia a la columna durante su procesamiento:

Fecha

El atributo columnas.posicion de tipo int indica la posición relativa de la columna en la fuente de datos:

2

El atributo columnas.tipoDato de tipo String es el nombre específico del tipo de dato almacenado:

Date

Se utiliza para indicar el tipo de dato que se está leyendo, a fin de implementar las operaciones de validación y conversión que correspondan con el tipo de dato en particular. Los tipos de datos soportados por la clase LectorCsv son todos los que se indican en el cuadro A.1. En el caso de "float" y "double", se valida que la 3.1. LECTORES DE DATOS 129 columna contenga valores numéricos válidos (números del 1 al 9, el guión medio para el signo negativo y el punto decimal). El caso de "Date" valida que el formato de fecha corresponda con el valor de la propiedad

El atributo columnas.formato de tipo String es el formato del dato y se utiliza para valores de tipo Date:

dd/MM/yyyy

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la clase LectorCsv es el que se muestra en la figura 3.1, y corresponde a un archivo de texto CSV (Comma-Separated Values). Contiene cuatro columnas de datos separadas por el carácter ',': Folio, Fecha, Concepto e Importe; y datos de ejemplo que hacen referencia a Movimientos Bancarios.

Figura 3.1 Ejemplo de la clase LectorCsv

Folio,Fecha,Concepto,Importe A1200301,21/04/2016,Transferencia Interbancaria,1750.00 A1200302,22/04/2016,Retiro en Ventanilla,-520.50 A1200303,23/04/2016,Depósito en Efectivo,280.00 A1200304,23/04/2016,Compra en Comercio,-127.20 A1200305,23/04/2016,Retiro en Cajero Automático,-300.00 A1200306,24/04/2016,Depósito en Efectivo,695.00 A1200307,24/04/2016,Pago SPEI a Proveedor,-500.00 A1200308,24/04/2016,Comercio S.A.,-247.30 A1200309,25/04/2016,Retiro en Cajero Automático,-300.00 A1200310,25/04/2016,Transferencia Interbancaria,1680.00

La estructura de configuración XML para una instancia de la clase LectorCsv se muestra en la configuración C.1.

Un ejemplo completo de implementación para una instancia de la clase LectorCsv se muestra en la configuración C.2. 130 3. IMPLEMENTACIÓN

3.1.2. Lector SQL

Para realizar la lectura de una estructura de datos basada en una consulta SQL a base de datos, se utiliza la clase LectorSql representada en el diagrama 3.3.

Diagrama 3.3 Clase LectorSql

En el cuadro 3.2 se enlistan los atributos que definen a la clase LectorSql.

Cuadro 3.2 Atributos de la Clase LectorSql Atributo Tipo Descripción Descripción de la instancia de la clase Lec- nombre String torSql Controlador específico del manejador de base cadenaControlador String de datos Cadena de conexión al servidor de base de cadenaConexion String datos Clave del usuario que se conectará a la base claveUsuario String de datos Contraseña de acceso para conectarse a la claveAcceso String base de datos Cadena utilizada para efectuar la consulta a cadenaConsulta String la base de datos Contiene una lista de instancias de la clase columnas List Columna

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase LectorSql: 3.1. LECTORES DE DATOS 131

El atributo cadenaControlador de tipo String es el controlador específico del maneja- dor de base de datos, que en este caso es MySQL:

com.mysql.jdbc.Driver

El atributo cadenaConexion de tipo String es la cadena de conexión al servidor de la base de datos:

jdbc:mysql://localhost/banco

El atributo claveUsuario de tipo String es la clave del usuario que se conectará a la base de datos:

root

El atributo claveAcceso de tipo String es la contraseña de acceso para conectarse a la base de datos:

root

El atributo cadenaConsulta de tipo String es la cadena utilizada para efectuar la consulta a la base de datos: SELECT TRAN_ID_K AS Folio, TRAN_DATE AS Fecha, TRAN_DESC AS Concepto, TRAN_AMNT AS Importe FROM TRAN WHERE TRAN_DATE >= '21-04-2016';

No es necesario indicar valores para el atributo columnas, ya que al momento de traer los valores desde la base de datos, se utilizará la información en el diccionario de datos para llenar los valores de la lista de objetos de tipo List.

A partir de la consulta SQL a la base de datos, se obtienen los valores para los siguientes atributos:

El atributo columnas.nombre de tipo String es un alias con el que se hará refe- rencia a la columna durante su procesamiento, por ejemplo: "Fecha". 132 3. IMPLEMENTACIÓN

El atributo columnas.posicion de tipo int indica la posición relativa de la co- lumna en la fuente de datos, por ejemplo: 2.

El atributo columnas.tipoDato de tipo String es el nombre específico del tipo de dato almacenado, por ejemplo: "Date".

El atributo columnas.formato de tipo String es el formato del dato y se utiliza para valores de tipo Date, por ejemplo: "dd/MM/yyyy".

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la clase LectorSql es el que se muestra en la figura 3.2, y corresponde al resultado de una con- sulta SQL a base de datos. Contiene cuatro columnas de datos: Folio, Fecha, Concepto e Importe; y datos de ejemplo que hacen referencia a Movimientos Bancarios.

Figura 3.2 Ejemplo de la clase LectorSql

Movimientos Bancarios Folio Fecha Concepto Importe A1200301 21/04/2016 Transferencia Interbancaria 1750.00 A1200302 22/04/2016 Retiro en Ventanilla -520.50 A1200303 23/04/2016 Depósito en Efectivo 280.00 A1200304 23/04/2016 Compra en Comercio -127.20 A1200305 23/04/2016 Retiro en Cajero Automático -300.00 A1200306 24/04/2016 Depósito en Efectivo 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor -500.00 A1200308 24/04/2016 Comercio S.A. -247.30 A1200309 25/04/2016 Retiro en Cajero Automático -300.00 A1200310 25/04/2016 Transferencia Interbancaria 1680.00

La estructura de configuración XML para una instancia de la clase LectorSql se muestra en la configuración C.3.

Un ejemplo completo de implementación para una instancia de la clase LectorSql se muestra en la configuración C.4. 3.1. LECTORES DE DATOS 133

3.1.3. Lector TXT

Para realizar la lectura de una estructura de datos basada en un archivo de texto por posición (TXT), se utiliza la clase LectorTxt representada en el diagrama 3.4.

Diagrama 3.4 Clase LectorTxt

En el cuadro 3.3 se enlistan los atributos que definen a la clase LectorTxt.

Cuadro 3.3 Atributos de la Clase LectorTxt Atributo Tipo Descripción Descripción de la instancia de clase Lec- nombre String torTxt rutaArchivo String Ubicación del archivo TXT Cantidad de líneas de encabezado a igno- lineasEncabezado int rar Indica si excluir líneas indicadas como en- excluirEncabezado boolean cabezado Indica si conservar caracteres de salto de conservarSaltosLinea boolean línea dentro de valores cadena Contiene una lista de instancias de la cla- columnas List se Columna

El atributo nombre de tipo String es el nombre descriptivo con el que se identificará a una instancia específica de la clase LectorTxt:

El atributo rutaArchivo de tipo String es la ubicación del archivo mediante la ruta 134 3. IMPLEMENTACIÓN

de acceso y el nombre completo del archivo TXT:

data/movimientos.txt

El atributo lineasEncabezado de tipo int es la cantidad de líneas de encabezado que incluye el archivo, a fin de ignorarla(s) durante el procesamiento:

1

El atributo excluirEncabezado de tipo boolean indica si las líneas indicadas como encabezado deberán excluirse del procesamiento:

false

El atributo conservarSaltosLinea de tipo boolean indica si los caracteres de salto de línea dentro de los valores de tipo cadena deberán conservarse:

false

El atributo columnas de tipo List contiene la configuración de las columnas de datos en el archivo TXT, mediante una lista de instancias de la clase Columna. ...

El atributo columnas.nombre de tipo String es un alias con el que se hará referencia a la columna durante su procesamiento:

Fecha

El atributo columnas.inicio de tipo int indica la posición relativa de la columna configurada dentro del conjunto de columnas de las que se compone el archivo. Es base cero, es decir, la primer columna del archivo recibe el valor de cero.

8

No es necesario que se especifiquen todas las columnas que contenga el archivo; y tampoco es necesario que las columnas especificadas lleven un orden secuencial. Esto brinda flexibilidad al momento de leer los datos:

El atributo columnas.longitud de tipo int indica la cantidad de caracteres a leer desde la posición de inicio:

10

El atributo columnas.tipoDato de tipo String es el nombre específico del tipo de dato almacenado: 3.1. LECTORES DE DATOS 135

Date

Se utiliza para indicar el tipo de dato que se está leyendo, a fin de implementar las operaciones de validación y conversión que correspondan con el tipo de dato en particular. Los tipos de datos soportados por la clase LectorTxt son todos los que se indican en el cuadro A.1. En el caso de "float" y "double", se valida que la columna contenga valores numéricos válidos (números del 1 al 9, el guión medio para el signo negativo y el punto decimal). El caso de "Date" valida que el formato de fecha corresponda con el valor de la propiedad

El atributo columnas.formato de tipo String es el formato del dato y se utiliza para valores de tipo Date:

dd/MM/yyyy

El atributo columnas.decimales de tipo int indica la cantidad de caracteres a consi- derar como dígitos decimales al lado derecho del valor:

2

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la clase LectorTxt es el que se muestra en la figura 3.3, y corresponde a un archivo de texto por posición (TXT). Contiene cuatro columnas de datos delimitadas por posición: Folio, Fecha, Concepto e Importe; y datos de ejemplo que hacen referencia a Movimientos Bancarios.

Figura 3.3 Ejemplo de la clase LectorTxt

0·········1·········2·········3·········4·········5···· 0123456789012345678901234567890123456789012345678901234 Folio···Fecha·····Concepto···················Importe··· A120030121/04/2016Transferencia·Interbancaria·000175000 A120030222/04/2016Retiro·en·Ventanilla·······000052050 A120030323/04/2016Depósito·en·Efectivo········000028000 A120030423/04/2016Compra·en·Comercio·········000012720 A120030523/04/2016Retiro·en·Cajero·Automático000030000 A120030624/04/2016Depósito·en·Efectivo········000069500 A120030724/04/2016Pago·SPEI·a·Proveedor······000050000 A120030824/04/2016Comercio·S.A.··············000024730 A120030925/04/2016Retiro·en·Cajero·Automático000030000 A120031025/04/2016Transferencia·Interbancaria·000168000

La estructura de configuración XML para una instancia de la clase LectorTxt se muestra 136 3. IMPLEMENTACIÓN

en la configuración C.5.

Un ejemplo completo de implementación para una instancia de la clase LectorTxt se muestra en la configuración C.6. 3.1. LECTORES DE DATOS 137

3.1.4. Lector XML

Para realizar la lectura de una estructura de datos basada en un archivo de texto con formato XML, se utiliza la clase LectorXml representada en el diagrama 3.5.

Diagrama 3.5 Clase LectorXml

En el cuadro 3.4 se enlistan los atributos que definen a la clase LectorXml.

Cuadro 3.4 Atributos de la Clase LectorXml Atributo Tipo Descripción nombre String Descripción de la instancia de la clase LectorXml rutaArchivo String Ubicación del archivo XML columnas List Contiene una lista de instancias de la clase Columna

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase LectorXml:

El atributo rutaArchivo de tipo String es la ubicación del archivo mediante la ruta de acceso y el nombre completo del archivo XML:

data/movimientos.xml

El atributo columnas de tipo List contiene la configuración de las columnas de datos en el archivo XML, mediante una lista de instancias de la clase Columna. 138 3. IMPLEMENTACIÓN

...

El atributo columnas.nombre de tipo String es un alias con el que se hará referencia a la columna durante su procesamiento:

Fecha

El atributo columnas.posicion de tipo int indica la posición relativa de la columna en la fuente de datos:

2

El atributo columnas.tipoDato de tipo String es el nombre específico del tipo de dato almacenado:

Date

Se utiliza para indicar el tipo de dato que se está leyendo, a fin de implementar las operaciones de validación y conversión que correspondan con el tipo de dato en particular. Los tipos de datos soportados por la clase LectorTxt son todos los que se indican en el cuadro A.1. En el caso de "float" y "double", se valida que la columna contenga valores numéricos válidos (números del 1 al 9, el guión medio para el signo negativo y el punto decimal). El caso de "Date" valida que el formato de fecha corresponda con el valor de la propiedad

El atributo columnas.formato de tipo String es el formato del dato y se utiliza para valores de tipo Date:

dd/MM/yyyy

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la clase LectorXml es el que se muestra en la figura 3.4, y corresponde a un archivo de texto con formato XML (eXtensible Markup Language). Contiene cuatro columnas de datos: folio, fecha, concepto e importe; y datos de ejemplo que hacen referencia a Movimientos Bancarios.

Figura 3.4 Ejemplo de la clase LectorXml

A1200301 3.1. LECTORES DE DATOS 139

21/04/2016 Transferencia Interbancaria 1750.00 A1200302 22/04/2016 Retiro en Ventanilla -520.50 A1200303 23/04/2016 Depósito en Efectivo 280.00 A1200304 23/04/2016 Compra en Comercio -127.20 A1200305 23/04/2016 Retiro en Cajero Automático -300.00 A1200306 24/04/2016 Depósito en Efectivo 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor -500.00 A1200308 24/04/2016 140 3. IMPLEMENTACIÓN

Comercio S.A. -247.30 A1200309 25/04/2016 Retiro en Cajero Automático -300.00 A1200310 25/04/2016 Transferencia Interbancaria 1680.00

La estructura de configuración XML para una instancia de la clase LectorXml se muestra en la configuración C.7.

Un ejemplo completo de implementación para una instancia de la clase LectorXml se muestra en la configuración C.8. 3.2. PROCESADORES DE DATOS 141

3.2. Procesadores de Datos

El modelo de objetos para los procesadores de datos parte de una interface llamada Procesador, mostrada en el diagrama 3.6.

Diagrama 3.6 Interface Procesador

Aquí se aplica el principio de la herencia (sección 1.7.4), pues los procesadores tienen que implementar la operación procesarDatos() (cuyo parámetro tablas es una lista de objetos de tipo Tabla que contiene los datos modificados por cada procesador) de la interface Procesador, heredando así el comportamiento para procesar los datos.

Y también se aplica el principio del polimorfismo (sección 1.7.2), pues cada uno de los tres procesadores del diagrama 3.6 (ProcesadorFusionar, ProcesadorUnir y Procesa- dorAgrupar) tiene propiedades diferentes, según las necesidades de cada procesador. 142 3. IMPLEMENTACIÓN

3.2.1. Procesador Agrupar

Para realizar el procesamiento basado en un agrupamiento de datos, se utiliza la clase ProcesadorAgrupar representada en el diagrama 3.7.

Diagrama 3.7 Clase ProcesadorAgrupar

El procesamiento efectúa una agrupación basada en un conjunto de columnas cuyos valores servirán de referencia para que, en caso de presentar igualdad entre sí con los mismos valores de otros registros, se agruparán en un sólo registro y se totalizarán los valores de las columnas indicadas en la lista de columnas agregadas.

En el cuadro 3.5 se enlistan los atributos que definen a la clase ProcesadorAgrupar.

Cuadro 3.5 Atributos de la Clase ProcesadorAgrupar Atributo Tipo Descripción Descripción de la instancia de la clase Proce- nombre String sadorAgrupar tablaEntrada String Nombre de la tabla de entrada tablaSalida String Nombre de la tabla de salida columnasAgrupar List Lista de columnas para agrupar columnasTotalizar List Lista de columnas para totalizar

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorAgrupar:

3.2. PROCESADORES DE DATOS 143

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene los registros a los que se aplicará el proceso de agrupado:

Movimientos

El atributo tablaSalida de tipo String, es el nombre de la tabla que contendrá la agrupación de los registros de tablaEntrada:

Totales

El atributo columnasAgrupar de tipo List es una lista con los nombres de las columnas cuyos valores serán utilizados en conjunto para efectuar la agrupación:

Fecha

El atributo columnasTotalizar de tipo List es una lista con los nombres de las columnas cuyos valores serán totalizados de acuerdo con la agrupación efectuada por columnasAgrupar:

Importe

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorAgrupar es el que se muestra en la figura 3.5, e inicia con la tabla Movimientos que contiene dos columnas de datos: Fecha e Importe con datos de

Figura 3.5 Ejemplo de la clase ProcesadorAgrupar

Movimientos Fecha Importe 21/04/2016 1750.00 Totales 22/04/2016 -520.50 Fecha Importe 23/04/2016 280.00 21/04/2016 1750.00 23/04/2016 -127.20 → 22/04/2016 -520.50 23/04/2016 -300.00 23/04/2016 -147.20 24/04/2016 695.00 24/04/2016 -52.30 24/04/2016 -500.00 25/04/2016 1380.00 24/04/2016 -247.30 25/04/2016 1680.00 25/04/2016 -300.00 144 3. IMPLEMENTACIÓN

ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se genera la tabla Totales conteniendo el re- sultado de la agrupación en la columna Fecha, y su correspondiente totalización de valores en la columna Importe.

La estructura de configuración XML para una instancia de la clase ProcesadorAgrupar se muestra en la configuración C.9.

Un ejemplo completo de implementación para una instancia de la clase ProcesadorA- grupar se muestra en la configuración C.10. 3.2. PROCESADORES DE DATOS 145

3.2.2. Procesador Clonar

Para realizar el procesamiento basado en una clonación de columna, se utiliza la clase ProcesadorClonar representada en el diagrama 3.8.

Diagrama 3.8 Clase ProcesadorClonar

El procesamiento realiza una copia exacta de una columna existente.

En el cuadro 3.6 se enlistan los atributos que definen a la clase ProcesadorClonar.

Cuadro 3.6 Atributos de la Clase ProcesadorClonar Atributo Tipo Descripción Descripción de la instancia de la clase Procesador- nombre String Clonar tablaEntrada String Nombre de la tabla con la columna a clonar columnaEntrada String Nombre de la columna a clonar columnaSalida String Nombre de la columna de salida reemplazarColumna boolean Indicador de reemplazo de columna

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorClonar:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene la columna a la que se aplicará el proceso de clonación:

Movimientos 146 3. IMPLEMENTACIÓN

El atributo columnaEntrada de tipo String, es el nombre de la columna existente cuyos valores serán clonados hacia columnaSalida:

Importe

El atributo columnaSalida de tipo String, es el nombre de la columna nueva o exis- tente cuyos valores serán clonados desde columnaEntrada:

Cantidad

El atributo reemplazarColumna de tipo boolean, indica si se debe reemplazar la colum- na en caso de que ya exista una con el mismo nombre indicado por columnaEntrada; en caso de que su valor sea false, suspende el proceso de clonación de la columna:

true

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorClonar es el que se muestra en la figura 3.6, donde los datos de entrada al proceso provienen de la tabla Movimientos conteniendo la columna Folio con valores llave; y las columnas: Fecha e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se actualiza la tabla Movimientos conteniendo la nueva columna Cantidad, que es una copia exacta de la columna existente Importe.

La estructura de configuración XML para una instancia de la clase ProcesadorClonar se muestra en la configuración C.11.

Figura 3.6 Ejemplo de la clase ProcesadorClonar

Movimientos Movimientos Folio Importe Folio Importe Cantidad A1200301 1750.00 A1200301 1750.00 1750.00 A1200302 -520.50 A1200302 -520.50 -520.50 A1200303 280.00 A1200303 280.00 280.00 A1200304 -127.20 → A1200304 -127.20 -127.20 A1200305 -300.00 A1200305 -300.00 -300.00 A1200306 695.00 A1200306 695.00 695.00 A1200307 -500.00 A1200307 -500.00 -500.00 A1200308 -247.30 A1200308 -247.30 -247.30 A1200309 -300.00 A1200309 -300.00 -300.00 A1200310 1680.00 A1200310 1680.00 1680.00 3.2. PROCESADORES DE DATOS 147

Un ejemplo completo de implementación para una instancia de la clase Procesador- Clonar se muestra en la configuración C.12. 148 3. IMPLEMENTACIÓN

3.2.3. Procesador Clonar Tabla

Para realizar el procesamiento basado en una clonación de tabla, se utiliza la clase ProcesadorClonarTabla representada en el diagrama 3.9.

Diagrama 3.9 Clase ProcesadorClonarTabla

El procesamiento realiza una copia exacta de una tabla existente, dando la opción de reemplazarla o no si es que ya existiese una tabla con el mismo nombre de tablaSalida.

En el cuadro 3.7 se enlistan los atributos que definen a la clase ProcesadorClonarTa- bla.

Cuadro 3.7 Atributos de la Clase ProcesadorClonarTabla Atributo Tipo Descripción Descripción de la instancia de la clase Procesador- nombre String ClonarTabla tablaEntrada String Nombre de la tabla a clonar tablaSalida String Nombre de la tabla de salida reemplazarTabla boolean Indicador de reemplazo de tabla

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorClonarTabla:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene los registros a los que se aplicará el proceso de clonado: 3.2. PROCESADORES DE DATOS 149

Movimientos

El atributo tablaSalida de tipo String, es el nombre de la tabla que será un clon de la estructura y los registros de tablaEntrada:

Detalles

El atributo reemplazarTabla de tipo boolean, indica si se debe reemplazar la tabla en caso de que ya exista una con el mismo nombre indicado por tablaSalida; en caso de que su valor sea false, suspende el proceso de clonado de la tabla.

true

Figura 3.7 Ejemplo de la clase ProcesadorClonarTabla

Movimientos Folio Fecha Importe A1200301 21/04/2016 1750.00 A1200302 22/04/2016 -520.50 A1200303 23/04/2016 280.00 A1200304 23/04/2016 -127.20 A1200305 23/04/2016 -300.00 A1200306 24/04/2016 695.00 A1200307 24/04/2016 -500.00 A1200308 24/04/2016 -247.30 A1200309 25/04/2016 -300.00 A1200310 25/04/2016 1680.00 ↓

Movimientos Detalles Folio Fecha Importe Folio Fecha Importe A1200301 21/04/2016 1750.00 A1200301 21/04/2016 1750.00 A1200302 22/04/2016 -520.50 A1200302 22/04/2016 -520.50 A1200303 23/04/2016 280.00 A1200303 23/04/2016 280.00 A1200304 23/04/2016 -127.20 A1200304 23/04/2016 -127.20 A1200305 23/04/2016 -300.00 A1200305 23/04/2016 -300.00 A1200306 24/04/2016 695.00 A1200306 24/04/2016 695.00 A1200307 24/04/2016 -500.00 A1200307 24/04/2016 -500.00 A1200308 24/04/2016 -247.30 A1200308 24/04/2016 -247.30 A1200309 25/04/2016 -300.00 A1200309 25/04/2016 -300.00 A1200310 25/04/2016 1680.00 A1200310 25/04/2016 1680.00 150 3. IMPLEMENTACIÓN

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorClonarTabla es el que se muestra en la figura 3.7, donde los datos de entrada al proceso provienen de la tabla Movimientos conteniendo la columna Folio con valores llave; y las columnas: Fecha e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se genera la tabla de salida Detalles conteniendo el resultado del clonado de la tabla Movimientos.

La estructura de configuración XML para una instancia de la clase ProcesadorClonar- Tabla se muestra en la configuración C.13.

Un ejemplo completo de implementación para una instancia de la clase Procesador- ClonarTabla se muestra en la configuración C.14. 3.2. PROCESADORES DE DATOS 151

3.2.4. Procesador Comparar

Para realizar el procesamiento basado en una comparación de datos, se utiliza la clase ProcesadorComparar representada en el diagrama 3.10.

Diagrama 3.10 Clase ProcesadorComparar

En el cuadro 3.8 se enlistan los atributos que definen a la clase ProcesadorComparar.

Cuadro 3.8 Atributos de la Clase ProcesadorComparar Atributo Tipo Descripción Descripción de la instancia de la clase nombre String ProcesadorComparar tablaEntrada String Nombre de la tabla a comparar Nombre de la tabla de salida con igual- tablaIgualdades String dades Nombre de la tabla de salida con de- tablaDesigualdades String sigualdades Nombre de la tabla de salida con el tablaReporteDiferencias String reporte de diferencias Prefijo que define las columnas de la prefijoColumnasPrimera String primera tabla Prefijo que define las columnas de la prefijoColumnasSegunda String segunda tabla columnasLlave List Lista de columnas llave columnasValor List Lista de columnas valor 152 3. IMPLEMENTACIÓN

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorComparar:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene los registros a los que se aplicará el proceso de comparación:

LlavesConIgualdad

El atributo tablaIgualdades de tipo String, es el nombre de la tabla de salida que contendrá los registros con las igualdades entre las columnas valor definidas en colum- nasValor, en combinación con los valores definidos en prefijoColumnasPrimera y en prefijoColumnasSegunda, en la tabla definida en tablaEntrada:

ValoresConIgualdad

El atributo tablaDesigualdades de tipo String, es el nombre de la tabla de salida que contendrá los registros con las desigualdades entre las columnas valor definidas en columnasValor, en combinación con los valores definidos en prefijoColumnasPrimera y en prefijoColumnasSegunda, en la tabla definida en tablaEntrada.

ValoresConDesigualdad

El atributo tablaReporteDiferencias de tipo String, es el nombre de la tabla de salida que contendrá una columna llave por cada elemento definido en columnasLlave con todos los valores llave de la tabla definida en tablaEntrada, y una columna valor con valores de tipo boolean indicando con el valor true indicando si hubo diferencias entre las columnas definidas en columnasValor, en combinación con los valores definidos en prefijoColumnasPrimera y en prefijoColumnasSegunda:

ReporteDiferencias

El atributo prefijoColumnasPrimera de tipo String, es el valor prefijo que antecede al nombre de las columnas valor definidas en columnasValor provenientes de la primera fuente de datos en la tabla definida en tablaEntrada, y que serán comparadas con las columnas definidas por prefijoColumnasSegunda:

t1_

El atributo prefijoColumnasSegunda de tipo String, es el valor prefijo que antecede al nombre de las columnas valor definidas en columnasValor provenientes de la segunda fuente de datos en la tabla definida en tablaEntrada, y que serán comparadas con las columnas definidas por prefijoColumnasPrimera: 3.2. PROCESADORES DE DATOS 153

t2_

El atributo columnasLlave de tipo List es una lista con las columnas llave en la tabla definida en tablaEntrada: Folio

Como resultado de la configuración anterior, se agregaría la columna llave Folio en tablaIgualdades y en tablaDesigualdades, conteniendo los valores originales en la tabla definida en tablaEntrada.

El atributo columnasValor de tipo List es una lista con las columnas con valores informativos en la tabla definida en tablaEntrada, que serán comparados en combinación con los valores de los atributos prefijoColumnasPrimera y prefijoCo- lumnasSegunda: Fecha Importe

Como resultado de la configuración anterior, se compararía la columna valor t1_Fecha con la columna valor t2_Fecha, y la columna valor t1_Importe con la columna valor t2_Importe.

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorComparar es el que se muestra en la figura 3.8, donde los datos de entrada al proceso provienen de la tabla LlavesConIgualdad, obtenida como resultado de un procesamiento anterior de la clase ProcesadorConciliar (sección 3.2.5).

La tabla contiene una columna Folio con valores llave; columnas t1_Fecha y t1_Importe con valores provenientes de la primera fuente de datos; y columnas t2_Fecha, t2_Importe y t2_Tipo con valores provenientes de la segunda fuente de datos. La tabla contiene datos de ejemplo que hacen referencia a Movimientos Bancarios.

El procesamiento realiza una comparación entre el conjunto de una o más columnas va- lor definidas en la propiedad columnasValor, en combinación con los valores definidos en la propiedad prefijoColumnasPrimera ("t1_") y en la propiedad prefijoColum- nasSegunda ("t2_").

Es decir, si la propiedad columnasValor contiene un elemento con el valor "Fecha", se realizará una comparación entre las columnas "t1_Fecha" y "t2_Fecha" de la tabla 154 3. IMPLEMENTACIÓN

definida en la propiedad tablaEntrada ("LlavesConIgualdad").

Luego del procesamiento, se generan dos tablas con sus correspondientes nombres definidos en la propiedad tablaIgualdades ("ValoresConIgualdad") y en la propiedad tablaDesigualdades ("ValoresConDesigualdad"), conteniendo la primera los registros con igualdades entre su conjunto de campos llave, y la segunda conteniendo los registros que no tuvieron igualdades con el conjunto de campos llave entre las tablas de entrada.

Figura 3.8 Ejemplo de la clase ProcesadorComparar

LlavesConIgualdad Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200302 22/04/2016 -520.50 22/04/2016 -520.50 Cargo A1200303 23/04/2016 280.00 22/04/2016 280.00 Abono A1200304 23/04/2016 -127.20 23/04/2016 -127.20 Cargo A1200305 23/04/2016 -300.00 23/04/2016 -300.00 Cargo A1200306 24/04/2016 695.50 24/04/2016 695.00 Abono A1200307 24/04/2016 -500.00 24/04/2016 -500.00 Cargo A1200308 24/04/2016 -247.00 24/04/2016 -247.30 Cargo ↓

ValoresConIgualdad Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200302 22/04/2016 -520.50 22/04/2016 -520.50 Cargo A1200304 23/04/2016 -127.20 23/04/2016 -127.20 Cargo A1200305 23/04/2016 -300.00 23/04/2016 -300.00 Cargo A1200307 24/04/2016 -500.00 24/04/2016 -500.00 Cargo

ValoresConDesigualdad Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200303 23/04/2016 280.00 22/04/2016 280.00 Abono A1200306 24/04/2016 695.50 24/04/2016 695.00 Abono A1200308 24/04/2016 -247.00 24/04/2016 -247.30 Cargo

ReporteDiferencias Folio Fecha Importe A1200303 true false A1200306 false true A1200308 false true 3.2. PROCESADORES DE DATOS 155

Es decir, ambas tablas contienen una columna Folio con valores llave; columnas t1_Fecha y t1_Importe con valores provenientes de la primera fuente de datos; y columnas t2_Fecha, t2_Importe y t2_Tipo con valores provenientes de la segunda fuente de datos.

Además, se genera otra tabla cuyo nombre está definido en la propiedad tablaRe- porteDiferencias ("ReporteDiferencias"), conteniendo una columna llave por cada elemento definido en la propiedad columnasLlave y una columna valor por cada ele- mento definido en la propiedad columnasValor.

Es decir, la tabla contiene una columna Folio con todos los valores llave de la tabla definida en la propiedad tablaEntrada ("LlavesConIgualdad"), y columnas Fecha e Importe con valores de tipo boolean indicando con el valor true indicando si hubo diferencias entre las columnas t1_Fecha y t2_Fecha, o entre las columnas t1_Importe y t2_Importe.

La estructura de configuración XML para una instancia de la clase ProcesadorComparar se muestra en la configuración C.15.

Un ejemplo completo de implementación para una instancia de la clase Procesador- Comparar se muestra en la configuración C.16. 156 3. IMPLEMENTACIÓN

3.2.5. Procesador Conciliar

Para realizar el procesamiento basado en una conciliación de datos, se utiliza la clase ProcesadorConciliar representada en el diagrama 3.11.

Diagrama 3.11 Clase ProcesadorConciliar

En el cuadro 3.9 se enlistan los atributos que definen a la clase ProcesadorConciliar.

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorConciliar:

El atributo tablaEntradaPrimera de tipo String, es el nombre de la primera tabla existente que contiene los registros a los que se aplicará el proceso de conciliación:

MOVIMIENTOS

El atributo tablaEntradaSegunda de tipo String, es el nombre de la segunda tabla existente que contiene los registros a los que se aplicará el proceso de conciliación:

ACCOUNT_STATUS 3.2. PROCESADORES DE DATOS 157

Cuadro 3.9 Atributos de la Clase ProcesadorConciliar Atributo Tipo Descripción Descripción de la instancia de la nombre String clase ProcesadorConciliar Nombre de la primera tabla a con- tablaEntradaPrimera String ciliar Nombre de la segunda tabla a con- tablaEntradaSegunda String ciliar Nombre de la tabla de salida con tablaIgualdades String igualdades Nombre de la tabla de salida con tablaDesigualdades String desigualdades Prefijo anexado a columnas de la prefijoColumnasPrimera String primera tabla Prefijo anexado a columnas de la prefijoColumnasSegunda String segunda tabla columnasLlave List Lista de columnas llave columnasValor List Lista de columnas valor

El atributo tablaIgualdades de tipo String, es el nombre de la tabla de salida que contendrá los registros con las igualdades entre las columnas llave de tablaEntrada- Primera y tablaEntradaSegunda, definidas en columnasLlave:

LlavesConIgualdad

El atributo tablaDesigualdades de tipo String, es el nombre de la tabla de salida que contendrá los registros con las desigualdades entre las columnas llave de tablaEntra- daPrimera y tablaEntradaSegunda, definidas en columnasLlave:

LlavesConDesigualdad

El atributo prefijoColumnasPrimera de tipo String, es el valor prefijo que se añadirá a los nombres de las columnas de tablaEntradaPrimera, definidas en columnasValor y que serán generadas en tablaIgualdades y tablaDesigualdades:

t1_

El atributo prefijoColumnasSegunda de tipo String, es el valor prefijo que se añadirá a los nombres de las columnas de tablaEntradaSegunda, definidas en columnasValor y que serán generadas en tablaIgualdades y tablaDesigualdades:

t2_

El atributo columnasLlave de tipo List es una lista con la configuración de los pares de columnas a comparar, de acuerdo con los atributos que definen a la 158 3. IMPLEMENTACIÓN

Cuadro 3.10 Atributos de la Clase ParColumna Atributo Tipo Descripción Nombre base de la columna a generar en tablaIgualdades y nombre String tablaDesigualdades primera String Nombre original de la columna en tablaEntradaPrimera segunda String Nombre original de la columna en tablaEntradaSegunda

clase ParColumna enlistados en el cuadro 3.10:

Folio NUMERO ID

Como resultado de la configuración anterior, se agregaría la columna llave Folio en tablaIgualdades y en tablaDesigualdades, conteniendo los valores coincidentes en- tre la columna llave NUMERO en la tabla definida en la propiedad tablaEntradaPrimera ("MOVIMIENTOS"), y la columna llave ID en la tabla definida en la propiedad tablaEn- tradaSegunda ("ACCOUNT_STATUS").

El atributo columnasValor de tipo List es una lista con la configuración de los pares de columnas con valores informativos, de acuerdo con los atributos que definen a la clase ParColumna enlistados en el cuadro 3.10 y en combinación con los valores de los atributos prefijoColumnasPrimera y prefijoColumnasSegunda:

Importe IMPORTE AMOUNT

Como resultado de la configuración anterior, se agregaría la columna valor t1_Importe conteniendo los valores originales de la columna IMPORTE en la tabla definida en la propiedad tablaEntradaPrimera ("MOVIMIENTOS"), y se agregaría también la columna valor t2_Importe conteniendo los valores originales de la columna AMOUNT en la tabla definida en la propiedad tablaEntradaSegunda ("ACCOUNT_STATUS"). 3.2. PROCESADORES DE DATOS 159

El atributo nombre de tipo String, es el nombre base que se asignará a las columnas generadas en tablaIgualdades y tablaDesigualdades:

Folio

El atributo primera de tipo String, es el nombre original de la columna en tablaEn- tradaPrimera, en combinación con el valor del atributo prefijoColumnasPrimera:

Total

El atributo segunda de tipo String, es el nombre original de la columna en tablaEn- tradaSegunda, en combinación con el valor del atributo prefijoColumnasSegunda:

ID

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorConciliar es el que se muestra en la figura 3.9, donde los datos de entrada al proceso provienen de las tablas MOVIMIENTOS y ACCOUNT_STATUS (estado de cuenta), la primera conteniendo una columna NUMERO y la segunda una columna ID, ambas con valores llave.

La tabla MOVIMIENTOS contiene, además, dos columnas de datos: FECHA e IMPORTE; y la tabla ACCOUNT_STATUS contiene tres columnas de datos: DATE (fecha), AMOUNT (cantidad) y TYPE (tipo). Ambas tablas con datos de ejemplo que hacen referencia a Movimientos Bancarios.

El procesamiento realiza una conciliación entre las dos tablas definidas en la propie- dad tablaEntradaPrimera ("MOVIMIENTOS") y en la propiedad tablaEntradaSegunda ("ACCOUNT_STATUS"), llevando a cabo una comparación directa entre el conjunto de una o más columnas llave, definidas en la propiedad columnasLlave.

Es decir, dentro de las propiedades de columnasLlave, la propiedad nombre ("Folio") es el nombre de la única columna llave que será generada en las tablas definidas en las propiedades tablaIgualdades ("LlavesConIgualdad") y tablaDesigualdades ("LlavesConDesigualdad").

La propiedad primera ("NUMERO") dentro de la propiedad columnasLlave es el nom- bre de la columna llave en la tabla definida en la propiedad tablaEntradaPrimera ("MOVIMIENTOS") cuyo valor será comparado con la columna definida en la propiedad segunda ("ID") dentro de la propiedad columnasLlave, que es el nombre de la columna llave en la tabla definida en la propiedad tablaEntradaSegunda ("ACCOUNT_STATUS").

Luego del procesamiento, también se generan nuevas columnas en las tablas definidas en la propiedad tablaIgualdades ("LlavesConIgualdad") y en la propiedad tabla- 160 3. IMPLEMENTACIÓN

Desigualdades ("LlavesConDesigualdad") con base en el conjunto de una o más columnas valor, definidas en la propiedad columnasValor.

Es decir, dentro de las propiedades de columnasValor, la propiedad nombre ("Importe") es el nombre base de las dos columnas valor que serán generadas en las tablas definidas en las propiedades tablaIgualdades ("LlavesConIgualdad") y tablaDesigualdades ("LlavesConDesigualdad"), en combinación con los valores definidos en la propiedad prefijoColumnasPrimera ("t1_") y en la propiedad prefijoColumnasSegunda ("t2_").

Figura 3.9 Ejemplo de la clase ProcesadorConciliar

ACCOUNT_STATUS MOVIMIENTOS ID DATE AMOUNT TYPE NUMERO FECHA IMPORTE A1200302 22/04/2016 -520.50 Cargo A1200301 21/04/2016 1750.00 A1200303 23/04/2016 280.00 Abono A1200302 22/04/2016 -520.50 A1200304 23/04/2016 -127.20 Cargo A1200303 22/04/2016 280.00 A1200305 23/04/2016 -300.00 Cargo A1200304 23/04/2016 -127.20 A1200306 24/04/2016 695.00 Abono A1200305 23/04/2016 -300.00 A1200307 24/04/2016 -500.00 Cargo A1200306 24/04/2016 695.50 A1200308 24/04/2016 -247.30 Cargo A1200307 24/04/2016 -500.00 A1200309 25/04/2016 -300.00 Cargo A1200308 24/04/2016 -247.00 A1200310 25/04/2016 1680.00 Abono ↓

LlavesConIgualdad Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200302 22/04/2016 -520.50 22/04/2016 -520.50 Cargo A1200303 23/04/2016 280.00 22/04/2016 280.00 Abono A1200304 23/04/2016 -127.20 23/04/2016 -127.20 Cargo A1200305 23/04/2016 -300.00 23/04/2016 -300.00 Cargo A1200306 24/04/2016 695.50 24/04/2016 695.00 Abono A1200307 24/04/2016 -500.00 24/04/2016 -500.00 Cargo A1200308 24/04/2016 -247.00 24/04/2016 -247.30 Cargo

LlavesConDesigualdad Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200301 21/04/2016 1750.00 A1200309 25/04/2016 -300.00 Cargo A1200310 25/04/2016 1680.00 Abono 3.2. PROCESADORES DE DATOS 161

La propiedad primera ("IMPORTE") dentro de la propiedad columnasValor es el nom- bre de la columna valor en la tabla definida en la propiedad tablaEntradaPrimera ("MOVIMIENTOS") cuyos valores serán agregados a una nueva columna cuyo nombre ("t1_Importe") es la combinación de los valores definidos en la propiedad prefijo- ColumnasPrimera ("t1_") y en la propiedad nombre ("Importe").

La propiedad segunda ("AMOUNT") dentro de la propiedad columnasValor es el nom- bre de la columna valor en la tabla definida en la propiedad tablaEntradaSegunda ("ACCOUNT_STATUS") cuyos valores serán agregados a una nueva columna cuyo nombre ("t2_Importe") es la combinación de los valores definidos en la propiedad prefijo- ColumnasSegunda ("t2_") y en la propiedad nombre ("Importe").

La estructura de configuración XML para una instancia de la clase ProcesadorConciliar se muestra en la configuración C.17.

Un ejemplo completo de implementación para una instancia de la clase Procesador- Conciliar se muestra en la configuración C.18. 162 3. IMPLEMENTACIÓN

3.2.6. Procesador Dividir

Para realizar el procesamiento basado en una división de datos, se utiliza la clase ProcesadorDividir representada en el diagrama 3.12.

Diagrama 3.12 Clase ProcesadorDividir

El procesamiento efectúa la división de una tabla hacia dos tablas de salida, de acuerdo con las columnas señaladas para ser incluidas en cada tabla de salida.

En el cuadro 3.11 se enlistan los atributos que definen a la clase ProcesadorDividir.

Cuadro 3.11 Atributos de la Clase ProcesadorDividir Atributo Tipo Descripción Descripción de la instancia de la clase Pro- nombre String cesadorDividir tablaEntrada String Nombre de la tabla de entrada tablaSalidaPrimera String Nombre de la primera tabla de salida tablaSalidaSegunda String Nombre de la segunda tabla de salida Lista de columnas para la primera tabla de columnasPrimera List salida Lista de columnas para la segunda tabla de columnasSegunda List salida

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorDividir:

3.2. PROCESADORES DE DATOS 163

El atributo tablaEntrada de tipo String, es el nombre de la tabla que contiene los registros que se dividirán hacia las tablas tablaSalidaPrimera y tablaSalidaSegunda:

Movimientos

El atributo tablaSalidaPrimera de tipo String, es el nombre de la primera tabla que contendrá las columnas de datos indicadas en columnasPrimera:

Detalles

El atributo tablaSalidaSegunda de tipo String, es el nombre de la segunda tabla que contendrá las columnas de datos indicadas en columnasSegunda:

Figura 3.10 Ejemplo de la clase ProcesadorDividir

Movimientos Folio Fecha Concepto Importe A1200301 21/04/2016 Transferencia Interbancaria 1750.00 A1200302 22/04/2016 Retiro en Ventanilla -520.50 A1200303 23/04/2016 Depósito en Efectivo 280.00 A1200304 23/04/2016 Compra en Comercio -127.20 A1200305 23/04/2016 Retiro en Cajero Automático -300.00 A1200306 24/04/2016 Depósito en Efectivo 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor -500.00 A1200308 24/04/2016 Comercio S.A. -247.30 A1200309 25/04/2016 Retiro en Cajero Automático -300.00 A1200310 25/04/2016 Transferencia Interbancaria 1680.00 ↓

Detalles Importes Folio Fecha Concepto Folio Importe A1200301 21/04/2016 Transferencia Interbancaria A1200301 1750.00 A1200302 22/04/2016 Retiro en Ventanilla A1200302 -520.50 A1200303 23/04/2016 Depósito en Efectivo A1200303 280.00 A1200304 23/04/2016 Compra en Comercio A1200304 -127.20 A1200305 23/04/2016 Retiro en Cajero Automático A1200305 -300.00 A1200306 24/04/2016 Depósito en Efectivo A1200306 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor A1200307 -500.00 A1200308 24/04/2016 Comercio S.A. A1200308 -247.30 A1200309 25/04/2016 Retiro en Cajero Automático A1200309 -300.00 A1200310 25/04/2016 Transferencia Interbancaria A1200310 1680.00 164 3. IMPLEMENTACIÓN

Importes

El atributo columnasPrimera de tipo List es una lista con los nombres de las columnas de tablaEntrada que serán añadidas a tablaSalidaPrimera: Folio Fecha Concepto

El atributo columnasSegunda de tipo List es una lista con los nombres de las columnas de tablaEntrada que serán añadidas a tablaSalidaSegunda: Folio Importe

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorDividir es el que se muestra en la figura 3.10, donde los datos de entrada al proceso provienen de la tabla Movimientos conteniendo la columna Folio con valores llave; y las columnas: Fecha, Concepto e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se generan las tablas Detalles e Importes conteniendo el resultado de la división con las columnas de datos seleccionadas para cada una de las tablas de salida.

La estructura de configuración XML para una instancia de la clase ProcesadorDividir se muestra en la configuración C.19.

Un ejemplo completo de implementación para una instancia de la clase ProcesadorDi- vidir se muestra en la configuración C.20. 3.2. PROCESADORES DE DATOS 165

3.2.7. Procesador Eliminar

Para realizar el procesamiento basado en una eliminación de columnas, se utiliza la clase ProcesadorEliminar representada en el diagrama 3.13.

Diagrama 3.13 Clase ProcesadorEliminar

El procesamiento realiza la eliminación de una o más columnas de una tabla existente.

En el cuadro 3.12 se enlistan los atributos que definen a la clase ProcesadorEliminar.

Cuadro 3.12 Atributos de la Clase ProcesadorEliminar Atributo Tipo Descripción Descripción de la instancia de la clase Proce- nombre String sadorEliminar tablaEntrada String Nombre de la tabla con las columnas a eliminar columnasEliminar List Lista de columnas para eliminar

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorEliminar:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene los registros a los que se aplicará el proceso de eliminado:

LlavesConIgualdad

El atributo columnasEliminar de tipo List es una lista con los nombres de las columnas para efectuar la eliminación: 166 3. IMPLEMENTACIÓN

t1_Importe t2_Fecha

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorEliminar es el que se muestra en la figura 3.11, donde los datos de entrada al proceso provienen de la tabla LlavesConIgualdad conteniendo la columna Folio con valores llave; y las columnas: t1_Fecha, t1_Importe, t2_Fecha, t2_Importe y t2_Tipo con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se actualiza la tabla LlavesConIgualdad conte- niendo el resultado de la eliminación de las columnas t1_Importe y t2_Fecha.

La estructura de configuración XML para una instancia de la clase ProcesadorEliminar se muestra en la configuración C.21.

Figura 3.11 Ejemplo de la clase ProcesadorEliminar

LlavesConIgualdad Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200302 22/04/2016 -520.50 22/04/2016 -520.50 Cargo A1200303 22/04/2016 280.00 22/04/2016 280.00 Abono A1200304 23/04/2016 -127.20 23/04/2016 -127.20 Cargo A1200305 23/04/2016 -300.00 23/04/2016 -300.00 Cargo A1200306 24/04/2016 695.50 24/04/2016 695.50 Abono A1200307 24/04/2016 -500.00 24/04/2016 -500.00 Cargo A1200308 24/04/2016 -247.30 24/04/2016 -247.30 Cargo ↓

LlavesConIgualdad Folio t1_Fecha t2_Importe t2_Tipo A1200302 22/04/2016 -520.50 Cargo A1200303 22/04/2016 280.00 Abono A1200304 23/04/2016 -127.20 Cargo A1200305 23/04/2016 -300.00 Cargo A1200306 24/04/2016 695.50 Abono A1200307 24/04/2016 -500.00 Cargo A1200308 24/04/2016 -247.30 Cargo 3.2. PROCESADORES DE DATOS 167

Un ejemplo completo de implementación para una instancia de la clase ProcesadorE- liminar se muestra en la configuración C.22. 168 3. IMPLEMENTACIÓN

3.2.8. Procesador Eliminar Tabla

Para realizar el procesamiento basado en una eliminación de tablas, se utiliza la clase ProcesadorEliminarTabla representada en el diagrama 3.14.

Diagrama 3.14 Clase ProcesadorEliminarTabla

El procesamiento realiza la eliminación de una o más tablas existentes.

En el cuadro 3.13 se enlistan los atributos que definen a la clase ProcesadorElimi- narTabla.

Cuadro 3.13 Atributos de la Clase ProcesadorEliminarTabla Atributo Tipo Descripción Descripción de la instancia de la clase Procesa- nombre String dorEliminarTabla tablasEliminar List Lista de tablas para eliminar

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorEliminarTabla:

El atributo tablasEliminar de tipo List es una lista con los nombres de las tablas para efectuar la eliminación: Detalles 3.2. PROCESADORES DE DATOS 169

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorEliminarTabla es el que se muestra en la figura 3.12, donde los datos de entrada al proceso provienen de las tablas Movimientos y Detalles, ambas con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se elimina la tabla Detalles, conservándose la otra tabla Movimientos.

La estructura de configuración XML para una instancia de la clase ProcesadorElimi- narTabla se muestra en la configuración C.23.

Figura 3.12 Ejemplo de la clase ProcesadorEliminarTabla

Movimientos Detalles Folio Fecha Importe Folio Fecha Importe A1200301 21/04/2016 1750.00 A1200301 21/04/2016 1750.00 A1200302 22/04/2016 -520.50 A1200302 22/04/2016 -520.50 A1200303 23/04/2016 280.00 A1200303 23/04/2016 280.00 A1200304 23/04/2016 -127.20 A1200304 23/04/2016 -127.20 A1200305 23/04/2016 -300.00 A1200305 23/04/2016 -300.00 A1200306 24/04/2016 695.00 A1200306 24/04/2016 695.00 A1200307 24/04/2016 -500.00 A1200307 24/04/2016 -500.00 A1200308 24/04/2016 -247.30 A1200308 24/04/2016 -247.30 A1200309 25/04/2016 -300.00 A1200309 25/04/2016 -300.00 A1200310 25/04/2016 1680.00 A1200310 25/04/2016 1680.00 ↓

Movimientos Folio Fecha Importe A1200301 21/04/2016 1750.00 A1200302 22/04/2016 -520.50 A1200303 23/04/2016 280.00 A1200304 23/04/2016 -127.20 A1200305 23/04/2016 -300.00 A1200306 24/04/2016 695.00 A1200307 24/04/2016 -500.00 A1200308 24/04/2016 -247.30 A1200309 25/04/2016 -300.00 A1200310 25/04/2016 1680.00 170 3. IMPLEMENTACIÓN

Un ejemplo completo de implementación para una instancia de la clase ProcesadorE- liminarTabla se muestra en la configuración C.24. 3.2. PROCESADORES DE DATOS 171

3.2.9. Procesador Equivaler

Para realizar el procesamiento basado en una equivalencia de datos, se utiliza la clase ProcesadorEquivaler representada en el diagrama 3.15.

Diagrama 3.15 Clase ProcesadorEquivaler

El procesamiento realiza un proceso de equivalencias entre valores en la columna llave de una tabla de datos, contra los valores en una tabla de equivalencias, y reemplaza o agrega el valor de la equivalencia a la columna indicada en la tabla de datos.

En el cuadro 3.14 se enlistan los atributos que definen a la clase ProcesadorEquivaler.

Cuadro 3.14 Atributos de la Clase ProcesadorEquivaler Atributo Tipo Descripción Descripción de la instancia de la clase Procesado- nombre String rEquivaler tablaEntrada String Nombre de la tabla de entrada tablaEquivalencias String Nombre de la tabla de equivalencias columnaLlave String Nombre de columna llave columnaValor String Nombre de columna valor

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorEquivaler:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene los registros a los que se aplicará el proceso de equivalencias: 172 3. IMPLEMENTACIÓN

Movimientos

El atributo tablaEquivalencias de tipo String, es el nombre de la tabla que contiene las equivalencias con dos columnas: Llave, que son los valores que serán compara- dos contra columnaLlave para realizar la equivalencia y Valor, que es el valor de la equivalencia que será actualizado en columnaValor:

Equivalencias

El atributo columnaLlave de tipo List es la columna en tablaEntrada que será comparada contra la columna Llave de tablaEquivalencias:

Figura 3.13 Ejemplo de la clase ProcesadorEquivaler

Movimientos Fecha Concepto Importe Equivalencias 21/04/2016 TRIB 1750.00 Llave Valor 22/04/2016 RTVN -520.50 CMSA Comercio S.A. 23/04/2016 DPEF 280.00 CPCM Compra en Comercio 23/04/2016 CPCM -127.20 DPEF Depósito en Efectivo 23/04/2016 RTCJ -300.00 RTCJ Retiro en Cajero Automático 24/04/2016 DPEF 695.00 RTVN Retiro en Ventanilla 24/04/2016 SPEI -500.00 SPEI Pago SPEI a Proveedor 24/04/2016 CMSA -247.30 TRIB Transferencia Interbancaria 25/04/2016 TRIB 1680.00 25/04/2016 RTCJ -300.00 ↓

Movimientos Fecha Concepto Importe 21/04/2016 Transferencia Interbancaria 1750.00 22/04/2016 Retiro en Ventanilla -520.50 23/04/2016 Depósito en Efectivo 280.00 23/04/2016 Compra en Comercio -127.20 23/04/2016 Retiro en Cajero Automático -300.00 24/04/2016 Depósito en Efectivo 695.00 24/04/2016 Pago SPEI a Proveedor -500.00 24/04/2016 Comercio S.A. -247.30 25/04/2016 Transferencia Interbancaria 1680.00 25/04/2016 Retiro en Cajero Automático -300.00 3.2. PROCESADORES DE DATOS 173

Concepto

El atributo columnaValor de tipo List es la columna en tablaEntrada donde será actualizado con el valor de la columna Valor en tablaEquivalencias en caso de existir coincidencia de valores entre columnaLlave de tablaEntrada y Llave de tablaEquivalencias. En caso de existir la columna, reemplaza los valores:

Concepto

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorEquivaler es el que se muestra en la figura 3.13, e inicia con la tabla Movimientos que contiene tres columnas de datos: Fecha, Concepto y Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Y también con la tabla Mapa de Equivalencias que contiene dos columnas de da- tos: Clave y Concepto con datos de ejemplo que hacen referencia a Equivalencias de Conceptos.

Luego de efectuarse el procesamiento, se actualiza la tabla Movimientos conteniendo el resultado de la equivalencia en la columna Concepto.

La estructura de configuración XML para una instancia de la clase ProcesadorEquivaler se muestra en la configuración C.25.

Un ejemplo completo de implementación para una instancia de la clase ProcesadorE- quivaler se muestra en la configuración C.26. 174 3. IMPLEMENTACIÓN

3.2.10. Procesador Filtrar

Para realizar el procesamiento basado en un filtrado de datos, se utiliza la clase Pro- cesadorFiltrar representada en el diagrama 3.16.

Diagrama 3.16 Clase ProcesadorFiltrar

El procesamiento realiza el filtrado de registros de una tabla existente con base en una fórmula de filtrado, como las que se describen en la sección 2.9.2.

En el cuadro 3.15 se enlistan los atributos que definen a la clase ProcesadorFiltrar.

Cuadro 3.15 Atributos de la Clase ProcesadorFiltrar Atributo Tipo Descripción Descripción de la instancia de la clase ProcesadorFil- nombre String trar tablaEntrada String Nombre de la tabla con las columnas a filtrar formulaFiltrar String Fórmula de filtrado

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorFiltrar:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene los registros a los que se aplicará el proceso de filtrado:

Movimientos 3.2. PROCESADORES DE DATOS 175

El atributo formulaFiltrar de tipo String, es la fórmula que determinará el alcance del filtrado, y está basada en las fórmulas de filtrado descritas en la sección 2.9.2.

{[Fecha] > #2016-04-21# && [Fecha] <= #fechaHoy# && [Importe] < 0.00}

La fórmula que se utiliza filtra cada uno de los valores en la columna Fecha para que cumplan primero la condición de ser mayores que #2016-04-21# (valor constante), después la condición de ser menores o iguales que #fechaHoy# (valor variable, en este caso es igual que #2016-04-24#), y finalmente filtra cada uno de los valores en la columna Importe para que cumplan la condición de ser menores que 0.00 (valor constante).

Figura 3.14 Ejemplo de la clase ProcesadorFiltrar

Movimientos Folio Fecha Concepto Importe A1200301 21/04/2016 Transferencia Interbancaria 1750.00 A1200302 22/04/2016 Retiro en Ventanilla -520.50 A1200303 23/04/2016 Depósito en Efectivo 280.00 A1200304 23/04/2016 Compra en Comercio -127.20 A1200305 23/04/2016 Retiro en Cajero Automático -300.00 A1200306 24/04/2016 Depósito en Efectivo 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor -500.00 A1200308 24/04/2016 Comercio S.A. -247.30 A1200309 25/04/2016 Retiro en Cajero Automático -300.00 A1200310 25/04/2016 Transferencia Interbancaria 1680.00 ↓

Movimientos Folio Fecha Concepto Importe A1200302 22/04/2016 Retiro en Ventanilla -520.50 A1200304 23/04/2016 Compra en Comercio -127.20 A1200305 23/04/2016 Retiro en Cajero Automático -300.00 A1200307 24/04/2016 Pago SPEI a Proveedor -500.00 A1200308 24/04/2016 Comercio S.A. -247.30 176 3. IMPLEMENTACIÓN

El nombre de las columnas se encierra entre corchetes para indicar que los valores serán los que correspondan a cada renglón en la tabla: [Fecha] e [Importe].

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorFiltrar es el que se muestra en la figura 3.14, donde los datos de entrada al proceso provienen de la tabla Movimientos conteniendo la columna Folio con valores llave; y las columnas: Fecha, Concepto e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se actualiza la tabla Movimientos conteniendo el resultado del filtrado de los registros.

La estructura de configuración XML para una instancia de la clase ProcesadorFiltrar se muestra en la configuración C.27.

Un ejemplo completo de implementación para una instancia de la clase Procesador- Filtrar se muestra en la configuración C.28. 3.2. PROCESADORES DE DATOS 177

3.2.11. Procesador Fusionar

Para realizar el procesamiento basado en una fusión de datos, se utiliza la clase Pro- cesadorFusionar representada en el diagrama 3.17.

Diagrama 3.17 Clase ProcesadorFusionar

El procesamiento efectúa una fusión de los datos provenientes de ambas tablas de entrada, con la premisa de que ambas tablas poseen una estructura idéntica de columnas de datos.

En el cuadro 3.16 se enlistan los atributos que definen a la clase ProcesadorFusionar.

Cuadro 3.16 Atributos de la Clase ProcesadorFusionar Atributo Tipo Descripción Descripción de la instancia de la clase Procesa- nombre String dorFusionar tablaEntradaPrimera String Nombre de la primera tabla de entrada tablaEntradaSegunda String Nombre de la segunda tabla de entrada tablaSalida String Nombre de la tabla de salida

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorFusionar:

El atributo tablaEntradaPrimera de tipo String, es el nombre de la primera tabla existente que contiene los registros a los que se aplicará el proceso de fusión: 178 3. IMPLEMENTACIÓN

Depósitos

El atributo tablaEntradaSegunda de tipo String, es el nombre de la segunda tabla existente que contiene los registros a los que se aplicará el proceso de fusión:

Retiros

El atributo tablaSalida de tipo String, es el nombre de la tabla que contendrá la

Figura 3.15 Ejemplo de la clase ProcesadorFusionar

Depósitos Fecha Concepto Importe 21/04/2016 Transferencia Interbancaria 1750.00 23/04/2016 Depósito en Efectivo 280.00 24/04/2016 Depósito en Efectivo 695.00 25/04/2016 Transferencia Interbancaria 1680.00

Retiros Fecha Concepto Importe 22/04/2016 Retiro en Ventanilla -520.50 23/04/2016 Compra en Comercio -127.20 23/04/2016 Retiro en Cajero Automático -300.00 24/04/2016 Pago SPEI a Proveedor -500.00 24/04/2016 Comercio S.A. -247.30 25/04/2016 Retiro en Cajero Automático -300.00 ↓

Movimientos Fecha Concepto Importe 21/04/2016 Transferencia Interbancaria 1750.00 23/04/2016 Depósito en Efectivo 280.00 24/04/2016 Depósito en Efectivo 695.00 25/04/2016 Transferencia Interbancaria 1680.00 22/04/2016 Retiro en Ventanilla -520.50 23/04/2016 Compra en Comercio -127.20 23/04/2016 Retiro en Cajero Automático -300.00 24/04/2016 Pago SPEI a Proveedor -500.00 24/04/2016 Comercio S.A. -247.30 25/04/2016 Retiro en Cajero Automático -300.00 3.2. PROCESADORES DE DATOS 179 fusión de los registros de tablaEntradaPrimera y tablaEntradaSegunda:

Movimientos

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorFusionar es el que se muestra en la figura 3.15, donde los datos de entrada al proceso provienen de las tablas Depósitos y Retiros, ambas con la misma estructura de columnas de datos: Fecha, Concepto e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se genera la tabla Movimientos conteniendo el resultado de la fusión de la totalidad de los renglones de datos de cada una de las tablas de entrada.

La estructura de configuración XML para una instancia de la clase ProcesadorFusionar se muestra en la configuración C.29.

Un ejemplo completo de implementación para una instancia de la clase ProcesadorFu- sionar se muestra en la configuración C.30. 180 3. IMPLEMENTACIÓN

3.2.12. Procesador Insertar

Para realizar el procesamiento basado en una inserción de columna, se utiliza la clase ProcesadorInsertar representada en el diagrama 3.18.

Diagrama 3.18 Clase ProcesadorInsertar

El procesamiento inserta una columna de datos a una tabla existente, permitiendo indicar el tipo de dato y un valor predeterminado que se asignará a todos los registros de la nueva columna con base en una fórmula de transformación, como las que se describen en la sección 2.9.1.

En el cuadro 3.17 se enlistan los atributos que definen a la clase ProcesadorInsertar.

Cuadro 3.17 Atributos de la Clase ProcesadorInsertar Atributo Tipo Descripción Descripción de la instancia de la clase ProcesadorIn- nombre String sertar tablaEntrada String Nombre de la tabla con la columna a insertar columnaEntrada String Nombre de la columna a insertar tipoDato String Tipo de dato de la columna formulaInsertar String Fórmula para inserción

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorInsertar:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- 3.2. PROCESADORES DE DATOS 181 tendrá la columna a la que se aplicará el proceso de inserción:

Movimientos

El atributo columnaEntrada de tipo String, es el nombre de la columna que será insertada en tablaEntrada:

IVA

El atributo tipoDato de tipo String, es el tipo de dato para los valores contenidos en columnaEntrada:

double

El atributo formulaInsertar de tipo String, es la fórmula que determinará el valor de la inserción, y está basada en las fórmulas de transformación descritas en la sección 2.9.1.

{[Importe] * 0.16}

La fórmula que se utiliza obtiene cada uno de los valores en la columna Importe y los multiplica por el valor constante de 0.16, que es el porcentaje para el cálculo del IVA:

El nombre de la columna se encierra entre corchetes para indicar que los valores a uti- lizar para el cálculo serán los que correspondan a cada renglón en la tabla: [Importe].

Los operadores pueden ser cualquier operador Aritmético ('+', '-', '*', '/' y ' %') descritos en el cuadro A.2.

Figura 3.16 Ejemplo de la clase ProcesadorInsertar

Movimientos Movimientos Folio Importe Folio Importe IVA A1200301 1750.00 A1200301 1750.00 280.00 A1200302 -520.50 A1200302 -520.50 -83.28 A1200303 280.00 A1200303 280.00 44.80 A1200304 -127.20 → A1200304 -127.20 -20.35 A1200305 -300.00 A1200305 -300.00 -48.00 A1200306 695.00 A1200306 695.00 111.20 A1200307 -500.00 A1200307 -500.00 -80.00 A1200308 -247.30 A1200308 -247.30 -39.57 A1200309 -300.00 A1200309 -300.00 -48.00 A1200310 1680.00 A1200310 1680.00 268.80 182 3. IMPLEMENTACIÓN

El resultado obtenido por cada renglón de la tabla será insertado como parte de la nueva columna IVA.

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorInsertar es el que se muestra en la figura 3.16, donde los datos de entrada al proceso provienen de la tabla Movimientos conteniendo la columna Folio con valores llave; y la columna: Fecha e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se actualiza la tabla Movimientos conteniendo la nueva columna IVA, que es el cálculo del IVA basado en los valores de la columna existente Importe.

La estructura de configuración XML para una instancia de la clase ProcesadorInsertar se muestra en la configuración C.31.

Un ejemplo completo de implementación para una instancia de la clase ProcesadorIn- sertar se muestra en la configuración C.32. 3.2. PROCESADORES DE DATOS 183

3.2.13. Procesador Ordenar

Para realizar el procesamiento mencionado, basado en un agrupamiento de datos, se utiliza la clase ProcesadorOrdenar representada en el diagrama 3.19.

Diagrama 3.19 Clase ProcesadorOrdenar

El procesamiento efectúa un ordenado basado en una columna o en un conjunto de columnas cuyos valores servirán de referencia para determinar el orden de los registros en la tabla.

En el cuadro 3.18 se enlistan los atributos que definen a la clase ProcesadorOrdenar.

Cuadro 3.18 Atributos de la Clase ProcesadorOrdenar Atributo Tipo Descripción Descripción de la instancia de la clase Procesa- nombre String dorOrdenar tablaEntrada String Nombre de la tabla a ordenar columnasOrdenar List Lista de columnas para ordenar

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorOrdenar:

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tiene los registros a los que se aplicará el proceso de ordenado:

Movimientos 184 3. IMPLEMENTACIÓN

El atributo columnasOrdenar de tipo List es una lista con los nombres de las columnas cuyos valores serán utilizados en conjunto para efectuar el ordenado: Fecha

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorOrdenar es el que se muestra en la figura 3.17, e inicia con la tabla Movimientos que contiene dos columnas de datos: Fecha, Tipo e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se actualiza la tabla Movimientos conteniendo el resultado del ordenado.

La estructura de configuración XML para una instancia de la clase ProcesadorOrdenar se muestra en la configuración C.33.

Un ejemplo completo de implementación para una instancia de la clase ProcesadorOr- denar se muestra en la configuración C.34.

Figura 3.17 Ejemplo de la clase ProcesadorOrdenar

Movimientos Movimientos Fecha Importe Fecha Importe 23/04/2016 280.00 21/04/2016 1750.00 24/04/2016 695.00 22/04/2016 -520.50 25/04/2016 1680.00 23/04/2016 280.00 22/04/2016 -520.50 → 23/04/2016 -127.20 23/04/2016 -127.20 23/04/2016 -300.00 25/04/2016 -300.00 24/04/2016 695.00 23/04/2016 -300.00 24/04/2016 -500.00 24/04/2016 -500.00 24/04/2016 -247.30 21/04/2016 1750.00 25/04/2016 1680.00 24/04/2016 -247.30 25/04/2016 -300.00 3.2. PROCESADORES DE DATOS 185

3.2.14. Procesador Transformar

Para realizar el procesamiento basado en una transformación de columna, se utiliza la clase ProcesadorTransformar representada en el diagrama 3.20.

Diagrama 3.20 Clase ProcesadorTransformar

El procesamiento transforma una columna de datos en una tabla existente, permitiendo indicar el tipo de dato y un valor predeterminado que se asignará a todos los registros de la columna existente con base en una fórmula de transformación, como las que se describen en la sección 2.9.1.

En el cuadro 3.19 se enlistan los atributos que definen a la clase ProcesadorTrans- formar.

Cuadro 3.19 Atributos de la Clase ProcesadorTransformar Atributo Tipo Descripción Descripción de la instancia de la clase Procesador- nombre String Transformar tablaEntrada String Nombre de la tabla con la columna a transformar columnaEntrada String Nombre de la columna a transformar tipoDato String Tipo de dato de la columna formulaTransformar String Fórmula para transformación

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorTransformar:

186 3. IMPLEMENTACIÓN

El atributo tablaEntrada de tipo String, es el nombre de la tabla existente que con- tendrá la columna a la que se aplicará el proceso de transformación:

Movimientos

El atributo columnaEntrada de tipo String, es el nombre de la columna que será transformada en tablaEntrada:

Fecha

El atributo tipoDato de tipo String, es el tipo de dato para los valores contenidos en columnaEntrada:

String

El atributo formulaTransformar de tipo String, es la fórmula que determinará el valor de la transformación, y está basada en las fórmulas de transformación descritas en la sección 2.9.1.

{[Fecha], yyyy-MM-dd}

La fórmula que se utiliza obtiene cada uno de los valores en la columna Fecha y los transforma asignándoles un formato diferente de fecha: yyyy-MM-dd:

El nombre de la columna se encierra entre corchetes para indicar que los valores a transformar serán los que correspondan a cada renglón en la tabla: [Fecha].

En el caso de las columnas de tipo fecha, los formatos se asignan después del carácter ',', y utilizan "yyyy" para el año, "MM" para el mes, y "dd" para el día.

Figura 3.18 Ejemplo de la clase ProcesadorTransformar

Movimientos Movimientos Fecha Importe Fecha Importe 21/04/2016 1750.00 2016-04-21 1750.00 22/04/2016 -520.50 2016-04-22 -520.50 23/04/2016 280.00 2016-04-23 280.00 23/04/2016 -127.20 → 2016-04-23 -127.20 23/04/2016 -300.00 2016-04-23 -300.00 24/04/2016 695.00 2016-04-24 695.00 24/04/2016 -500.00 2016-04-24 -500.00 24/04/2016 -247.30 2016-04-24 -247.30 25/04/2016 1680.00 2016-04-25 1680.00 25/04/2016 -300.00 2016-04-25 -300.00 3.2. PROCESADORES DE DATOS 187

El resultado obtenido por cada renglón de la tabla será transformado dentro de la misma columna Fecha.

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorTransformar es el que se muestra en la figura 3.18, donde los datos de entrada al proceso provienen de la tabla Movimientos conteniendo las columnas: Fecha e Importe con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se actualiza la tabla Movimientos conteniendo la transformación de la columna Fecha, con el nuevo formato.

La estructura de configuración XML para una instancia de la clase ProcesadorTrans- formar se muestra en la configuración C.35.

Un ejemplo completo de implementación para una instancia de la clase Procesador- Transformar se muestra en la configuración C.36. 188 3. IMPLEMENTACIÓN

3.2.15. Procesador Unir

Para realizar el procesamiento mencionado, basado en una unión de datos, se utiliza la clase ProcesadorUnir representada en el diagrama 3.21.

Diagrama 3.21 Clase ProcesadorUnir

El procesamiento efectúa una unión entre dos tablas, basada en las columnas llave de cada tabla y cuyos valores servirán de referencia para que, en caso de presentar igualdad entre sí, se unirán en un mismo registro combinando las columnas de ambas tablas. También es posible indicar si se deben conservar todos los registros de la primera tabla aún cuando no hubiera coincidencias entre las columnas llave contra la segunda tabla.

En el cuadro 3.20 se enlistan los atributos que definen a la clase ProcesadorUnir.

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase ProcesadorUnir:

El atributo tablaEntradaPrimera de tipo String, es el nombre de la primera tabla existente que contiene los datos a unir y que servirá como base para la unión:

Detalles 3.2. PROCESADORES DE DATOS 189

Cuadro 3.20 Atributos de la Clase ProcesadorUnir Atributo Tipo Descripción Descripción de la instancia de la clase Pro- nombre String cesadorUnir tablaEntradaPrimera String Nombre de la primera tabla de entrada tablaEntradaSegunda String Nombre de la segunda tabla de entrada tablaSalida String Nombre de la tabla de salida columnaLlavePrimera String Nombre de la primera columna llave columnaLlaveSegunda String Nombre de la segunda columna llave columnaLlaveSalida String Nombre de la columna llave de salida columnasPrimera List Lista de columnas para unir columnasSegunda List Lista de columnas para totalizar combinacionExterna boolean Indicador de combinación externa

El atributo tablaEntradaSegunda de tipo String, es el nombre de la segunda tabla existente que contiene los datos a unir:

Importes

El atributo tablaSalida de tipo String, es el nombre de la tabla que contendrá la unión de los registros de tablaEntradaPrimera y tablaEntradaSegunda:

Movimientos

El atributo columnaLlavePrimera de tipo String, es el nombre de la columna en tablaEntradaPrimera que contiene los valores llave cuyas coincidencias permitirán la unión:

Número

El atributo columnaLlaveSegunda de tipo String, es el nombre de la columna en tablaEntradaSegunda que contiene los valores llave cuyas coincidencias permitirán la unión:

Folio

El atributo columnaLlaveSalida de tipo String, es el nombre de la columna en ta- blaSalida que contendrá los valores llave:

ID

El atributo columnasPrimera de tipo List es una lista con los nombres de las columnas de tablaEntradaPrimera que serán añadidas a tablaSalida: 190 3. IMPLEMENTACIÓN

Fecha Concepto

El atributo columnasSegunda de tipo List es una lista con los nombres de las columnas de tablaEntradaSegunda que serán añadidas a tablaSalida:

Importe

Figura 3.19 Ejemplo de la clase ProcesadorUnir

Detalles Importes Número Fecha Concepto ID Importe A1200301 21/04/2016 Transferencia Interbancaria A1200301 1750.00 A1200302 22/04/2016 Retiro en Ventanilla A1200302 -520.50 A1200303 23/04/2016 Depósito en Efectivo A1200303 280.00 A1200304 23/04/2016 Compra en Comercio A1200304 -127.20 A1200305 23/04/2016 Retiro en Cajero Automático A1200305 -300.00 A1200306 24/04/2016 Depósito en Efectivo A1200306 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor A1200307 -500.00 A1200308 24/04/2016 Comercio S.A. A1200308 -247.30 A1200309 25/04/2016 Retiro en Cajero Automático A1200309 -300.00 A1200310 25/04/2016 Transferencia Interbancaria A1200310 1680.00 ↓

Movimientos Folio Fecha Concepto Importe A1200301 21/04/2016 Transferencia Interbancaria 1750.00 A1200302 22/04/2016 Retiro en Ventanilla -520.50 A1200303 23/04/2016 Depósito en Efectivo 280.00 A1200304 23/04/2016 Compra en Comercio -127.20 A1200305 23/04/2016 Retiro en Cajero Automático -300.00 A1200306 24/04/2016 Depósito en Efectivo 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor -500.00 A1200308 24/04/2016 Comercio S.A. -247.30 A1200309 25/04/2016 Retiro en Cajero Automático -300.00 A1200310 25/04/2016 Transferencia Interbancaria 1680.00 3.2. PROCESADORES DE DATOS 191

El atributo combinacionExterna de tipo boolean, indica si se deben conservar todos los registros de tablaEntradaPrimera, aún si no hubiera coincidencias con los valores llave de tablaEntradaSegunda:

true

Un ejemplo del tipo de procesamiento de datos que pueden implementarse con la clase ProcesadorUnir es el que se muestra en la figura 3.19, donde los datos de entrada al proceso provienen de las tablas Detalles e Importes, la primera conteniendo una columna Número y la segunda una columna ID, ambas con valores llave. La primera tabla contiene, además, dos columnas de datos: Fecha y Concepto; y la segunda tabla contiene una columna adicional de datos: Importe. Ambas tablas con datos de ejemplo que hacen referencia a Movimientos Bancarios.

Luego de efectuarse el procesamiento, se genera la tabla Movimientos conteniendo el resultado de la unión de la totalidad de las columnas de datos de cada una de las tablas de entrada.

La estructura de configuración XML para una instancia de la clase ProcesadorUnir se muestra en la configuración C.37.

Un ejemplo completo de implementación para una instancia de la clase ProcesadorUnir se muestra en la configuración C.38. 192 3. IMPLEMENTACIÓN

3.3. Publicadores de Datos

El modelo de objetos para los publicadores de datos parte de una interface llamada Publicador, mostrada en el diagrama 3.22.

Diagrama 3.22 Interface Publicador

Aquí se aplica el principio de la herencia (sección 1.7.4), pues los publicadores tienen que implementar la operación publicarDatos() (cuyo parámetro tablas es una lista de objetos de tipo Tabla que contiene los datos que enviará cada publicador) de la interface Publicador, heredando así el comportamiento para publicar los datos.

Y también se aplica el principio del polimorfismo (sección 1.7.2), pues cada uno de los tres publicadores del diagrama 3.22 (PublicadorCsv, PublicadorTxt y PublicadorSql) tiene propiedades diferentes, según las necesidades de cada publicador. 3.3. PUBLICADORES DE DATOS 193

3.3.1. Publicador CSV

Para realizar la publicación de una estructura de datos basada en un archivo de tex- to separado por comas (CSV), se utiliza la clase PublicadorCsv representada en el diagrama 3.23.

Diagrama 3.23 Clase PublicadorCsv

En el cuadro 3.21 se enlistan los atributos que definen a la clase PublicadorCsv.

Cuadro 3.21 Atributos de la Clase PublicadorCsv Atributo Tipo Descripción Descripción de la instancia de la clase Publica- nombre String dorCsv nombreTabla String Nombre exacto de la instancia de la clase Tabla rutaArchivo String Ubicación del archivo CSV caracterSeparador char Carácter para separación de columnas de datos caracterComillas char Carácter para generar valores de cadenas caracterEscape char Carácter para generar caracteres de escape caracterFinDeLinea String Carácter para generar el fin de línea incluirEncabezado boolean Indica si incluir líneas indicadas como encabezado

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase PublicadorCsv:

El atributo nombreTabla de tipo String, es el nombre exacto de la instancia de la clase 194 3. IMPLEMENTACIÓN

Tabla que contiene los datos que serán publicados:

Flujos

El atributo rutaArchivo de tipo String es la ubicación del archivo mediante la ruta de acceso y el nombre completo del archivo CSV:

data/flujos.csv

El atributo caracterSeparador de tipo char es el carácter que deberá utilizar el publi- cador CSV para llevar a cabo la separación de las columnas de datos:

,

El atributo caracterComillas de tipo char es el carácter que deberá utilizar el publi- cador CSV para generar los valores de cadenas:

"

El atributo caracterEscape de tipo char es el carácter que deberá utilizar el publicador CSV para generar los caracteres de escape, como tabuladores (\t) o saltos de línea (\n):

\

El atributo caracterFinDeLinea de tipo String es el carácter que deberá utilizar el publicador CSV para generar el fin de cada línea publicada:

\n

El atributo incluirEncabezado de tipo boolean indica si deberá generarse una línea adicional al inicio del archivo publicado, con los nombres de cada una de las columnas:

true

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la clase PublicadorCsv es el que se muestra en la figura 3.20, y corresponde a un archivo de texto CSV (Comma-Separated Values). Contiene cuatro columnas de datos separadas por

Figura 3.20 Ejemplo de la clase LectorCsv

FLOW_DATE,FLOW_DEPO,FLOW_WITH,FLOW_BALN 21/04/2016,1750.00,0.00,1750.00 22/04/2016,0.00,-520.50,1229.50 23/04/2016,280.00,-427.20,1082.30 24/04/2016,695.00,-747.30,1030.00 25/04/2016,1680.00,-300.00,2410.00 3.3. PUBLICADORES DE DATOS 195 el carácter ',': FLOW_DATE (Fecha), FLOW_DEPO (Depósitos), FLOW_WITH (Retiros) y FLOW_BALN (Saldo); y datos de ejemplo que hacen referencia a un Reporte de Flujos Bancarios.

La estructura de configuración XML para una instancia de la clase PublicadorCsv se muestra en la configuración C.39.

Un ejemplo completo de implementación para una instancia de la clase PublicadorCsv se muestra en la configuración C.40. 196 3. IMPLEMENTACIÓN

3.3.2. Publicador SQL

Para realizar la publicación de una estructura de datos basada en una actualización SQL a base de datos, se utiliza la clase PublicadorSql representada en el diagrama 3.24.

Diagrama 3.24 Clase PublicadorSql

En el cuadro 3.22 se enlistan los atributos que definen a la clase PublicadorSql.

Cuadro 3.22 Atributos de la Clase PublicadorSql Atributo Tipo Descripción nombre String Descripción de la instancia de la clase PublicadorSql Controlador específico del manejador de base de da- cadenaControlador String tos cadenaConexion String Cadena de conexión al servidor de base de datos claveUsuario String Clave del usuario que se conectará a la base de datos Contraseña de acceso para conectarse a la base de claveAcceso String datos Cadena utilizada para efectuar la publicación a la ba- cadenaConsulta String se de datos

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase PublicadorSql:

El atributo cadenaControlador de tipo String es el controlador específico del maneja- dor de base de datos, que en este caso es MySQL: 3.3. PUBLICADORES DE DATOS 197

com.mysql.jdbc.Driver

El atributo cadenaConexion de tipo String es la cadena de conexión al servidor de la base de datos:

jdbc:mysql://localhost/banco

El atributo claveUsuario de tipo String es la clave del usuario que se conectará a la base de datos:

root

El atributo claveAcceso de tipo String es la contraseña de acceso para conectarse a la base de datos:

root

El atributo cadenaConsulta de tipo String es la plantilla de consulta SQL con la que se actualizará el contenido de la base de datos:

INSERT INTO FLOW (FLOW_DATE, FLOW_DEPO, FLOW_WITH, FLOW_BALN) VALUES (' %FLOW_DATE %', %FLOW_DEPO %, %FLOW_WITH %, %FLOW_BALN %);

Los valores entre los caracteres ' %' corresponden con el nombre exacto de la columna en la tabla de datos, y serán reemplazados en una serie de consultas SQL de actualización a la base de datos de la siguiente forma:

INSERT INTO FLOW (FLOW_DATE, FLOW_DEPO, FLOW_WITH, FLOW_BALN) VALUES ('2016-04-21', 1750.00, 0.00, 1750.00);

INSERT INTO FLOW (FLOW_DATE, FLOW_DEPO, FLOW_WITH, FLOW_BALN) VALUES ('2016-04-22', 0.00, -520.50, 1229.50);

INSERT INTO FLOW (FLOW_DATE, FLOW_DEPO, FLOW_WITH, FLOW_BALN) VALUES ('2016-04-23', 280.00, -427.20, 1082.30);

INSERT INTO FLOW (FLOW_DATE, FLOW_DEPO, FLOW_WITH, FLOW_BALN) VALUES ('2016-04-24', 695.00, -747.30, 1030.00); 198 3. IMPLEMENTACIÓN

INSERT INTO FLOW (FLOW_DATE, FLOW_DEPO, FLOW_WITH, FLOW_BALN) VALUES ('2016-04-25', 1680.00, -300.00, 2410.00);

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la clase PublicadorSql es el que se muestra en la figura 3.21, y corresponde al resultado de una actualización SQL a base de datos. Contiene cuatro columnas de datos: FLOW_DATE (Fecha), FLOW_DEPO (Depósitos), FLOW_WITH (Retiros) y FLOW_BALN (Saldo); y datos de ejemplo que hacen referencia a un Reporte de Flujos Bancarios.

Figura 3.21 Ejemplo de la clase LectorSql

Reporte de Flujos Bancarios FLOW_DATE FLOW_DEPO FLOW_WITH FLOW_BALN 21/04/2016 1750.00 0.00 1750.00 22/04/2016 0.00 -520.50 1229.50 23/04/2016 280.00 -427.20 1082.30 24/04/2016 695.00 -747.30 1030.00 25/04/2016 1680.00 -300.00 2410.00

La estructura de configuración XML para una instancia de la clase PublicadorSql se muestra en la configuración C.43.

Un ejemplo completo de implementación para una instancia de la clase PublicadorSql se muestra en la configuración C.44. 3.3. PUBLICADORES DE DATOS 199

3.3.3. Publicador TXT

Para realizar la publicación de una estructura de datos basada en un archivo de texto por posición (TXT), se utiliza la clase PublicadorTxt representada en el diagrama 3.25.

Diagrama 3.25 Clase PublicadorTxt

En el cuadro 3.23 se enlistan los atributos que definen a la clase PublicadorTxt.

Cuadro 3.23 Atributos de la Clase PublicadorTxt Atributo Tipo Descripción nombre String Descripción de la instancia de clase PublicadorTxt nombreTabla String Nombre exacto de la instancia de la clase Tabla rutaArchivo String Ubicación del archivo TXT incluirEncabezado boolean Indica si incluir una línea de encabezado

El atributo nombre de tipo String es el nombre descriptivo con el que se identificará a una instancia específica de la clase PublicadorTxt:

El atributo nombreTabla de tipo String, es el nombre exacto de la instancia de la clase Tabla que contiene los datos que serán publicados:

Flujos

El atributo rutaArchivo de tipo String es la ubicación del archivo mediante la ruta de acceso y el nombre completo del archivo TXT:

data/flujos.txt 200 3. IMPLEMENTACIÓN

El atributo incluirEncabezado de tipo boolean indica si las líneas indicadas como encabezado deberán incluirse en el procesamiento:

true

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la cla- se PublicadorTxt es el que se muestra en la figura 3.3, y corresponde a un archivo de texto por posición (TXT). Contiene cuatro columnas de datos delimitadas por posi- ción: FLOW_DATE (Fecha), FLOW_DEPO (Depósitos), FLOW_WITH (Retiros) y FLOW_BALN (Saldo); y datos de ejemplo que hacen referencia a un Reporte de Flujos Bancarios.

Figura 3.22 Ejemplo de la clase LectorTxt

0·········1·········2·········3········· 0123456789012345678901234567890123456789 FLOW_DATE·FLOW_DEPO·FLOW_WITH·FLOW_BALN· 21/04/2016·000175000·000000000·000175000 22/04/2016·000000000-000052050·000122950 23/04/2016·000028000-000042720·000108230 24/04/2016·000069500-000074730·000103000 25/04/2016·000168000-000030000·000241000

La estructura de configuración XML para una instancia de la clase PublicadorTxt se muestra en la configuración C.41.

Un ejemplo completo de implementación para una instancia de la clase PublicadorTxt se muestra en la configuración C.42. 3.3. PUBLICADORES DE DATOS 201

3.3.4. Publicador XML

Para realizar la publicación de una estructura de datos como la anterior, basada en un archivo de texto con formato XML, se utiliza la clase PublicadorXml representada en el diagrama 3.26.

Diagrama 3.26 Clase PublicadorXml

En el cuadro 3.24 se enlistan los atributos que definen a la clase PublicadorXml.

Cuadro 3.24 Atributos de la Clase PublicadorXml Atributo Tipo Descripción nombre String Descripción de la instancia de la clase PublicadorXml rutaArchivo String Ubicación del archivo XML

El atributo nombre de tipo String, es el nombre descriptivo con el que se identificará a una instancia específica de la clase PublicadorXml:

El atributo rutaArchivo de tipo String es la ubicación del archivo mediante la ruta de acceso y el nombre completo del archivo XML:

data/flujos.xml

Un ejemplo del tipo de estructuras de datos que pueden implementarse con la clase PublicadorXml es el que se muestra en la figura 3.23, y corresponde a un archivo de texto con formato XML (eXtensible Markup Language). Contiene cuatro columnas de 202 3. IMPLEMENTACIÓN

datos: flow_date (Fecha), flow_depo (Depósitos), flow_with (Retiros) y flow_baln (Saldo); y datos de ejemplo que hacen referencia a un Reporte de Flujos Bancarios.

Figura 3.23 Ejemplo de la clase LectorXml

21/04/2016 1750.00 0.00 1750.00 22/04/2016 0.00 -520.50 1229.50 23/04/2016 280.00 -427.20 1082.30 24/04/2016 695.00 -747.30 1030.00 25/04/2016 1680.00 -300.00 2410.00

La estructura de configuración XML para una instancia de la clase PublicadorXml se muestra en la configuración C.45.

Un ejemplo completo de implementación para una instancia de la clase PublicadorXml se muestra en la configuración C.46. 3.4. INTERFAZ DE USUARIO 203

3.4. Interfaz de Usuario

3.4.1. Línea de Comandos

La ejecución de los procesos se efectuará mediante la línea de comandos, con pa- rámetros opcionales para, por ejemplo, indicar la ruta del archivo de configuración (-config), y valores para las fechas de procesamiento (-FechaHoy / -FechaAyer).

Conforme se ejecuta el procesamiento de cada solución y de sus procesos internos, se mostrará el resultado de cada uno.

>EPD -config:cfg/EMD.xml -FechaHoy:2015-07-16 -FechaAyer:2015-07-15

* EPD: Estructura para el Procesamiento de Datos *

[Procesando Parámetros] - FechaHoy: 16-Jul-2015 - FechaAyer: 15-Jul-2015

[Procesando Soluciones]

[Actualización de Datos de Mercado] - LectorTxt::leerDatos() - LectorBaseDatos::leerDatos() - ProcesadorFiltrado::procesarDatos() - ProcesadorFusion::procesarDatos() - ProcesadorConciliacion::procesarDatos() - PublicadorXml::publicarDatos()

[Conciliación Bancaria] - LectorCsv::leerDatos() - LectorBaseDatos::leerDatos() - ProcesadorFiltrado::procesarDatos() - ProcesadorEquivalencia::procesarDatos() - ProcesadorConciliacion::procesarDatos() - PublicadorHojaCalculo::publicarDatos() 204 3. IMPLEMENTACIÓN

[Envío de Reportes Regulatorios] - LectorCsv::leerDatos() - LectorBaseDatos::leerDatos() - ProcesadorFiltrado::procesarDatos() - ProcesadorTransformacion::procesarDatos() - ProcesadorAgrupacion::procesarDatos() - PublicadorTxt::publicarDatos() - PublicadorCsv::publicarDatos() - PublicadorBaseDatos::publicarDatos()

[Proceso Finalizado Exitosamente] 3.5. Casos de Uso

3.5.1. Caso de Uso Migración

La migración de datos de una fuente origen hacia un repositorio destino es, quizá, el caso de uso más común en cualquier entidad ya sea pública o privada, donde por lo general ocurre que coexistan diferentes sistemas con diferentes formatos para la entrada y la salida de datos, dificultando así las posibilidades de una intercomunicación directa entre ellos.

Figura 3.24 Ejemplo del Caso de Uso Migración

0·········1·········2·········3·········4·········5···· 0123456789012345678901234567890123456789012345678901234 Folio···Fecha·····Concepto···················Importe··· A120030222/04/2016Retiro·en·Ventanilla·······000052050 A120030724/04/2016Pago·SPEI·a·Proveedor······000050000 A120030523/04/2016Retiro·en·Cajero·Automático000030000 A120030925/04/2016Retiro·en·Cajero·Automático000030000 A120030824/04/2016Comercio·S.A.··············000024730 A120030423/04/2016Compra·en·Comercio·········000012720 A120030323/04/2016Depósito·en·Efectivo········000028000 A120030624/04/2016Depósito·en·Efectivo········000069500 A120031025/04/2016Transferencia·Interbancaria·000168000 A120030121/04/2016Transferencia·Interbancaria·000175000 ↓

Movimientos Folio Fecha Concepto Importe A1200301 21/04/2016 Transferencia Interbancaria 1750.00 A1200302 22/04/2016 Retiro en Ventanilla -520.50 A1200303 23/04/2016 Depósito en Efectivo 280.00 A1200304 23/04/2016 Compra en Comercio -127.20 A1200305 23/04/2016 Retiro en Cajero Automático -300.00 A1200306 24/04/2016 Depósito en Efectivo 695.00 A1200307 24/04/2016 Pago SPEI a Proveedor -500.00 A1200308 24/04/2016 Comercio S.A. -247.30 A1200309 25/04/2016 Retiro en Cajero Automático -300.00 A1200310 25/04/2016 Transferencia Interbancaria 1680.00

205 206 3. IMPLEMENTACIÓN

Al establecer un proceso básico de migración de datos, se logran salvar las barreras del formato y se hace posible la transferencia de datos entre sistemas.

El ejemplo del caso de uso “Migración” es el que se muestra en la figura 3.24, e inicia con una fuente de datos que corresponde a un archivo de texto por posición (TXT). Contiene cuatro columnas de datos delimitadas por posición: 8 caracteres para el Folio, 10 caracteres para la Fecha, 27 caracteres para el Concepto y 10 caracteres para el Importe; con datos de ejemplo que hacen referencia a Movimientos Bancarios.

El resultado de la salida del caso de uso es una actualización a una tabla de base de datos. Contiene también cuatro columnas de datos conteniendo los datos migrados de la fuente original: Folio, Fecha, Concepto e Importe.

La configuración 3.1 muestra la forma de implementar el caso de uso “Migración” en formato XML, donde primero se implementan los parámetros de ejecución mediante una lista de instancias de la clase Parametro (secciones 2.5.1 y 2.7.3), con los siguientes pa- rámetros configurados: fechaHoy, fechaAyer, fechaAyerHabil, rutaArchivoTxt, sql- CadenaControlador, sqlCadenaConexion, sqlClaveUsuario, sqlClaveAcceso y sqlCa- denaConsulta.

Posteriormente se implementa la clase LectorTxt (sección 3.1.3), que será la que ob- tendrá los datos desde la fuente origen de un archivo de texto por posición.

Los datos vienen ordenados desde su origen en base a los valores de la columna Importe (de menor a mayor), pero en el repositorio destino se requiere que estén ordenados por los valores de la columna Folio (de menor a mayor), y por ello se implementa la clase ProcesadorOrdenar (sección 3.2.13).

Finalmente se implementa la clase PublicadorSql (sección 3.3.2) para insertar los valores en el repositorio final, es decir, la tabla Movimientos de la base de datos.

Configuración 3.1 Caso de Uso Migración

{#fechaHoy# - 1, yyyyMMdd} {#fechaHoy# - 1, yyyyMMdd} MEX,USA 3.5. CASOS DE USO 207

\\servidor\banco$\{#fechaAyer#, yyyy-MM-dd}\movimientos.txt com.mysql.jdbc.Driver jdbc:mysql://localhost/banco root root INSERT INTO Movimientos (Folio, Fecha, Concepto, Importe) VALUES (' %Folio %', %Fecha %, %Concepto %, %Importe %); #rutaArchivoTxt# 1 false false Folio 0 8 String Fecha 8 208 3. IMPLEMENTACIÓN

10 Date dd/MM/yyyy Concepto 18 27 String Importe 45 10 double 2 MovimientosTxt Folio #sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# #sqlCadenaConsulta# 3.5. CASOS DE USO 209

3.5.2. Caso de Uso Reporte

Otro caso de uso que también suele ser muy común es el referente a la emisión de reportes sumarizados donde se presente un resumen de los valores totales provenientes de fuentes de datos a detalle.

Figura 3.25 Ejemplo del Caso de Uso Reporte

Movimientos Folio Fecha Depositos Retiros Total A1200301 21/04/2016 1750.00 0.00 1750.00 A1200302 22/04/2016 0.00 -520.50 -520.50 A1200303 23/04/2016 280.00 0.00 280.00 A1200304 23/04/2016 0.00 -127.20 -127.20 A1200305 23/04/2016 0.00 -300.00 -300.00 A1200306 24/04/2016 695.00 0.00 695.00 A1200307 24/04/2016 0.00 -500.00 -500.00 A1200308 24/04/2016 0.00 -247.30 -247.30 A1200309 25/04/2016 0.00 -300.00 -300.00 A1200310 25/04/2016 1680.00 0.00 1680.00 ↓

Reporte Fecha Depositos Retiros Total 21/04/2016 1750.00 0.00 1750.00 22/04/2016 0.00 -520.50 -520.50 23/04/2016 280.00 -427.20 -147.20 24/04/2016 695.00 -747.30 -52.30 25/04/2016 1680.00 -300.00 1380.00

El ejemplo del caso de uso “Reporte” es el que se muestra en la figura 3.25, e inicia con una fuente de datos que corresponde a una consulta a base de datos. Contiene cinco columnas de datos conteniendo los datos a detalle obtenidos de la fuente original: Folio, Fecha, Depositos, Retiros y Total; con datos de ejemplo que hacen referencia a Movimientos Bancarios.

El resultado de la salida del caso de uso es una actualización a una tabla de base de datos. Contiene cuatro columnas de datos conteniendo los datos agrupados de la fuente original: Fecha, Depositos, Retiros y Total. 210 3. IMPLEMENTACIÓN

La configuración 3.2 muestra la forma de implementar el caso de uso “Reporte” en for- mato XML, donde primero se implementan los parámetros de ejecución mediante una lista de instancias de la clase Parametro (secciones 2.5.1 y 2.7.3), con los siguientes pa- rámetros configurados: fechaHoy, fechaAyer, fechaAyerHabil, sqlCadenaControlador, sqlCadenaConexion, sqlClaveUsuario, sqlClaveAcceso, sqlCadenaConsultaLector y sqlCadenaConsultaPublicador.

Posteriormente se implementa la clase LectorSql (sección 3.1.2), que será la que ob- tendrá los datos desde la fuente origen de una consulta SQL a base de datos.

El requerimiento principal del caso de uso “Reporte” es que se totalicen los valores provenientes de las columnas Depositos, Retiros y Total, y por ello se implementa la clase ProcesadorAgrupar (sección 3.2.1).

Finalmente se implementa la clase PublicadorSql (sección 3.3.2) para insertar los valores en el repositorio final, es decir, la tabla Reporte de la base de datos.

Configuración 3.2 Caso de Uso Reporte

{#fechaHoy# - 1, yyyyMMdd} {#fechaHoy# - 1, yyyyMMdd} MEX,USA com.mysql.jdbc.Driver jdbc:mysql://localhost/banco root root 3.5. CASOS DE USO 211

SELECT Folio, Fecha, Depositos, Retiros, Total FROM Movimientos WHERE Fecha >= '{#fechaAyerHabil#, dd-MM-yyyy}'; INSERT INTO Reporte (Fecha, Depositos, Retiros, Total) VALUES (' %Fecha %', %Depositos %, %Retiros %, %Total %); #sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# #sqlCadenaConsultaLector# Movimientos Reporte Fecha Depositos Retiros Total #sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# 212 3. IMPLEMENTACIÓN

#sqlCadenaConsultaPublicador# 3.5. CASOS DE USO 213

3.5.3. Caso de Uso Conciliación

El principal caso de uso, y que fue el que motivó a la elaboración del presente trabajo, es una conciliación entre dos orígenes de datos, dando como resultado los registros conciliados, los que tuvieron diferencias, y los no conciliados.

El ejemplo del caso de uso “Conciliación” es el que se muestra en la figura 3.26, e inicia con dos fuente de datos. La primera corresponde a un archivo con formato CSV. Contiene tres columnas de datos conteniendo los datos a detalle obtenidos de la fuente original: Numero, Fecha e Importe; con datos de ejemplo que hacen referencia a Movimientos Bancarios.

La segunda fuente de datos es una consulta a base de datos. Contiene cinco columnas de datos conteniendo los datos a detalle obtenidos de la fuente original: TR_ID_K, TR_DATE, TR_CASH y TR_TYPE; con datos de ejemplo que también hacen referencia a Movimientos Bancarios.

El resultado de la salida del caso de uso son varias actualizaciones a tablas de base de datos.

La primera tabla es Conciliados, que agrupa aquellos registros de ambas fuentes de datos cuyo campo llave (o conjunto de campos llave) tuvieron una coincidencia com- pleta entre sí; y que no presentaron diferencias en aquellos campos señalados como de comparación.

La segunda tabla es Con_Diferencias, que agrupa aquellos registros de ambas fuentes de datos cuyo campo llave (o conjunto de campos llave) tuvieron una coincidencia completa entre sí; pero que sí presentaron diferencias en aquellos campos señalados como de comparación.

Además se genera una tercera tabla: Diferencias, que contiene una columna de ti- po boolean con el nombre de cada columna comparada, y con un valor de true si existieron diferencias entre los valores de ambas fuentes de datos al momento de com- pararlas, y en caso de que no hubiesen sido encontradas diferencias, se le asigna el valor de false.

Finalmente la cuarta tabla es No_Conciliados, que agrupa aquellos registros de ambas fuentes de datos cuyo campo llave (o conjunto de campos llave) no tuvieron una sola coincidencia entre sí. 214 3. IMPLEMENTACIÓN

Figura 3.26 Ejemplo del Caso de Uso Conciliación

TRAN movimientos.csv TR_ID_K TR_DATE TR_CASH TR_TYPE Numero,Fecha,Importe A1200302 22/04/2016 -520.50 Cargo A1200301,21/04/2016,1750.00 A1200303 23/04/2016 280.00 Abono A1200302,22/04/2016,-520.50 A1200304 23/04/2016 -127.20 Cargo A1200303,22/04/2016,280.00 A1200305 23/04/2016 -300.00 Cargo A1200304,23/04/2016,-127.20 A1200305,23/04/2016,-300.00 A1200306 24/04/2016 695.00 Abono A1200306,24/04/2016,695.50 A1200307 24/04/2016 -500.00 Cargo A1200307,24/04/2016,-500.00 A1200308 24/04/2016 -247.30 Cargo A1200308,24/04/2016,-247.00 A1200309 25/04/2016 -300.00 Cargo A1200310 25/04/2016 1680.00 Abono ↓

Conciliados Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200302 22/04/2016 -520.50 22/04/2016 -520.50 Cargo A1200304 23/04/2016 -127.20 23/04/2016 -127.20 Cargo A1200305 23/04/2016 -300.00 23/04/2016 -300.00 Cargo A1200307 24/04/2016 -500.00 24/04/2016 -500.00 Cargo

Con_Diferencias Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200303 23/04/2016 280.00 22/04/2016 280.00 Abono A1200306 24/04/2016 695.50 24/04/2016 695.00 Abono A1200308 24/04/2016 -247.00 24/04/2016 -247.30 Cargo

Diferencias Folio Fecha Importe A1200303 true false A1200306 false true A1200308 false true

No_Conciliados Folio t1_Fecha t1_Importe t2_Fecha t2_Importe t2_Tipo A1200301 21/04/2016 1750.00 A1200309 25/04/2016 -300.00 Cargo A1200310 25/04/2016 1680.00 Abono 3.5. CASOS DE USO 215

La configuración 3.2 muestra la forma de implementar el caso de uso “Reporte” en for- mato XML, donde primero se implementan los parámetros de ejecución mediante una lista de instancias de la clase Parametro (secciones 2.5.1 y 2.7.3), con los siguientes parámetros configurados: fechaHoy, fechaAyer, fechaAyerHabil, sqlCadenaContro- lador, sqlCadenaConexion, sqlClaveUsuario, sqlClaveAcceso, sqlCadenaConsulta- Lector, sqlCadenaConsultaConciliados, sqlCadenaConsultaConDiferencias, sqlCa- denaConsultaDiferencias y sqlCadenaConsultaNoConciliados.

Posteriormente se implementa la clase ProcesadorConciliar (sección 3.2.5), que será la que procesará las fuentes de datos y generará las tablas de salida.

Finalmente se implementa la clase PublicadorSql (sección 3.3.2) para insertar los valores en los repositorios finales, es decir, las tablas Conciliados, Con_Diferencias, Diferencias y No_Conciliados de la base de datos.

Configuración 3.3 Caso de Uso Conciliación

{#fechaHoy# - 1, yyyyMMdd} {#fechaHoy# - 1, yyyyMMdd} MEX,USA \\servidor\banco$\{#fechaAyer#, yyyy-MM-dd}\movimientos.csv com.mysql.jdbc.Driver jdbc:mysql://localhost/banco root root 216 3. IMPLEMENTACIÓN

SELECT TR_ID_K AS Folio, TR_DATE AS Fecha, TR_CASH AS Importe TR_TYPE AS Tipo, FROM TRAN WHERE TRAN_DATE >= '{#fechaAyerHabil#, dd-MM-yyyy}'; INSERT INTO Conciliados (Folio, t1_Fecha, t1_Importe, t2_Fecha, t2_Importe, t2_Tipo) VALUES (' %Folio %', ' %t1_Fecha %', %t1_Importe %, ' %t2_Fecha %', %t2_Importe %, ' %t2_Tipo %'); INSERT INTO Con_Diferencias (Folio, t1_Fecha, t1_Importe, t2_Fecha, t2_Importe, t2_Tipo) VALUES (' %Folio %', ' %t1_Fecha %', %t1_Importe %, ' %t2_Fecha %', %t2_Importe %, ' %t2_Tipo %'); INSERT INTO Diferencias (Folio, Fecha, Importe) VALUES (' %Folio %', ' %Fecha %', ' %Importe %'); INSERT INTO No_Conciliados (Folio, t1_Fecha, t1_Importe, t2_Fecha, t2_Importe, t2_Tipo) VALUES (' %Folio %', ' %t1_Fecha %', %t1_Importe %, ' %t2_Fecha %', %t2_Importe %, ' %t2_Tipo %'); 3.5. CASOS DE USO 217

#rutaArchivoCsv# , " \ 1 false true false false false Numero 1 String Fecha 2 Date dd/MM/yyyy Importe 3 double #sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# #sqlCadenaConsultaLector# 218 3. IMPLEMENTACIÓN

MovimientosCsv TRAN Conciliados No_Conciliados t1_ t2_ Folio Numero TR_ID_K Fecha Fecha TR_DATE Importe Importe TR_CASH Tipo TR_TYPE Movimientos Reporte Fecha Depositos Retiros Total 3.5. CASOS DE USO 219

#sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# #sqlCadenaConsultaConciliados# #sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# #sqlCadenaConsultaConDiferencias# #sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# #sqlCadenaConsultaDiferencias# #sqlCadenaControlador# #sqlCadenaConexion# #sqlClaveUsuario# #sqlClaveAcceso# #sqlCadenaConsultaNoConciliados# 220 3. IMPLEMENTACIÓN Conclusiones

El desarrollo del presente trabajo ha estado motivado esencialmente por la experiencia obtenida durante más de 19 años en distintas áreas operativas de instituciones finan- cieras como bancos, aseguradoras y administradoras de fondos para el retiro (afores). Durante todo ese tiempo, fui llegando a la conclusión de que todas esas áreas tenían un común denominador, pues en cada una de ellas existía un subconjunto específico de actividades que involucraban procesos diarios de migración, conversión y explotación de datos; provenientes de fuentes cuyo formato era tan diverso como la manera de acceder a ellas.

Por regla general, esas necesidades estaban relacionadas con tareas como validacio- nes, conciliaciones, reportes, entre otras; y siempre habían existido múltiples soluciones a ellas: desde el procesamiento manual, software de terceros, hasta desarrollos a la medida (tanto subcontratados como hechos en casa).

Una problemática en particular ocurría en el contexto de los desarrollos hechos a la medida y estaba relacionada directamente con el código fuente, pues por lo general no existía un consenso estandarizado en cuanto al lenguaje de programación, los estándares de codificación y la metodología para el desarrollo en general.

Fue entonces que logré identificar las principales consecuencias de esa problemática, y que de seguir así, pondrían en riesgo la estabilidad del área, y la continuidad de los procesos diarios:

Código heredado sin documentar

Dificultad para solucionar errores rápidamente por la complejidad de las diferentes aplicaciones

Duplicación del trabajo al hacer diferentes versiones de procedimientos utilitarios comunes

Tiempos de desarrollo lentos, al tener que analizar y diseñar aplicaciones similares desde cero

221 222 CONCLUSIONES

Ello me llevó a afirmar que una estructura estandarizada y configurable para el procesa- miento de datos brindaría los siguientes beneficios para los desarrolladores de diferentes áreas, lo que redundaría en una mayor capacidad de respuesta y una mejor calidad en los entregables informáticos:

Facilidad para trabajar con tecnologías complejas

Agrupamiento de objetos y componentes separados en algo de mayor utilidad

Se obliga al equipo de desarrollo a implementar código de una manera que pro- mueva la codificación consistente, menos errores, y aplicaciones más flexibles

Que cualquiera pueda efectuar fácilmente pruebas y rastreo del código, inclusive código escrito por alguien más

El objetivo de este trabajo consistió en desarrollar una Estructura para el Procesamien- to de Datos (Data Processing Framework) en un lenguaje de programación orientado a objetos, cuya arquitectura se fundamentó en los patrones de diseño, y que su enfoque de desarrollo fuera uno controlado por la configuración.

Para el desarrollo se utilizó el lenguaje de programación Java, aplicando sólo los patro- nes de diseño específicos para optimizar los diferentes casos de uso. La configuración de las aplicaciones estuvo basada en el lenguaje XML, implementando la propiedad de la reflexión de código a fin de crear instancias de objetos en tiempo de ejecución.

La arquitectura básica consideró los siguientes módulos y sus casos de uso:

Módulo para leer los datos desde sus fuentes

Archivos de texto separados por comas (CSV)

Archivos de texto por posición (TXT)

Consultas a bases de datos (SQL)

Archivos de texto con formato XML

Módulo para efectuar procesamiento sobre los datos

Agrupar valores totalizados en base a valores llave

Clonar el tipo de dato y el valor de una columna

Clonar la estructura y el contenido de una tabla

Comparar columnas valor de una tabla previamente conciliada 223

Conciliar diferencias entre valores llave

Dividir columnas de una tabla conservando referencias llave

Eliminar una columna en su totalidad

Eliminar una tabla en su totalidad

Equivaler columnas de datos con valores de equivalencia

Filtrar valores en base a un criterio específico

Fusionar los datos de dos tablas con la misma estructura en una nueva tabla

Insertar una nueva columna especificando su tipo de dato y valor

Ordenar los datos de una tabla en base a un conjunto de columnas valor

Transformar valores en base a criterios de transformación como formato o valor

Unir registros de dos tablas cuya coincidencia ocurra en los valores llave

Módulo para publicar la información ya procesada

Archivos de texto separados por comas (CSV)

Archivos de texto por posición (TXT)

Actualizaciones a bases de datos (SQL)

Archivos de texto con formato XML

Casos de Uso

Migración

Reporte

Conciliación

Dado que la naturaleza de este desarrollo era la de ser un programa de servicio, éste no contó con una interfaz gráfica para un sistema operativo específico. En vez de ello, se desarrolló una interfaz de línea de comandos con manejo de parámetros para conducir la ejecución.

Respecto del módulo de carga de datos, solo se hizo el desarrollo para un manejador específico de base de datos (MySQL), sin embargo, es parte de la visión evolutiva de 224 CONCLUSIONES

la estructura que se pueda ir mejorando con la agregación de funcionalidad al núcleo principal, sin que por ello se vea afectada la operación de implementaciones anteriores.

Es importante hacer mención de que la versión original de la Estructura para el Proce- samiento de Datos fue desarrollada en el lenguaje C#, basado en métodos de Reflexión de Código (Reflection) propios del lenguaje y con una funcionalidad reducida.

Por cuestiones de protección a la propiedad intelectual de la entidad financiera donde se hizo el desarrollo original, la versión del presente trabajo tuvo que ser nuevamente desarrollada desde cero en el lenguaje Java, con un diseño similar, pero extendiendo su alcance a otros tipos adicionales de procesamiento, y lo más importante, sin utilizar los métodos de Reflexión de Código (al ser propios del lenguaje C#), y en vez de ello, utilizando los métodos de Arquitectura Java para Enlazado de XML (JAXB: Java Architecture for XML Binding), como se vio en la sección 2.7.1.

Finalmente, buena parte de la decisión de haber realizado desde cero el desarrollo en el lenguaje Java, es la posibilidad de que también se pudiera ofrecer el código completo de manera abierta para su reutilización y mejora, como un beneficio adicional a la comunidad. A| Anexo: Referencias del Lenguaje

225 226 ANEXO A A.1. LENGUAJE JAVA 227

A.1. Lenguaje Java

A.1.1. Tipos de Datos

Los tipos de datos soportados por Java se muestran en el cuadro A.1 [57] [101]

Cuadro A.1 Tipos de Datos en Java Tipo Definición Valores boolean Booleano de 1 bit true o false

Desde -27 (-128) char Carácter Unicode de 16 bits hasta '\uffff' (65,535)

Desde '\u0000' (0) byte Entero de 8 bits hasta 27-1 (127)

Desde -215 (-32,768) short Entero de 16 bits hasta 215-1 (32,767)

Desde -231 (-2,147,483,648) int Entero de 32 bits hasta 231-1 (2,147,483,647)

Desde -263 (-9,223,372,036,854,775,808) long Entero de 64 bits hasta 263-1 (9,223,372,036,854,775,807)

Desde 2−126 float Flotante de 32 bits hasta (1 - 2−24) x 2128

Desde 2−1,074 double Doble de 64 bits hasta (1 + (1 - 2−52)) x 21,023

Desde el 1 de enero de 1970, Date Fecha y Hora a las 00:00:00 GMT 228 ANEXO A

A.1.2. Operadores

Los tipos de operadores soportados por Java se muestran en el cuadro A.2 [30]

Cuadro A.2 Operadores en Java Tipo Operador Definición Asignación = Operador de asignación simple Operador de suma (utilizado también para + concatenación de cadenas) - Operador de resta Aritméticos * Operador de multiplicación / Operador de división % Operador de residuo Operador unario de más; indica un valor po- + sitivo (sin embargo, los números son positi- vos sin él) Operador unario de menos; hace que una ex- - presión sea negativa Unarios Operador de incremento; incrementa un va- ++ lor en 1 Operador de decremento; decrementa un va-  lor en 1 Operador de complemento lógico; invierte el ! valor de una expresión booleana == Igual que != No igual que > Mayor que Igualdad y Relacionales >= Mayor o igual que < Menor que <= Menor o igual que && AND condicional || OR condicional Condicionales Ternario (abreviatura para instrucción if- ?: then-else) Comparación de Tipos instanceof Compara un objeto con un tipo específico ~ Complemento unario de bits << Desplazamiento a la izquierda con signo >> Desplazamiento a la derecha con signo Desplazamiento de Bits >>> Desplazamiento a la derecha sin signo & AND de bits ^ OR exclusivo de bits | OR inclusivo de bits B| Anexo: Listados de Programas en Len- guaje Java

229 230 ANEXO B B.1. ESTRUCTURAS DE DATOS 231

B.1. Estructuras de Datos

B.1.1. Clase Columna

Programa B.1 Implementación de la clase Columna

public class Columna { private String nombre; private int posicion; private int longitud; private String tipoDato; private String formato; private int decimales;

public String getNombre() { return nombre; } public int getPosicion() { return posicion; } public int getLongitud() { return longitud; } public String getTipoDato() { return tipoDato; } public String getFormato() { return formato; } public int getDecimales() { return decimales; }

public void setNombre(String newNombre) { nombre = newNombre; } public void setPosicion(int newPosicion) { posicion = newPosicion; } public void setLongitud(int newLongitud) { longitud = newLongitud; } public void setTipoDato(String newTipoDato) { tipoDato = newTipoDato; } public void setFormato(String newFormato) { formato = newFormato; } public void setDecimales(int newDecimales) { decimales = newDecimales; }

public Columna() { this("", 0, 0, "", "", 0); } public Columna(String newNombre, int newPosicion, int newLongitud, String newTipoDato, String newFormato, int newDecimales) { setNombre(newNombre); setPosicion(newPosicion); setLongitud(newLongitud); setTipoDato(newTipoDato); setFormato(newFormato); setDecimales(newDecimales); } } 232 ANEXO B

B.1.2. Clase Tabla

Programa B.2 Implementación de la clase Tabla

public class Tabla { private String nombre; private List columnas; private List renglones;

public String getNombre() { return nombre; } public List getColumnas() { return columnas; } public List getRenglones() { return renglones; }

public void setNombre(String newNombre) { nombre = newNombre; } public void setColumnas(List newColumnas) { columnas = newColumnas; } public void setRenglones(List newRenglones) { renglones = newRenglones; }

public Tabla() { this("", new ArrayList(), new ArrayList()); }

public Tabla(String newNombre, List newColumnas, List newRenglones) { setNombre(newNombre); setColumna(newColumna); setRenglones(newRenglones); } } B.2. MODELO DE OBJETOS 233

B.2. Modelo de Objetos

B.2.1. Clase Parámetro

Programa B.3 Implementación de la clase Parametro

public class Parametro { private String nombre; private String tipo; private String valor;

public String getNombre() { return nombre; } public String getTipo() { return tipo; } public String getValor() { return valor; }

public void setNombre(String newNombre) { this.nombre = newNombre; } public void setTipo(String newTipo) { this.tipo = newTipo; } public void setValor(String newValor) { this.valor = newValor; }

public Parametro() { this("", "", ""); }

public Parametro(String newNombre, String newTipo, String newValor) { setNombre(newNombre); setTipo(newTipo); setValor(newValor); } } 234 ANEXO B

B.2.2. Clase Solución

Programa B.4 Implementación de la clase Solucion

public class Solucion { private String nombre; private List lectores; private List procesadores; private List publicadores;

public String getNombre() { return nombre; } public List getLectores() { return lectores; } public List getProcesadores() { return procesadores; } public List getPublicadores() { return publicadores; }

public void setNombre(String newNombre) { this.nombre = newNombre; } public void setLectores(List newLectores) { this.lectores = newLectores; } public void setProcesadores(List newProcesadores) { this.procesadores = newProcesadores; } public void setPublicadores(List newPublicadores) { this.publicadores = newPublicadores; }

public Solucion() { this("", new ArrayList(), new ArrayList(), new ArrayList()); }

public Solucion(String newNombre, List newLectores, List newProcesadores) { setNombre(newNombre); setLectores(newLectores); setProcesadores(newProcesadores); setPublicadores(newPublicadores); }

public void procesar(List tablas) { ... } } B.2. MODELO DE OBJETOS 235

B.2.3. Clase EPD

Programa B.5 Implementación de la clase Epd

public class Epd { private String nombre; private List parametros; private List soluciones;

public String getNombre() { return nombre; } public List getParametros() { return parametros; } public List getSoluciones() { return soluciones; }

public void setNombre(String newNombre) { nombre = newNombre; } public void setParametros(ListnewParametros) { parametros = newParametros; } public void setSoluciones(ListnewSoluciones) { soluciones = newRenglones; }

public Epd() { this("", new ArrayList(), new ArrayList()); }

public Epd(String newNombre, ListnewParametros, List newSoluciones) { setNombre(newNombre); setParametros(newParametros); setSoluciones(newSoluciones); }

public void procesar(List tablas) { ... } } 236 ANEXO B C| Anexo: Listados de Configuraciones en Lenguaje XML

237 238 ANEXO C C.1. LECTORES 239

C.1. Lectores

C.1.1. Lector CSV

Configuración C.1 Estructura de la clase LectorCsv

... 240 ANEXO C

Configuración C.2 Ejemplo de la clase LectorCsv

data/movimientos.csv , " \ 1 false true false false false Folio 1 String Fecha 2 Date dd/MM/yyyy Concepto 3 String Importe 4 double C.1. LECTORES 241

C.1.2. Lector SQL

Configuración C.3 Estructura de la clase LectorSql

Configuración C.4 Ejemplo de la clase LectorSql

com.mysql.jdbc.Driver jdbc:mysql://localhost/banco root root SELECT TRAN_ID_K AS Folio, TRAN_DATE AS Fecha, TRAN_DESC AS Concepto, TRAN_CASH AS Importe FROM TRAN WHERE TRAN_DATE >= '21-04-2016'; 242 ANEXO C

C.1.3. Lector TXT

Configuración C.5 Estructura de la clase LectorTxt

... C.1. LECTORES 243

Configuración C.6 Ejemplo de la clase LectorTxt

data/movimientos.txt 1 false false Folio 0 8 String Fecha 8 10 Date dd/MM/yyyy Concepto 18 27 String Importe 45 10 double 2 244 ANEXO C

C.1.4. Lector XML

Configuración C.7 Estructura de la clase LectorXml

... C.1. LECTORES 245

Configuración C.8 Ejemplo de la clase LectorXml

data/movimientos.xml Folio 1 String Fecha 2 Date dd/MM/yyyy Concepto 3 String Importe 4 double 246 ANEXO C C.2. PROCESADORES 247

C.2. Procesadores

C.2.1. Procesador Agrupar

Configuración C.9 Estructura de la clase ProcesadorAgrupar

... ...

Configuración C.10 Ejemplo de la clase ProcesadorAgrupar

Movimientos Totales Fecha Importe 248 ANEXO C

C.2.2. Procesador Clonar

Configuración C.11 Estructura de la clase ProcesadorClonar

Configuración C.12 Ejemplo de la clase ProcesadorClonar

Movimientos Importe Cantidad true C.2. PROCESADORES 249

C.2.3. Procesador Clonar Tabla

Configuración C.13 Estructura de la clase ProcesadorClonarTabla

Configuración C.14 Ejemplo de la clase ProcesadorClonarTabla

Movimientos Detalles true 250 ANEXO C

C.2.4. Procesador Comparar

Configuración C.15 Estructura de la clase ProcesadorComparar

Configuración C.16 Ejemplo de la clase ProcesadorComparar

LlavesConIgualdad ValoresConIgualdad ValoresConDesigualdad ReporteDiferencias t1_ t2_ Folio Fecha Importe C.2. PROCESADORES 251

C.2.5. Procesador Conciliar

Configuración C.17 Estructura de la clase ProcesadorConciliar

252 ANEXO C

Configuración C.18 Ejemplo de la clase ProcesadorConciliar

MOVIMIENTOS ACCOUNT_STATUS LlavesConIgualdad LlavesConDesigualdad t1_ t2_ Folio NUMERO ID Fecha FECHA DATE Importe IMPORTE AMOUNT Tipo TYPE C.2. PROCESADORES 253

C.2.6. Procesador Dividir

Configuración C.19 Estructura de la clase ProcesadorDividir

... ...

Configuración C.20 Ejemplo de la clase ProcesadorDividir

Movimientos Detalles Importes Folio Fecha Concepto Folio Importe 254 ANEXO C

C.2.7. Procesador Eliminar

Configuración C.21 Estructura de la clase ProcesadorEliminar

...

Configuración C.22 Ejemplo de la clase ProcesadorEliminar

LlavesConIgualdad t1_Importe t2_Fecha C.2. PROCESADORES 255

C.2.8. Procesador Eliminar Tabla

Configuración C.23 Estructura de la clase ProcesadorEliminarTabla

...

Configuración C.24 Ejemplo de la clase ProcesadorEliminarTabla

Detalles 256 ANEXO C

C.2.9. Procesador Equivaler

Configuración C.25 Estructura de la clase ProcesadorEquivaler

Configuración C.26 Ejemplo de la clase ProcesadorEquivaler

Movimientos Equivalencias Concepto Concepto C.2. PROCESADORES 257

C.2.10. Procesador Filtrar

Configuración C.27 Estructura de la clase ProcesadorFiltrar

Configuración C.28 Ejemplo de la clase ProcesadorFiltrar

Movimientos {[Fecha] > #2016-04-21# && [Fecha] <= #fechaHoy# && [Importe] < 0.00} 258 ANEXO C

C.2.11. Procesador Fusionar

Configuración C.29 Estructura de la clase ProcesadorFusionar

Configuración C.30 Ejemplo de la clase ProcesadorFusionar

Depósitos Retiros Movimientos C.2. PROCESADORES 259

C.2.12. Procesador Insertar

Configuración C.31 Estructura de la clase ProcesadorInsertar

Configuración C.32 Ejemplo de la clase ProcesadorInsertar

Movimientos IVA double {[Importe] * 0.16} 260 ANEXO C

C.2.13. Procesador Ordenar

Configuración C.33 Estructura de la clase ProcesadorOrdenar

...

Configuración C.34 Ejemplo de la clase ProcesadorOrdenar

Movimientos Fecha C.2. PROCESADORES 261

C.2.14. Procesador Transformar

Configuración C.35 Estructura de la clase ProcesadorTransformar

Configuración C.36 Ejemplo de la clase ProcesadorTransformar

Movimientos Fecha String {[Fecha], yyyy-MM-dd} 262 ANEXO C

C.2.15. Procesador Unir

Configuración C.37 Estructura de la clase ProcesadorUnir

... ...

Configuración C.38 Ejemplo de la clase ProcesadorUnir

Detalles Importes Movimientos Número ID Folio Fecha Concepto Importe true C.3. PUBLICADORES 263

C.3. Publicadores

C.3.1. Publicador CSV

Configuración C.39 Estructura de la clase PublicadorCsv

Configuración C.40 Ejemplo de la clase PublicadorCsv

Flujos data/flujos.csv , " \ \n true 264 ANEXO C

C.3.2. Publicador TXT

Configuración C.41 Estructura de la clase PublicadorTxt

Configuración C.42 Ejemplo de la clase PublicadorTxt

Flujos data/flujos.txt true C.3. PUBLICADORES 265

C.3.3. Publicador SQL

Configuración C.43 Estructura de la clase PublicadorSql

Configuración C.44 Ejemplo de la clase PublicadorSql

com.mysql.jdbc.Driver jdbc:mysql://localhost/banco root root INSERT INTO FLOW (FLOW_DATE, FLOW_DEPO, FLOW_WITH, FLOW_BALN) VALUES (' %FLOW_DATE %', %FLOW_DEPO %, %FLOW_WITH %, %FLOW_BALN %); 266 ANEXO C

C.3.4. Publicador XML

Configuración C.45 Estructura de la clase PublicadorXml

Configuración C.46 Ejemplo de la clase PublicadorXml

data/flujos.xml Bibliografía

Libros

[1]A PPLE INC. (2010). Object-Oriented Programming with Objective-C. Cupertino, Ca- lifornia: Apple Developer Publications.

[2]B URD B. (2014). Java For Dummies, 6th Edition. Hoboken, NJ: John Wiley & Sons, Inc.

[3]D UBOIS P. (2013). MySQL, Fifth Edition. Massachusetts, MA: Addison-Wesley Professional.

[4]E VJEN B.,SHARKEY K.,THANGARATHINAM T.,KAY M.,VERNET A.&FERGUSON S. (2007). Professional XML. Indianapolis, IN: Wiley Publishing, Inc.

[5]F ORD N. (2008). The Productive . Sebastopol, CA: O’Reilly Media, Inc.

[6]F REEMAN E.,ROBSON E.,BATES B.&SIERRA K. (2004). Head First Design Patterns. Sebastopol, CA: O’Reilly Media, Inc.

[7]H ANMER R. (2013). Pattern-Oriented Software Architecture For Dummies. Chiches- ter, West Sussex: John Wiley & Sons Ltd.

[8]K URNIAWAN B. (2014). Java 7: A Comprehensive Tutorial. Quebec, Canada: Brainy Software.

[9]L ASATER C. (2007). Design Patterns. Plano, Tex.: Wordware Publishing, Inc.

[10]M ETSKER S.&WAKE W. (2006). Design Patterns in Java, Second Edition. Boston, MA: Pearson Education, Inc.

[11]N IEMEYER P. & LEUCK D. (2013). Learning Java, 4th Edition. Sebastopol, CA: O’Reilly Media, Inc.

267 268 BIBLIOGRAFÍA

[12]P ERRY G. (2011). Absolute Beginner’s Guide to Programming, Second Edition. In- dianapolis, IN: Que.

[13]S ARANG P. (2012). Java Programming. New York, NY: McGraw-Hill Professional.

[14]S CHILDT, H. (2014). Java: The complete reference (9th ed.). United States of America: McGraw-Hill Education.

[15]S HALLOWAY A.&TROTT J. (2004). Design Patterns Explained: A New Perspective on Object-Oriented Design, Second Edition. Boston, MA: Addison-Wesley Professional.

[16]S IERRA K.&BATES B. (2005). Head First Java, 2nd Edition. Sebastopol, CA: O’Reilly Media, Inc.

[17]S INTES A. (2001). Sams Teach Yourself Object Oriented Programming in 21 Days, Second Edition. United States of America: Sams Publishing.

[18]W EISFELD M. (2013). The Object-Oriented Thought Process, Fourth Edition. Boston, MA: Addison-Wesley Professional.

[19]W EST D. (2004). Object Thinking. Redmond, WA: Microsoft Press. PÁGINAS WEB 269

Páginas Web

[20]C INCOM SYSTEMS INC.. (2016). Our Past. Extraído el 10 de abril del 2016 desde Cincom Systems Inc.: http://www.cincomsmalltalk.com/main/about- us/smalltalks-past/

[21]C OPELAND J.. (19 de Junio del 2012). Alan Turing: The codebreaker who saved ‘millions of lives’. Extraído el 22 de marzo del 2016 desde BBC News: http://www.bbc.com/news/technology-18419691

[22]ENIACP ROGRAMMERS PROJECT. (2016). ENIAC Project. Extraído el 25 de marzo del 2016 desde ENIAC Programmers Project: http:// eniacprogrammers.org/eniac-programmers-project/

[23]F ERGUSON A.. (2000). A History of Computer Programming Languages. Extraído el 11 de marzo del 2016 desde: http://cs.brown.edu/~adf/programming_ languages.html

[24]H ODGES, A.. (9 de Febrero del 2015). Alan Turing: Creator of modern computing. Extraído el 22 de marzo del 2016 desde BBC: http://www.bbc.co.uk/ timelines/z8bgr82

[25]IBM DEVELOPERWORKS. (2015). UML basics: The class diagram. Extraído el 6 de agosto del 2015 desde IBM: http://www.ibm.com/developerworks/ rational/library/content/RationalEdge/sep04/bell/index.html

[26]ILMI NFORMATIQUE. (2014) jOpenDocument Homepage. Open Document library. Extraído el 17 de mayo del 2014 desde http://www.jopendocument.org

[27]K AY A.. (1993) The Early History of Smalltalk. Extraído el 10 de abril del 2016 desde http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST. html

[28]L AVINGTON S.. (20 de Junio del 2012). Alan Turing: Is he really the father of computing?. Extraído el 22 de marzo del 2016 desde BBC News: http: //www.bbc.com/news/technology-18327261

[29]M EYERS J.. (1993). A Brief History of The Computer (B.C. - 1993 A.D.. Extraído el 11 de marzo del 2016 desde Jeremy Meyers dot com: http://www. jeremymeyers.com/comp/ 270 BIBLIOGRAFÍA

[30]ORACLE-T HE JAVA™ TUTORIALS. (1995). Summary of Operators. Extraído el 27 de junio del 2016 desde ORACLE: https://docs.oracle.com/javase/ tutorial/java/nutsandbolts/opsummary.html

[31]W IKIMEDIA FOUNDATION,INC.. (2016). Ada Lovelace. Extraído el 11 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Ada_Lovelace

[32]W IKIMEDIA FOUNDATION,INC.. (2016). Alan Kay. Extraído el 10 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Alan_Kay

[33]W IKIMEDIA FOUNDATION,INC.. (2016). Alan Turing. Extraído el 18 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Alan_Turing

[34]W IKIMEDIA FOUNDATION,INC.. (2016). Algorithm. Extraído el 30 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Algorithm

[35]W IKIMEDIA FOUNDATION,INC.. (2016). Analytical Engine. Extraído el 11 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Analytical_Engine

[36]W IKIMEDIA FOUNDATION,INC.. (2016). Arthur Scherbius. Extraído el 19 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Arthur_ Scherbius

[37]W IKIMEDIA FOUNDATION,INC.. (2016). Assembly language. Extraído el 29 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Assembly_language

[38]W IKIMEDIA FOUNDATION,INC.. (2016). Automatic Computing Engine. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/ wiki/Automatic_Computing_Engine

[39]W IKIMEDIA FOUNDATION,INC.. (2016). BASIC. Extraído el 1 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/BASIC

[40]W IKIMEDIA FOUNDATION,INC.. (2016). . Extraído el 25 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Betty_ Holberton

[41]W IKIMEDIA FOUNDATION,INC.. (2016). Bill Joy. Extraído el 11 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Bill_Joy

[42]W IKIMEDIA FOUNDATION,INC.. (2016). Bjarne Stroustrup. Extraído el 9 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Bjarne_ Stroustrup PÁGINAS WEB 271

[43]W IKIMEDIA FOUNDATION,INC.. (2016). Blaise Pascal. Extraído el 11 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Blaise_ Pascal

[44]W IKIMEDIA FOUNDATION,INC.. (2016). Bletchley Park. Extraído el 23 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Bletchley_Park

[45]W IKIMEDIA FOUNDATION,INC.. (2016). Bombe. Extraído el 19 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Bombe

[46]W IKIMEDIA FOUNDATION,INC.. (2016). C++. Extraído el 9 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/C%2B%2B

[47]W IKIMEDIA FOUNDATION,INC.. (2016). C (programming language). Extraído el 8 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/C_ (programming_language)

[48]W IKIMEDIA FOUNDATION,INC.. (2016). Charles Babbage. Extraído el 10 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Charles_ Babbage

[49]W IKIMEDIA FOUNDATION,INC.. (2016). Charles Wheatstone. Extraído el 14 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Charles_Wheatstone

[50]W IKIMEDIA FOUNDATION,INC.. (2016). COBOL. Extraído el 31 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/COBOL

[51]W IKIMEDIA FOUNDATION,INC.. (2016). CODASYL. Extraído el 1 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/CODASYL

[52]W IKIMEDIA FOUNDATION,INC.. (2015). Comma-separated values. Extraído el 6 de agosto del 2015 desde Wikipedia: https://en.wikipedia.org/wiki/ Comma-separated_values

[53]W IKIMEDIA FOUNDATION,INC.. (2016). Dartmouth College. Extraído el 1 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Dartmouth_College

[54]W IKIMEDIA FOUNDATION,INC.. (2016). Dartmouth Time Sharing System. Extraído el 1 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/ wiki/Dartmouth_Time_Sharing_System 272 BIBLIOGRAFÍA

[55]W IKIMEDIA FOUNDATION,INC.. (2016). . Extraído el 8 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Dennis_ Ritchie

[56]W IKIMEDIA FOUNDATION,INC.. (2016). Difference engine. Extraído el 10 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Difference_engine

[57]W IKIMEDIA FOUNDATION,INC.. (2016). Double-precision floating-point format. Ex- traído el 1 de mayo del 2016 desde Wikipedia: https://en.wikipedia. org/wiki/Double-precision_floating-point_format

[58]W IKIMEDIA FOUNDATION,INC.. (2015). Document type definition. Extraído el 8 de agosto del 2015 desde Wikipedia: https://en.wikipedia.org/wiki/ Document_type_definition

[59]W IKIMEDIA FOUNDATION,INC.. (2016). Edsger W. Dijkstra. Extraído el 3 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Edsger_W. _Dijkstra

[60]W IKIMEDIA FOUNDATION,INC.. (2016). EDVAC. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/EDVAC

[61]W IKIMEDIA FOUNDATION,INC.. (2016). Document type definition. Extraído el 23 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ ENIAC

[62]W IKIMEDIA FOUNDATION,INC.. (2016). Enigma machine. Extraído el 19 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Enigma_ machine

[63]W IKIMEDIA FOUNDATION,INC.. (2016). FLOW-MATIC. Extraído el 1 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/FLOW-MATIC

[64]W IKIMEDIA FOUNDATION,INC.. (2016). Fortran. Extraído el 30 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Fortran

[65]W IKIMEDIA FOUNDATION,INC.. (2016). . Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Frances_ Spence

[66]W IKIMEDIA FOUNDATION,INC.. (2016). Frederic Calland Williams. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Frederic_Calland_Williams PÁGINAS WEB 273

[67]W IKIMEDIA FOUNDATION,INC.. (2016). Gleiwitz incident. Extraído el 19 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Gleiwitz_ incident

[68]W IKIMEDIA FOUNDATION,INC.. (2016). Goto. Extraído el 5 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Goto

[69]W IKIMEDIA FOUNDATION,INC.. (2016). Gottfried Wilhelm Leibniz. Extraído el 11 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Gottfried_Wilhelm_Leibniz

[70]W IKIMEDIA FOUNDATION,INC.. (2016). Grace Hopper. Extraído el 31 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Grace_Hopper

[71]W IKIMEDIA FOUNDATION,INC.. (2016). Herman Hollerith. Extraído el 14 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Herman_ Hollerith

[72]W IKIMEDIA FOUNDATION,INC.. (2016). High-level programming language. Extraído el 30 de marzo del 2016 desde Wikipedia: https://en.m.wikipedia. org/wiki/High-level_programming_language

[73]W IKIMEDIA FOUNDATION,INC.. (2016). hardware. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/ wiki/History_of_computing_hardware

[74]W IKIMEDIA FOUNDATION,INC.. (2016). History of programming languages. Extraí- do el 9 de marzo del 2016 desde Wikipedia: https://en.wikipedia. org/wiki/History_of_programming_languages

[75]W IKIMEDIA FOUNDATION,INC.. (2016). James Gosling. Extraído el 11 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/James_ Gosling

[76]W IKIMEDIA FOUNDATION,INC.. (2016). Java (programming language). Extraído el 11 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/ wiki/Java_(programming_language)

[77]W IKIMEDIA FOUNDATION,INC.. (2016). . Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Jean_Bartik

[78]W IKIMEDIA FOUNDATION,INC.. (2016). J. Presper Eckert. Extraído el 23 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/J. _Presper_Eckert 274 BIBLIOGRAFÍA

[79]W IKIMEDIA FOUNDATION,INC.. (2016). John Backus. Extraído el 30 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/John_Backus

[80]W IKIMEDIA FOUNDATION,INC.. (2016). John G. Kemeny. Extraído el 1 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/John_G. _Kemeny

[81]W IKIMEDIA FOUNDATION,INC.. (2016). John Mauchly. Extraído el 23 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/John_ Mauchly

[82]W IKIMEDIA FOUNDATION,INC.. (2016). John von Neumann. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ John_von_Neumann

[83]W IKIMEDIA FOUNDATION,INC.. (2016). . Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Kathleen_Antonelli

[84]W IKIMEDIA FOUNDATION,INC.. (2016). . Extraído el 8 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Ken_Thompson

[85]W IKIMEDIA FOUNDATION,INC.. (2016). Luigi Federico Menabrea. Extraído el 11 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Luigi_Federico_Menabrea

[86]W IKIMEDIA FOUNDATION,INC.. (2016). Machine code. Extraído el 30 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Machine_code

[87]W IKIMEDIA FOUNDATION,INC.. (2016). Marlyn Meltzer. Extraído el 25 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Marlyn_ Meltzer

[88]W IKIMEDIA FOUNDATION,INC.. (2016). Modula. Extraído el 9 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Modula

[89]W IKIMEDIA FOUNDATION,INC.. (2016). Modula-2. Extraído el 9 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Modula-2

[90]W IKIMEDIA FOUNDATION,INC.. (2016). Modular programming. Extraído el 9 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Modular_programming

[91]W IKIMEDIA FOUNDATION,INC.. (2016). National Physical Laboratory (Uni- ted Kingdom). Extraído el 25 de marzo del 2016 desde Wikipedia: PÁGINAS WEB 275

https://en.wikipedia.org/wiki/National_Physical_Laboratory_ (United_Kingdom)

[92]W IKIMEDIA FOUNDATION,INC.. (2016). Niklaus Wirth. Extraído el 6 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Niklaus_ Wirth

[93]W IKIMEDIA FOUNDATION,INC.. (2016). Object-oriented programming. Extraído el 9 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Object-oriented_programming

[94]W IKIMEDIA FOUNDATION,INC.. (2016). Oracle America, Inc. v. Google, Inc.. Ex- traído el 12 de abril del 2016 desde Wikipedia: https://en.wikipedia. org/wiki/Oracle_America,_Inc._v._Google,_Inc.

[95]W IKIMEDIA FOUNDATION,INC.. (2016). Pascal (programming language). Extraído el 6 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/ wiki/Pascal_(programming_language)

[96]W IKIMEDIA FOUNDATION,INC.. (2016). Pascal’s calculator. Extraído el 10 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Pascal% 27s_calculator

[97]W IKIMEDIA FOUNDATION,INC.. (2016). Programming language. Extraído el 30 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Programming_language

[98]W IKIMEDIA FOUNDATION,INC.. (2016). Punched card. Extraído el 14 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Punched_card

[99]W IKIMEDIA FOUNDATION,INC.. (2016). Ruth Teitelbaum. Extraído el 25 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Ruth_ Teitelbaum

[100]W IKIMEDIA FOUNDATION,INC.. (2016). Short Code (computer language). Extraído el 29 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/ wiki/Short_Code_(computer_language)

[101]W IKIMEDIA FOUNDATION,INC.. (2016). Single-precision floating-point format. Ex- traído el 1 de mayo del 2016 desde Wikipedia: https://en.wikipedia. org/wiki/Single-precision_floating-point_format

[102]W IKIMEDIA FOUNDATION,INC.. (2016). Smalltalk. Extraído el 10 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Smalltalk 276 BIBLIOGRAFÍA

[103]W IKIMEDIA FOUNDATION,INC.. (2016). Stepped reckoner. Extraído el 10 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Stepped_ reckoner

[104]W IKIMEDIA FOUNDATION,INC.. (2016). Stored-program computer. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Stored-program_computer

[105]W IKIMEDIA FOUNDATION,INC.. (2016). Structured programming. Extraído el 5 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Structured_programming

[106]W IKIMEDIA FOUNDATION,INC.. (2016). Sun Microsystems. Extraído el 12 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Sun_ Microsystems

[107]W IKIMEDIA FOUNDATION,INC.. (2016). Thomas E. Kurtz. Extraído el 1 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Thomas_E. _Kurtz

[108]W IKIMEDIA FOUNDATION,INC.. (2016). Timeline of programming languages. Ex- traído el 9 de marzo del 2016 desde Wikipedia: https://en.wikipedia. org/wiki/Timeline_of_programming_languages

[109]W IKIMEDIA FOUNDATION,INC.. (2016). Tom Kilburn. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Tom_Kilburn

[110]W IKIMEDIA FOUNDATION,INC.. (2016). Turing completeness. Extraído el 23 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Turing_completeness

[111]W IKIMEDIA FOUNDATION,INC.. (2016). Turing machine. Extraído el 18 de mar- zo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Turing_ machine

[112]W IKIMEDIA FOUNDATION,INC.. (2016). Turing test. Extraído el 23 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Turing_test

[113]W IKIMEDIA FOUNDATION,INC.. (2016). Unix. Extraído el 9 de abril del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Unix

[114]W IKIMEDIA FOUNDATION,INC.. (2016). Von Neumann architecture. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/ Von_Neumann_architecture PÁGINAS WEB 277

[115]W IKIMEDIA FOUNDATION,INC.. (2016). Williams tube. Extraído el 25 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/Williams_ tube

[116]W IKIMEDIA FOUNDATION,INC.. (2016). World War I. Extraído el 20 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/World_War_I

[117]W IKIMEDIA FOUNDATION,INC.. (2016). World War II. Extraído el 19 de marzo del 2016 desde Wikipedia: https://en.wikipedia.org/wiki/World_War_II