miércoles, 21 de diciembre de 2016

Depurar aplicaciones Android en Windows con AMD

En este artículo, voy a apartar un poco la temática general del blog, que es la arquitectura de software, para hablar sobre un problema reciente que he tenido y la solución que encontré.

Hace unas semanas decidí comprar una nueva laptop aprovechando una temporada de ofertas, hacía mucho que no renovada mí equipo y estaba realmente impaciente. Uno de mis principales objetivos era iniciarme en la programación en Android (con Android Studio). Había tenido algunos acercamientos previos, no profesionales, pero esta vez desea poner en serio manos en el asunto.

Vi una laptop de la que me enamore, tenía una memoria impresionante, un procesador más que decente y una tarjeta gracia aceptable, aparte de un teclado y monitores bastante cómodos. Solo había un problema, tenía un micro AMD.

Había oído que los procesadores AMD era muy lentos a la hora de ejecutar aplicaciones en el emulador de Android, pero me dije “¡Ba!, ¿Qué tal lento puede ser, con esta máquina?”. Así que me la lleve a casa. Todo iba como la seda, rapidísimo, hasta que probé el dichoso emulador. Era lento, muy lento… Ridículamente lento. El emulador tardaba horas en arrancar, ¡Horas! Y cuando arranco, no se podía hacer nada, cada movimiento era extremadamente tedioso.





En este punto podía hacer varias cosas [1]:

  • Devolver la laptop, pero ¡Me gustaba mucho!
  • Comprar una solución de pago, como Genymotion, pero no desea gasta más dinero y menos tener que realizar un poco anual.
  • Compra un o varios dispositivo móvil, y debugear en ellos, pero ¡Ey, me acabo de comprar una laptop, no estoy para derrochar!
  • Buscar algún otro emulador (gratuito), que funcione correctamente.

La solución que encontré fue combinar android-x86, un sistema operativo para pc, basado en Android, y Virtual Box (un sistema para gestionar maquinas virtuales). Con ambos sistemas conseguí tener un emulador rápido que se acoplaba perfectamente a Android Studio.

Estos son los pasos para montar un emulador con Android-x86 y Virtual Box.


Habilitar las capacidades de virtualización de tu equipo


Tanto AMD, como Intel, tiene capacidades de virtualización para acelerar el uso de máquinas virtuales, pero por defecto vienen, casi siempre, apagadas. Aunque no es necesario, si es muy recomendable que las habilites para el emulador vaya más rápido.


Conseguir el software


Puedes bajar el android-x86 del siguiente enlace, yo tengo android-x86_64-6.0-r1.iso (Marshmallow), aunque puedes usar la imagen que más te convenga:


Android Studio puedes descargarlo de:


Y por último Virtual Box


Procede a Instalar la maquina Android Studio y Virtual Box


Crea un maquina virtual para Android-x86


Inicia Virtual Box y crea una nueva máquina virtual que contenga Android-x86. Para lo cual haz clic, en “Nuevo”, y proporciona la siguiente información:

  • Nombre: “Emulador Android”
  • Tipo: Linux
  • Versión: Other Linux (64 bits)
  • Memoria: Yo seleccione 1204 Megas, pero ajústalo a tus necesidades y capacidades.
  • Disco duro: Deje el recomendado de 8 gigas.

Y continúa el proceso hasta finalizar.

Inicia la máquina, cuando te pregunte el disco de arranque indícale el archivo ISO que descargaste (en mi caso android-x86_64-6.0-r1.iso)

Nos mostrara el menú inicial, seleccionaremos

Installation – Install Android-x86 to harddisk

A continuación iremos seleccionando las siguientes opciones:

Create/Modify partitions

Do you want to use GPT, indicaremos que no.

Nos aparecerá el menú de particiones del disco virtual, seleccionaremos las siguientes opciones:

New -> Primary

Seleccionaremos Bootable.

Después Write y por ultimo quit.

Seleccionaremos la partición creada, normalmente sda1, y la formateamos como ext4 (confirmarnos el formateo).

Indicaremos que queremos instalar GRUB (yes), que no queremos instalar EFI (skip).

Indicaremos que quedemos nuestra directorio /system de lectura y escritura.

Se procederá a copiar los archivos.


Iniciar la maquina


Una vez realizada la instalación, debemos arrancar el sistema y configurarlo como si fuera un dispositivo Android cualquiera (con cuenta de Gmail y demás).

La primera ejecución puede llegar a ser un poco lenta (varios minutos), pero las siguientes serán aproximadamente, como iniciar un teléfono móvil (si no es que mas rápido).

Por cierto, el sistema de integración del ratón, no es automático, tenemos que seleccionar la opción “integración del ratón”, dentro del menú “Entrada”, cada vez que iniciemos la maquina y usar la tecla <HOST > (por defecto control derecho) para liberar el puntero de la máquina virtual.


Configurar las dimensiones de un teléfono móvil


Al momento de iniciar nuestro nuevo sistema operativo Android, veremos que tiene el aspecto de un monitor, más ancho que alto. El sistema tiene varias resoluciones y todas cumplen ese patrón.

Para poder usar resoluciones propias de un teléfono, es decir más alto que ancho, tenemos que modificar el arranque de nuestro sistema, además de indicar a nuestra máquina virtual que soporte dichas resoluciones.

Las resoluciones que recomiendo para emular un dispositivo móvil, son las siguientes:

  • 320x480
  • 480x800
  • 768x1280
  • 1080x1920

Para hacer posible que la máquina virtual reconozca estas resoluciones, hay que ejecutar en una ventana de cmd, los siguientes comandos (con la maquina virtual apagada):

VBoxManage setextradata "Emulador Android" "CustomVideoMode1" "320x480x16"
VBoxManage setextradata "Emulador Android" "CustomVideoMode2" "480x800x16"
VBoxManage setextradata "Emulador Android" "CustomVideoMode3" "768x1280x16"
VBoxManage setextradata "Emulador Android" "CustomVideoMode4" "1080x1920x16"

Ya que estén habilitadas estas resoluciones, iniciamos nuestra máquina, pulsando en la ventana de inicio de GRUB, la tecla ‘e’, para editar la línea de arranque. En la segunda pantalla, la volvemos a pulsar para entrar en el editor.

Debemos dirigirnos al final de la línea de arranque y agregar la configuración vga=ask. Guardamos y iniciamos la maquina, con la tecla ‘b’, para pulsar enter cuando nos lo solicite.

Aquí vemos la las opciones de resolución posible (para ver más escribimos ‘scan’):


Es necesario apuntar, los números de “Mode” que corresponde a cada resolución nueva, en mi caso son los cuatro últimos y son los siguientes:

Modo
Dimensiones
360
320x480
361
480x800
362
768x1280
363
1080x1920

Estos números están en Hexadecimal, a partir de ahora necesitaremos los mismo números pero en decimal, para convertirlos, puedes usar, por ejemplo, esta página http://www.binaryhexconverter.com/hex-to-decimal-converter

Los valores de mis pantallas en decimal quedarían así:

Dimensiones
Hexadecimal
decimal
320x480
360
864
480x800
361
865
768x1280
362
866
1080x1920
363
867

Apunta bien esos valores por que los vas a necesitar en la sección siguiente


Configurar GRUB, para arrancar en diversas resoluciones


Una vez que tenemos los mencionados números de las resoluciones, debemos configurar GRUB, para arrancar una u otra. Para ello, debemos crear nuevas entraras en su archivo de configuración.

Para poder modificarlo debemos seleccionar, en el arranque de la máquina virtual “Android-x86 6.0-r1 (Debug mode)” (o el modo debug que aparezca) en el menú de inicio. Se nos habilitara un Shell donde podremos escribir comandos (posiblemente tengamos que pulsar enter antes de comenzar a escribir):

Los pasos a completar son:

Localizar el archivo menu.lst, en mi caso está en /mnt/grub/.

cd /mnt/grub

Lo editamos con vi:

vi menu.lst

Tendrá una apariencia como esta:




Nuestro objetivo es que acabe con las siguientes entradas:

default=0
timeout=6
splashimage=/grub/android-x86.xpm.gz
root (hd0,0)

title Android-x86 6.0-r1
kernel /android-6.0-r1/kernel quiet root=/dev/ram0 androidboot.hardware=android_x86_64 SRC=/android-6.0-r1
initrd /android-6.0-r1/initrd.img

title Android-x86 6.0-r1 320x480x32
kernel /android-6.0-r1/kernel quiet root=/dev/ram0 androidboot.hardware=android_x86_64 SRC=/android-6.0-r1 vga=864
initrd /android-6.0-r1/initrd.img

title Android-x86 6.0-r1 480x800x32
kernel /android-6.0-r1/kernel quiet root=/dev/ram0 androidboot.hardware=android_x86_64 SRC=/android-6.0-r1 vga=865
initrd /android-6.0-r1/initrd.img

title Android-x86 6.0-r1 768x1280x32
kernel /android-6.0-r1/kernel quiet root=/dev/ram0 androidboot.hardware=android_x86_64 SRC=/android-6.0-r1 vga=866
initrd /android-6.0-r1/initrd.img

title Android-x86 6.0-r1 1080x1920x32
kernel /android-6.0-r1/kernel quiet root=/dev/ram0 androidboot.hardware=android_x86_64 SRC=/android-6.0-r1 vga=867
initrd /android-6.0-r1/initrd.img


title Android-x86 6.0-r1 (Debug mode)
kernel /android-6.0-r1/kernel root=/dev/ram0 androidboot.hardware=android_x86_64 DEBUG=2 SRC=/android-6.0-r1
initrd /android-6.0-r1/initrd.img

title Android-x86 6.0-r1 (Debug nomodeset)
kernel /android-6.0-r1/kernel nomodeset root=/dev/ram0 androidboot.hardware=android_x86_64 DEBUG=2 SRC=/android-6.0-r1
initrd /android-6.0-r1/initrd.img

title Android-x86 6.0-r1 (Debug video=LVDS-1:d)
kernel /android-6.0-r1/kernel video=LVDS-1:d root=/dev/ram0 androidboot.hardware=android_x86_64 DEBUG=2 SRC=/android-6.0-r1
initrd /android-6.0-r1/initrd.img

Tenemos que agregar nuevas configuraciones basadas en la primera y agregar el atributo vga=<valor de nuestra pantalla> por ejemplo vga=865, siendo el numero indicado, el valor en decimal, que se obtuvo en las pantalla de seleccionar resolución (estando en dicha pantalla en hexadecimal).

Para editar un archivo en vi, tenemos los siguientes comandos

Tecla
Efecto
Ejemplo
Esc
Permite introducir comandos
I
Comienza una inserción
dd
Borra una línea completa
Nyy
Copia N líneas al portapapeles
10yy
p
Pega las líneas del portapapeles
:wq
Salva el archivo y sale

A partir de ahora cuando iniciemos nuestra máquina virtual podremos seleccionar la resolución deseada



Ajustar la resolución


Cuando iniciemos la aplicación, nos daremos cuenta que la resolución de Android, es mayor que nuestro monitor, con lo que aparecerán unas scrollbar con la que nos podemos desplazar, lo cual es bastante incómodo.

Para solucionarlo, podemos pulsar la tecla <HOST>+C, hará que sea redimensionable la ventana de Android, con el nuevo problema que se verá con un “aspecto” raro:




Para solucionarlo dimensiona la ventana de la pantalla, fijándote que la figura central quede circular, con eso obtendrás la resolución deseada. Tómalo como referencia, siempre que cambies el tamaño de la pantalla.



Por otro lado el posible que pierdas frecuentemente el uso del ratón, para recuperarlo pulsa <HOST>+c y activa la integración del ratón, para luego volver a pulsar <HOST> + C y volver a la resolución deseada.


Configura la red


La configuración que yo tengo en la red de la máquina virtual de Android es “Adaptador puente”, si tienes por necesidad otra, ve a esta página ver configuraciones adicionales http://www.android-x86.org/documents/debug-howto




¡Vamos a debugear!


Ya casi hemos llegado…

Este es el único paso que vas a tener que hacer cada vez que quieras debugear tu aplicaciones (y hayas reiniciado tu maquina).

Necesitas “conectar” tu maquina física con la máquina virtual Android, para lo cual necesitas conocer la IP de dicha máquina.

En una terminal de Android, teclea ifconfig, y apunta la IP, que te va a dar (suele ser siempre la misma si así configuras tu router, por si más adelante quieres hacer un Shell).


Una vez que tengas dicha IP, en tu máquina de Windows, teclea el comando

adb connect <IP de la máquina de Android>



¡Listo!, ahora podemos iniciar nuestro Android Studio, y comenzar a depurar.





[1] Otra opción no expuesta es usar el emulador en Linux, donde se comparta de forma nativa, con un muy buen rendimiento, prueba que es lo mejor para ti y elije lo que más te convenga.

lunes, 28 de noviembre de 2016

Arquitectura de un sistema empresarial prototipo


En las entradas anteriores establecimos que la gran mayoría del software empresarial se parece entre sí, y entre otros ámbitos de negocio semejantes. Lo que es diferente es la variabilidad de las características que se implementan, cuales son y de qué forma son implementadas.

Vamos a hacer un pequeño acercamiento a la arquitectura de un sistema empresarial prototipo básico. Se muestra un diagrama de bloques de dicho prototipo:




Nota: Debido a que este artículo se creó originalmente como parte del desarrollo de generador “CapicuaGen”, existe varias partes que hacen referencia a dicho generador llamadas “Posibles uso del generador en este contexto”, las cuales se encuentran en cursiva. Si no se está creando un generador de código, o si no es de interés, la parte relativa a “CapicuaGen”, se puede omitir.

Interfaz de usuario


En esta capa se define la apariencia y la interacción con nuestros usuarios y clientes, debe ser lo suficientemente sencilla para que la usen con facilidad, y lo suficientemente completa para que se sea útil. Posibles interfaces son:


Interfaces tradicionales para monitor (computadora)


  • Interfaz de escritorio: Puede ser para un sistema de escritorio para Windows, Linux, Mac u otros.
  • Interfaz web: Un sitio web tradicional. Aunque HTML y CSS nos garantiza homogeneidad entre los distintos navegadores, ocasionalmente hay pequeñas diferencias de visualizado, que tenemos que tener en cuenta al momento de desarrollar.

Interfaces móviles


  • Aplicaciones: Son las aplicaciones nativas desarrolladas para cada dispositivo móvil. En este escenario tenemos que consideran distintas resoluciones de pantalla y tipos de dispositivo como tablet, o smart phones. Podemos desarrollar aplicaciones para Android, iOS y Windows entre otros.
  • Interfaz móvil web: Es una interfaz Web diseñada explícitamente para dispositivos móviles (considerando el tamaño de su pantalla).

Posibles uso del generador en este contexto



La interfaz representa lo que puede "hacer" y puede "ver" nuestro usuario, y esto debería ser común para todas las plataformas, el generador debiera ser capaz de crear dicha funcionalidad, y una vez que cambie el negocio, rehacer el código automáticamente para que se adapten todas las interfaces a dichos cambios. Sería necesario contar con una característica generadora para cada plataforma deseada.


Interfaz de servicios


Representa la puerta de acceso a la funcionalidad del negocio. Es una fachada que expone la funcionalidad de forma que la pueda consumir apropiadamente la interfaz gráfica. De esta manera aislamos el negocio, de la forma en la que este es expuesto.

Por ejemplo puede exponerse el negocio de las siguientes formas (entre otras):

  • Componentes
  • Web Services
  • Socket
  • RPC
  • HTTP


Posibles uso del generador en este contexto



Debido que es un mismo negocio el que se debe exponer y que solo cambia la forma de exponerse, el generador puede crear automáticamente cada fachada necesaria en base a dicho negocio.


Negocio


En esta capa está el problema que queremos resolver en nuestro sistema, representa, en forma de software, la solución a una necesidad a cumplir por la empresa con respecto al mercado.

En esta capa puede haber diversos elementos y diferentes enfoques de resolución, podríamos distinguir los siguientes elementos:

  • Entidades de negocio: Son elementos que representan al modelo del negocio, la representación debe ser tanto de información (datos), como de comportamiento, aislar los datos del comportamiento, nos llevaría a un modelo de dominio anémico. [1]
  • Flujos de operación: Son elementos que representan que entidades de negocio están vigentes y la forma en la que se convierten en otras. Pueden representar flujos de trabajo que no tengan una correspondencia en una entidad de negocio.
  • Acceso a otros componentes: Representan el punto de entrada a componentes ajenos a nuestro software, pueden ser componentes empresariales o componentes externos a nuestra empresa, en cualquier caso esta funcionalidad está aislada, de forma que otros componentes de negocio u otra capa, ignoran el acceso a componentes externos.


Posibles uso del generador en este contexto



Esta parte es muy dependiente de como diseñemos el modelo del dominio de nuestra aplicación, en base a esto podemos crear elementos como:

  • Entidades de negocio en base a otros elementos como un UML, o una base de datos.
  • Agregar funcionalidad en base a diversas configuraciones.
  • Agregar funcionalidad y comportamiento común de la empresa.

Persistencia


Esta capa se encarga gestionar el acceso a diversas fuentes de persistencia, desde donde obtener y guardar la información de nuestro sistema.


Interfaz de persistencia


Expone las funcionalidades de persistencia abstrayendo al negocio de conocer los detalles sobre la tecnología encargada de esta.

Posibles uso del generador en este contexto


Es posible crear las interfaces de los servicios de persistencia, siguiendo algún patrón de software o algo política empresarial sobre cómo deben persistirse los elementos de negocio.


Proveedores de Información


Son los mecanismos concretos por los que se persiste la información. Gracias a la interfaz de persistencia dichos mecanismo podrían ser cambiados por otros, sin afectar al negocio. Algunos de estos mecanismos son:

  • ORM.
  • Stored Procedures.
  • Sentencias SQL.
  • XML.
  • Archivos de texto.
  • Servicios RESTFul.

Posibles uso del generador en este contexto



La persistencia es una de las grandes oportunidades para los generadores de código [2]. Dependiendo de nuestro diseño puede convertir los modelos, en tablas y crear los puntos de acceso para dichas tablas, ya sea por SQL, Stored, o tecnologías ORM. Por otro lado si nuestro diseño comienza por la creación las tablas y procedimientos almacenados (cosa que en principio no es recomendable), se puede crear el acceso a la base de datos, y el modelo a través de ella.


Abstracción del acceso a datos


Mientras la capa anterior trabaja sobre la tecnología de persistencia, esta capa proporciona acceso a dicha tecnología, sin preocuparse donde esté ubicada “físicamente” dicha tecnología. Por ejemplo si el destino es un documento XML, dicho documento puede guardarse en un archivo, en una base de datos, o en cualquier otro tipo de repositorio. Si el destino fuera una base de datos, esta podría ser SQL Server, Informix, MySQL, SQLite, o cualquier otro. Esta capa sabría cómo comunicarse con cada uno de estos proveedores, con independencia de la capa anterior. Igualmente esta capa se encargaría de cualquier tipo de la configuración sobre conexiones y localización de archivos, acorde a las políticas de la empresa acerca del almacén y la seguridad de esta información.

Posibles uso del generador en este contexto



El generador puede ayudarnos a crear el código necesario para el acceso a los repositorios de información, y además puede generar distintos accesos, para simular diversos esquemas de persistencia en un ambiente de pruebas o de desarrollo.


Seguridad


Es una capa que afecta a todas las demás independientemente de lo profundas o externas que sean [3]. Los servicios que ofrecen la capa de seguridad son (entre otros):

  • Autentificación: Garantiza que la persona que está usando el software es quien realmente está identificada ante el sistema.
  • Autorización: Asegura que la persona autenticada, solo pueda realizar las tareas sobre las que tenga autorización.

Posibles uso del generador en este contexto



El generador puede crear distintos tipos de seguridad y agregarla en los puntos requeridos ya sea por programación orientada a aspectos, o cualquier otro mecanismo.


Políticas empresariales


Implica cualquier aspecto empresarial, que se pueda aplicar de forma vertical en cualquier punto de nuestro sistema. Pueden ser, entre otro:

  • Reglas empresariales que deben cumplir todos los sistemas.
  • Mecanismos de Cache
  • Mecanismos y política de bitácoras y trazabilidad
  • Inyección de código
  • Gestión de dependencias
  • Validación de datos
  • Control de excepciones

Posibles uso del generador en este contexto



Dependiendo de qué tipo sea la política empresarial, el generador de código, puede ayudarnos a introducirlas en los lugares adecuados de nuestro software, y encargase de “replicarlas” en el caso que estas cambien.


Acerca de las arquitecturas empresariales


Si bien lo mostrado anteriormente es un ejemplo de una arquitectura empresarial prototipo, hay que tener en cuenta que debemos usar la arquitectura adecuada para resolver cada problema en concreto. No existe una arquitectura que sea indicada para resolver todas los necesidades de software a los que se enfrenta un empresa.

Para considerar una arquitectura software adecuada, esta debe cumplir lo siguiente:

  • Que resuelva la necesidad de negocio de forma adecuada.
  • Que sea sencilla de entender y de explicar.
  • Que sea mantenible.




[1] El modelo de dominio anémico, es un antipatrón de diseño, en que se usa un modelo del dominio, sin lógica de negocio, lo cual rompe el paradigma de la orientación a objetos donde dichos elementos (información y comportamiento) van juntos en una misma entidad.


[2] Jack Herrington, expresa en su libro “Code Generation in Action”, que el principal motivo por el cual comenzara a usar generación automática de código, son las experiencias y dificultades que tuvo trabajando con capas de acceso a datos, como menciona el capítulo 6: “Teaching engineers how to use code generation for database work is my primary reason for writing this book. This motivation comes from some personal experiences with database work.”


[3] Principio “Defense in Deep”

lunes, 24 de octubre de 2016

Diseño de una fábrica de software


Analicemos los elementos necesarios que necesitamos para crear nuestra línea de producción de software , basado en un esquema de “Fabrica de software”, que se puede implementar dentro de nuestra empresa, ya sea que esta tenga un departamento de desarrollo de sistemas o que el giro de la empresa sea el desarrollo de sistemas en sí.


Estándares de programación: Es una colección de reglas de programación que define como debe crearse el software de nuestra empresa , es importante que todos los programadores los conozcan y respecten. De esta forma cualquier codificador del equipo podría asumir cualquier tarea de programación o mantenimiento con una curva mínima de aprendizaje. Deben de existir herramientas que validen de forma automática que los estándares se cumplan.

Metodologías adecuadas: Debemos trabajar de la forma correcta y que dicha forma sea conocida y cumplida por todos los integrantes del equipo. Debido a las características de nuestra línea de producción, en que muchos elementos serán generados automáticamente, puede utilizarse un enfoque ágil (como XP, o Scrum), en el que se presenten cada poco tiempo un prototipo que a la vez sirva para definir y acércanos más a la necesidad final del cliente (En las metodologías agiles se asume que el software va a cambiar y eso se valora como algo positivo).

Patrones de software : Es necesario que el equipo de desarrollo conozca los patrones de software y los sepa aplicar de forma adecuada, igualmente nuestro generador puede implementar automáticamente los patrones de software, para garantizar que se usen correctamente.

Consumo de framework de terceros: Es necesario identificar los componentes existentes en el mercado que nos pueden ayudar en nuestro desarrollo . Muchos de estos componentes resuelven problemas que a nosotros nos pueden resultar complejos o los más probable que estén fuera del ámbito del problema de negocio que queremos resolver (por ejemplo cuando creamos un portal web , no queremos crear un Framework MVC, por que ese no es nuestro objetivo real, por eso usamos alguno previamente existe como ASP.NET MVC o Apache Struts). Es importante encapsular los framework elegidos apropiadamente para no generar dependencias externas excesivas, para ello, nos será muy útil nuestro generador de código que puede crear las interfaces adecuadas hacia dichos frameworks (y cambiarlas si es necesario).

Desarrollo de framework empresariales propios: Se encapsularan los componentes y funcionalidades comunes que se hayan sido desarrollados dentro la empresa . Cualquier funcionalidad que pueda ser global, se convierte en una herramienta que podrá ser usada en cualquier futuro desarrollo . Nuestro generador puede administrar dichos componentes.

Control de versiones: En toda fábrica es necesario tener controlado el software generado, permitir "viajar" sobre distintas revisiones y sobre distintas ramas de un mismo producto , para ello podemos usar herramientas como SVN o GIT.

Generador de código: Es el encargado de generar la gran parte de nuestro sistema . Todo característica repetible, que se propague en dirección vertical u horizontal en nuestra aplicación, se convertirá en una parte de este generador , una característica a incluir en un catálogo común.

Un característica común repetible, no es un fragmento de código, ni una librería que se usa en varios lugares, sino una parte del desarrollo , que puede ser reusada en otros desarrollos, esto incluye la parte del análisis y del diseño, no solo del código. El código se generara automáticamente adaptándose a la circunstancia indicada para el sistema que se quiera hacer.

Por ejemplo si empresarialmente definimos que nuestros sistemas deben tener cierta arquitectura, existirá una característica (o conjunto de ella), que se encarga de generar el código que respecte dicha característica. El código por sistema será diferente pero se habrá generado automáticamente, en base a un análisis y diseño que se realizaron previamente. El código de la misma forma, podrá cambiar de arquitectura, si cambiamos la característica generadora, o podrá crearse simultáneamente para varias arquitectura, por ejemplo podríamos desear que se genere nuestro software para escritorio y para teléfono móvil (Android o iOS ). De esta manera para una misma lógica de negocio , se crearan diferentes arquitecturas de forma automática.

Hay que considerar que para resolver el desarrollo de un sistema no se puede usar cada uno de los elementos previamente mencionados como única solución (de hacerlo caeremos en el problema del martillo de oro ). Es necesario combinar adecuadamente todos los elementos, para conseguir un software estable y con escalable a futuro:

Los estándares y las metodologías por sí solo, nos dan las reglas y las buenas prácticas sobre cómo crear nuestro software , por otro lado los patrones de software deben usarse de la forma y en los lugares correctos.

El abuso de los frameworks externos nos genera una dependencia, tanto al nivel de arquitectura, como técnicamente. Cuando estamos muy atados a un framework, y este no resuelve un problema en concreto, la solución puede volverse tremendamente complicada y enrevesada, entorpeciendo el mantenimiento del producto .

Intentar resolver todos los problemas con framework propios tampoco es una solución idónea, puesto que caeremos en dos escenarios posibles para abarcar todas las circunstancias propias de nuestro negocio , o crearemos un framework muy abstracto, que no resuelva nada, o creamos un framework muy concreto, amplio y difícil de manejar y mantener.

Si solo usáramos nuestro generador de código de forma exclusiva, este crearía muchos elementos repetidos, y código innecesariamente largo, haciéndolo difícil de comprender su funcionamiento, y por lo tanto condenado a ir perdiendo su utilidad con el tiempo (por posibles mantenimiento y diagnósticos).

Por todo eso debemos combinar en nuestra línea de producción de software todos los elementos según las necesidades particulares de los sistemas a desarrollar, eso hará que sean sistemas con alta calidad , funcionales y escalables.

El manifiesto ágil indica que se debe valorar más la colaboración con el cliente sobre negociación contractual y respuesta ante el cambio sobre seguir un plan.

La expresión "Martillo de oro", hace referencia el refrán "Al que tiene un martillo, todo le parece un clavo". Se quiere evidenciar que es fácil creer que nuestra herramienta o tecnología, por buena que sea, puede resolver cualquier problema, aunque no sea apropiada para la tarea.

lunes, 26 de septiembre de 2016

Dos años después

¡Cumplimos dos años en el blog! Este es el resumen de todo lo acontecido:





¿Cuántas publicaciones hemos hecho este año?, unas 13, de un total de 35.


¡Tenemos redes sociales!


Estamos en Facebook, Google+ y twitter en los siguientes enlaces:


Programación


Temas que tienen que ver directamente con asuntos de programación y código



Seguridad


Temas que tienen que ver con la seguridad en el desarrollo de software






Post relativos a reglas de software de la ingeniería de software


Es un conjunto de reglas o recomendaciones que nos ayudan a diseñar y construir software, con la intención de que aumentar nuestras posibilidades de éxito. Se han publicado las siguientes:




Ingeniera de software en la empresa


Artículos relativos al desarrollo de software en la empresa.





CapicuaGen


CapicuaGen es un producto orientado a la generación automática de código, y a la construcción de software desde un enfoque generativo. ¿Qué quiere decir esto? Bueno básicamente que construiremos un software, cuya misión es construir otro software, o más exactamente el código de dicho software.








Y esto es todo en el segundo año, espero que os haya gustado :-)

jueves, 8 de septiembre de 2016

CapicuaGen: Acerca de la fabricación de software (Breve historia de los lenguajes de programación)

Aunque tradicionalmente se nos indica en la ingeniería de software que este se construye, la verdad es que la tendencia desde finales de los años noventa es tender a la fabricación de software.

La diferencia entre construir y fabricar, es que cuando se construye algo, se analiza, se diseña y se construye por única vez y por proyecto, como por ejemplo “construir una casa”, sin embargo cuando algo es fabricado, se diseña y analiza una vez y, generalmente en cadena, es ensamblando con partes previamente fabricadas, generando una serie de productos por un costo reducido. Un ejemplo de esto es la industria automotriz.

Si vemos la evolución de los lenguajes y metodologías de programación, cada vez se basan más en reusar software creados.

Repasemos brevemente las circunstancias sobre cómo esta tendencia se ha ido dando. Analizando la historia de los lenguajes de programación vemos que estos se han ido simplificando desde sus inicios a la actualidad, para centrarse en conceptos cada vez más abstractos y alejándose de las instrucciones que realmente procesa una CPU.



Asm (ensamblador) con sus saltos de memoria y macros, dio paso a C, un lenguaje estructurado, diseñado para facilitar la programación, a un nivel más alto que ASM, sin embargo fácilmente traducible a este. C tiene un conjunto básico de librerías ampliable, se pueden usar "módulos" y estos son fácilmente insertados en otras aplicaciones y sistemas. A C, le siguió C++ "C con clases", que abstraía más la programación y la reusabilidad de componentes .

Debido a que asm, C y C++, se usaban en multitud de dispositivos (no solo computadoras, sino aparatos electrónicos programables en general), y que cada dispositivo parecía manejar su propia versión de estos lenguajes, era necesario generar un programa específico para controlar a cada uno de ellos, programas que prácticamente hacían los mismo, pero cuyo código era diferente, dificultando en exceso la portabilidad de los sistemas. Ante este problema, casi a mediados de los 90, surgió Java, un lenguaje pensado para programase exactamente igual en todos los dispositivos. Java está basado en C++, pero depurado de todas las funcionalidades confusas y peligrosas de este lenguaje, simplificando mucho la programación, a la vez que hacia posible que un mismo programa (compilado), funcionara en varias arquitecturas disparejas.

A Java le siguió la contraoferta de Microsoft (que por aquel entonces tenía un compilador de C++, bastante popular y su IDE y lenguaje tradicional “Visual Basic”), creando su arquitectura .NET a principios de los años 2000. Dicha arquitectura, está inspirada en Java, simplificando aún más su uso, en C++, y buscando un enfoque de sencillez al momento de programar, en Visual Basic y Delphi (es de notar que Delphi y C#, comparte un creador común, El arquitecto principal del equipo encargado de Delphi (en Borland) y C# (en Microsoft) fue el danés Anders Hejlsberg.). Además .NET ofrecía programar en varios lenguajes (originalmente Visual Basic .NET, C# y J#), y posibilidad de usar componentes creados en unos lenguajes en otros.

Es curioso también señalar la relevancia que tuvo Visual Basic (versión 6 y anteriores), en los 90 y buena parte de los 2000, a pesar de ser un lenguaje poco práctico, muy poco escalable, y tener un gran número de problemas de fondo. Visual Basic enfoco el desarrollo a través de componentes que eran fáciles de desarrollar y de incrustaban de forma gráfica en los desarrollos, comunicándose con otros componentes en forma de eventos (mensajes que lanzaba el mismo componentes esperando a que un oyente que los interpretara). En estos casos realmente estamos “fabricando” software ensamblando distintas piezas, desde un catálogo disponible, de una forma sencilla y clara. Adema Visual Basic unifico el acceso a base de datos, enmascarándolo dentro de un esquema común (independiente del motor subyacente), de tal forma que se podía establecer comunicación, y ejecutar sentencias SQL, sin importar la base de datos.

Linus Torvald, creador de Linux, alabo en el 2006 a Visual Basic, diciendo que a pesar de no ser un gran lenguaje de programación hizo más por la programación que los lenguajes orientados a objetos, al introducir interfaces sencillas de conexión a base de datos. Si bien el comentario es muy discutible, es más que curioso por provenir de quien viene, la conclusión sobre esto, es que de todos los lenguajes se puede aprender algo.

Para la WWW, tenemos una evolución parecida. HTML comenzó con un conjunto de etiquetas pare definir formato y contenido, y se les fue añadiendo programación en forma de scripts, para añadirle funcionalidad. En la actualidad, está dividido en varias aspectos, el contenido que es definido por HTML, la presentación que lo define CSS, y la funcionalidad que es implementada a través de JavaScript. Es de espera que cada uno de estos elementos sean componentes independientes que se pueden separar y juntar, según convenga, por ejemplo un mismo contenido, se pueden mostrar de forma diferente en una pantalla de ordenador, y un dispositivo móvil. Igualmente para el desarrollo de las sitios web, se puede usar un amplio catálogo de framework y “librerías” para facilitar su desarrollo, como JQuery, Angular, o Bootstrap (nuevamente se reúsa y se ensamblan componentes para crear software ).

El enfoque de “Fabrica” es muy evidente en los productos que nos ayudan a crear sitios web automáticamente, un ejemplo muy claro es Blogger, que sin conocer nada de HTML, ni de desarrollo de software, podemos tener un blog completo solo dando instrucciones sobre cómo queremos que sea, y que elementos querernos que lo compongan.

La evolución hacia la reusabilidad también tomo el enfoque de componentes y servicios. Se comenzaron a crear librerías, cuya funcionalidad eran utilizada por diversos sistemas, posteriormente se realizaron componentes que podrían invocarse remotamente (RPC, CORBA, DCOM,…), y por ultimo servicios que exponen funcionalidad de una forma estándar y fácilmente consumibles por cualquier sistema en cualquier tecnologías (SOA, RESTFul,..). Muchas de estos componentes y servicios están expuestos públicamente para su uso de forma gratuita, por ejemplo para Ruby, Perl, C# y Java, tenemos RubyGem, CPAN, NuGet y Maven respectivamente, como repositorios donde obtener componentes, y como servicios tanto Google como Apple o Amazon, exponen multitud de ellos, los cuales podemos consumir desde nuestros sistemas.

Como vemos, la historia nos lleva a lenguajes, metodologías y ambientes en los que se tiende a lo siguiente:


  • Lenguajes de programación cada vez más abstractos y enfocados a la manera de pensar de los programadores, no a la manera de operar de las maquinas.
  • Sistemas que tienden a la reutilización del software, a crearse a través del ensamblado de componentes previamente desarrollados.
  • Sistemas que delegan en componentes y servicios de diversas arquitecturas, de los que no se tiene conocimiento de cómo realizan su tarea, sino de la funcionalidad que realizan (Se sabe el “que” no el “como”).

Con respecto a este enfoque, podemos diseñar nuestra metodóloga de “Fabrica”, en la se creara una “Línea de producción”, que será configurada con los requisitos y características del software deseado y creara un sistema de la forma más automática que sea posible (Contra más característica tengamos disponibles en el catálogo de la fábrica, más funcionalidad podrá crearse de forma automática).

domingo, 28 de agosto de 2016

CapicuaGen: Desarrollo de software en la empresa, Parte II

Si bien las empresas pueden llegar ser muy diferentes entre sí, a nivel de software es más lo que se parece que en los que se diferencia. En cualquier de los enfoques anteriores, se dan dos constantes que hay tener en cuenta:

El software va a cambiar: Los cambios son necesarios para el negocio, estos cambios se darán de forma cada vez más frecuente y debemos poder responder a la necesidad de dicho cambio para que nuestra empresa siga vigente en el mercado de la forma adecuada.

El software se parece entre sí: Casi todo el software empresarial se parece entre sí, casi todas las empresas gestionan recursos de algún tipo (humanos, económicos, etc.) y generan un producto (dinero, servicios, o bienes de alguna naturaleza). Técnicamente hablando casi todas los sistemas software tienen características como acceso a datos, seguridad, interacción con el usuario o trazabilidad.

En el escenario donde una misma empresa fabrica su propio software, se deseara que este sea homogéneo entre los distintos sistemas que posee, para disminuir la curva de aprendizaje entre sus usuario y fomentar la imagen corporativa unificada.

En las fábricas de software, se deseara reusar los máximos componentes posibles entre desarrollos diversos, para optimizar el uso de recursos y reducir los costos de producción.

En el caso de la empresa que vende un producto de software, esta querrá vendérsela al máximo número de posibles clientes, con las mínimas y menos costosas personalizaciones posibles.

En cualquier de estas opciones, se tiende a desarrollar componentes y elementos software, que se reúsan en los diversos sistemas. Los sistemas a su vez, se parecen a otros sistemas con los que comparten una funcionalidad semejante, o tienen elementos técnicos semejantes como características y aspectos comunes. La parte que hace diferencia a un software, aunque en el producto final es la que más destaca, en proporción es la que menor código representa, con respecto a la parte de código que puede reciclarse.

Veamos una serie de ejemplos que muestren las constantes sobre el cambio y las semejanzas del software.

Si existe un mercado que evidencie la necesidad rápida de cambio de un software es el de la telefonía movil. En menos de 10 años se convirtieron en un elemento imprescindible, tanto en lo laboral, como en lo personal. Actualmente viene dominado por dos gigantes de la industria, Apple (con su teléfono iPhone) y Google (con Android), ambos ofrecen sistemas de funcionalidades idénticas, y llevan años en una carrera de cambios, que en el fondo son semejantes en lado y en el otro. La diferenciación entre ambos no se da en los que hace sus sistemas, sino en que Apple ofrece una experiencia ligada a su hardware y a un ecosistemas de productos completo, y Google a se basa en una interconexión de multitud de servicios, independientes del hardware. Anualmente estas compañías presentan cambios y novedades a sus sistemas, y siguen vendiendo teléfonos manteniendo al mercado interesado.

En el lado contrario tememos a RiM, el creador de la BlackBerry. BlackBerry fue el primero en entrar en el mercado de los teléfonos inteligentes con un gran éxito, pero se conformaron con tener un nicho seguro dentro del mundo empresarial, y perdieron de vista los cambios en la sociedad que solicitaba tener al alcance de su mano una forma diferente de servicios y conectividad global. Cuando emergieron los IPhone y los Android Phone, que si supieron entender las necesidades de cambio, se quedaron estancados y terminaron por casi desaparecer del mercado.

Microsoft, en cambio fue el último en entrar en este mercado, si bien entendió las necesidades, no lo hizo en el momento adecuado, sino en uno en que ya no podía competir con los dos grandes ya establecidos. Motorola y Nokia se enfocaron en sacar un producto para cada sector consumidor según sus estudios de mercado, pero no comprendieron que si bien, una persona necesita un teléfono para trabajar, también lo va a necesitar para otras actividades, así que hicieron muchos teléfonos mediocres en lugar de pocos que resuelvan un amplio aspecto de necesidades. Estos fueron ejemplos de empresas que no supieron adaptarse al cambio de una manera adecuada.

Si vemos a las empresas que tuvieron éxito, observamos las constantes que hemos mencionado:


  • El negocio cambia, cambia frecuentemente, y la vigencia del producto viene definido por el cambio, y este debe estar sostenido un sistema software.
  • Los sistemas se parecen entre sí, el software tiene más semejanzas que diferencias.

Si obtenernos el porcentaje del código de un sistema que se asemeja a otro código, en comparación al que es exclusivo de nuestra aplicación, descubriremos que el código semejante es mucho mayor que el que no es.

El problema es que se invierte más tiempo y recursos en desarrollar las partes semejantes (por su volumen) que en desarrollar las partes exclusivas de un sistema, sin embargo las partes exclusivas de un sistema son las que le dan su identidad, con lo que debieran ser en las que se dedique más recursos y tiempo.

Para poder invertir los mencionados recursos y tiempo en el lugar adecuados, necesitamos una herramienta que nos ayude a generar las características comunes del sistema con el mínimo esfuerzo. La herramienta nos debe permitir escoger dichas características de un catálogo general común para una empresa, para un ámbito de negocio, o para un aspecto de nuestro software en particular e implementarla de forma automática en el sistema.

En base a esto se puede construir una línea de desarrollo de productos de software con un enfoque generativo.

martes, 23 de agosto de 2016

CapicuaGen: Desarrollo de software en la empresa, Parte I

Es un hecho que cualquier empresa, sea cual sea su tamaño, necesita un ambiente software adecuado que facilite su negocio, y le ayude en los cambios, constantes y rápidos que se dan en cualquier industria, más aun en la época de globalización e interconectividad en la que vivimos actualmente.

Los escenarios en los que se crean software empresarial son muy variados, vamos a enunciar principalmente tres de ellos:

Empresas con un departamento de desarrollo de software: En este escenario la empresa considero que es más factible para ella, tener un equipo que se dedique a construir el software que necesita en lugar de adquirirlo por medio de un ente externo. Este equipo puede tener más o menos madurez, además tener un tamaño variable.

Las ventajas de este enfoque, es que el equipo de desarrollo, tiene un solo “cliente” (la misma empresa) y debido a la cercanía, entre empresa y desarrollo, el conocimiento y las necesidades son más cercanas entre los unos y los otros, generalmente tiene un costo fijo al basarse principalmente en nóminas.

La desventaja es que no siempre se consigue la madurez necesaria para construir software lo suficientemente escalable para permitir al negocio crecer de manera adecuada. Frecuentemente se mantiene un mismo software durante años, haciéndole los mínimos cambios posibles, porque cada cambio tiene un gran impacto, haciendo sus sistemas difíciles de mantener. Al pasar del tiempo, es necesaria una restructuración completa del sistema software de la empresa, que muchas veces viene impulsara por cambios en el personal del mismo equipo de desarrollo.

Fábricas de software que son contratadas para tal efecto: En este enfoque la empresa contrata recursos externos para construir el software que necesite para para su negocio, puede ser para la creación de un producto, o otros eventos desarrollo y construcción en particular.

Las ventajas de este enfoque es no se debe invertir en recursos de construcción de una forma constante, solo cuando es necesario un desarrollo.

El problema es que posiblemente la fábrica tendrá más de un cliente, con lo que su atención hacia la empresa puede no ser la más adecuada, fases de análisis y diseño se pueden alargar en lo que la fábrica conoce las necesidades de la empresa y por ultimo cualquier cambio en los requisitos (que sin duda se darán en las revisiones de los productos) generada un costo adicional para la empresa.

Empresas de software que vende uno o varios productos: En este caso la empresa busca a otra empresa que venda o proporcione un producto adecuado a sus necesidades.

La ventaja de este enfoque es que generalmente se busca un producto que ya está realizado y construido, con lo que podría decirse que el problema se reduce a la puesta en producción de este.

La desventaja de este acercamiento, es que la empresa debe adaptarse al producto, y no lo deseable, que es que el producto se adapte a las necesidades de la empresa. En cualquier caso es muy posible que el software deba comunicarse con otros sistemas de la empresa, con lo que habrá que desarrollar una serie de interfaces para permitir la comunicación, perdiendo la ventaja de obtener un software completo y funcional desde el primer momento.

lunes, 11 de julio de 2016

Nuestras Redes sociales


Estoy actualizando las redes sociales del blog. Hace unas semanas que tenemos twitter, y recientemente abrimos un canal de Youtube para poder subir algunos videos y tutoriales.

sábado, 14 de mayo de 2016

Primera versión de CapicuaGen publicada


Acabo de publicar mi primera versión de CapicuaGen, el proyecto de mi máster en "Investigación en "Ingeniera de Software", la cual me ha tenido varios meses sin la posibilidad de publicar nada, y posiblemente me tenga algunos meses más debido a que estoy completando la memoria.

Pero no quería dejar pasar la oportunidad de anunciar la publicación del código fuente del proyecto, y de sus gemas.




CapicuaGen es un proyecto modular de generación de código, construido en Ruby, y de código libre, se puede obtener más información de la propuesta en:


Igualmente se puede obtener el código en:

  • CapicuaGen: Núcleo del generador de código.

https://rubygems.org/gems/CapicuaGen
https://github.com/jbautistamartin/CapicuaGen


  • CapicuaGenMelchior: Características comunes del generador.

https://rubygems.org/gems/CapicuaGenMelchior
https://github.com/jbautistamartin/CapicuaGenMelchior


  • CapicuaGenGaspar: Características para C#.

https://rubygems.org/gems/CapicuaGenGaspar
https://github.com/jbautistamartin/CapicuaGenGaspar


  • CapicuaGenBalthazar: Características para Android.

https://rubygems.org/gems/CapicuaGenBalthazar
https://github.com/jbautistamartin/CapicuaGenBalthazar


  • CapicuaGenEssential: Gema base que referencia a las anteriores para facilitar la instalación de un entorno funcional

https://rubygems.org/gems/CapicuaGenEssential
https://github.com/jbautistamartin/CapicuaGenEssential


La descripción publicada en GitHub, Sobre el generador es la siguiente:

CapicuaGen


CapicuaGen es un software que ayuda a la creación automática de sistemas empresariales a través de la definición y ensamblado de diversos generadores de características.CapicuaGenEssential agrega referencia a los generadores de características Melchior, Gaspar, Balthazar, con lo que es posible generar un ejemplo funcional completo.

El proyecto fue iniciado por José Luis Bautista Martin, el 6 de enero del 2016.

Puede modificar y distribuir este software, según le plazca, y usarlo para cualquier fin ya sea comercial, personal, educativo, o de cualquier índole, siempre y cuando incluya este mensaje, y se permita acceso el código fuente.

Este software es código libre, y se licencia bajo LGPL.

Para más información consultarhttp://www.gnu.org/licenses/lgpl.html

Instalación


Agregue la siguiente línea al archivo GemFile de tu aplicación

gem 'CapicuaGenEssential'
y ejecute:

$ bundle
O instálela manualmente con el siguiente comando

$ gem install CapicuaGenEssential

Uso


CapicuaGen permite comenzar a trabajar con él desde el mismo momento en que es instalado. Para obtener un ejemplo funcional simplemente ejecutamos el comando CapicuaGen con el parámetro example:

$ capicuagen example
Se crearan los siguientes archivos:

  • generator.rb: Ejemplo de un generador de codigo
  • GemFile: Archivo de configuración de depencias para bundler .
  • instnwnd.sql: Ejemplo de base de datos NorthWind, para Microsoft SQL Server

Revise el archivo generator.rb para tener una introducción a CapicuaGen.

Contribuir


Reporte de fallos y solicitudes de pull son bien recibidas en https://github.com/jbautistamartin/CapicuaGen

domingo, 6 de marzo de 2016

El problema de "No somos una empresa de software"


Todas las empresas usan software y en muchos casos necesitan software a medida que supla sus necesidades, posibiliten crecer a su negocio y las preparan para los cambios, que seguramente, requieran para mantenerse vigentes en el mercado.


Uno de los principales problemas es que generalmente no le dan la suficiente importancia al software como impulsor de su negocio, no invierten adecuadamente en su desarrollo y ni en su correcta integración  y uso, uno de los principales motivos es que "No son una empresa de software".

El tema es que ninguna empresa es una "empresa de software" como tal, en el sentido de que el software no es un producto final en sí mismo, sino que es un producto, que sirve para "algo",  para conseguir una seria de objetivos o suplir una serie de necesidades.

Si una empresa minimiza la necesidad del software que requiere, ya sea adquirido o desarrollado internamente,  su empresa tendrá problema, puesto que el software es una herramienta para "hacer" su trabajo y cumplir sus objetivos,  y esa es su única finalidad. Si no tiene el software adecuado, seguramente  será superada por otra empresa que si tenga el software necesario.

Muchas empresa tiene un pequeño departamento de desarrollo de software, generalmente integrado por un equipo sin una estructura clara, que resuelve problemas de una forma reactiva, y sin una planificación clara hacia el futuro, y mucho menos hacia el futuro del software y su sostenibilidad, no se invierte en elementos de programación, metodologías, y tecnologías actuales, porque consideran simplemente "que no es para ellos" y "no les hace falta", Al final ocurre un curioso efecto: En lugar de reflejar el software el negocio, el negocio acaba haciendo lo que el software "puede" hacer, limitándose cada vez más la operativa de la empresa. De allí viene la famosa frase "El sistema no me deja hacerlo", que muchas personas oyen perplejos ante peticiones aparentemente sencillas, acerca de sus necesidades, frente a vendedores, o personas de atención directa a clientes (y no hablamos de atención telefónica, donde el problema se agrava más).

Finalmente  dichas empresas deben comenzar un arduo camino, recorriendo los mismos pasos, uno a uno, que recorrió la ingeniera de software,  para poder llegar a resolver las autenticas necesidades que tiene. El problema es que la carga anterior que ya poseen hace ese cambio lento y pesado, y a veces condenado al fracaso.

Por eso es fundamental que las empresas nacientes, consideren el software como un elemento fundamental de su negocio, y aprovechen las tendencias y metodologías actuales de la ingeniera de software, cuya único propósito es construir software de manera más rápida, a menor costo y con mayor calidad, por que dichas tendencias y metodologías ya han recorrido el "arduo camino" mencionado previamente y no es necesario que nosotros lo volvamos a recorrer.