miércoles, 10 de septiembre de 2014

Mi primera aplicación Android en Google Play Store

Acaban de publicar mi primera aplicación implementada para móviles Android, es una aplicación sencilla que permite acceder en la web de compras ecológicas http://www.cerroviejo.org y guardar los datos de acceso, pero por algo hay que empezar:



Cerro Viejo en Google Play

lunes, 11 de agosto de 2014

Formato de filas alternativas en Hoja de Cálculo de Google Docs


Conseguir un formato de filas alternativas en las Hojas de Cálculo de Google Docs es bastante sencillo, aunque yo no encontré información al respecto y tuve que investigar un poco entre las funciones que proporciona. Entre ellas está ISEVEN(#VALOR), que comprueba si el número que se le pasa es PAR.

Para conseguir, por ejemplo, un color de fila alternativo, basta con seguir los siguientes pasos:
  1. Seleccionar las celdas o filas que queramos formatear.
  2. Seleccionar Color de Relleno -> Formato Condicional.
  3. El valor condicional debe ser:
    • La fórmula personalizada es:      =ISEVEN(ROW())
  4. Seleccionar formato de Texto y/o de Fondo para las filas pares.
Para hacer lo mismo, para filas impares, solo hay que negar la función anterior o sumarle 1 al número de fila: =ISEVEN(ROW()+1)



viernes, 13 de enero de 2012

Metodologías Ágiles, Ecosistema y Reciclaje de Software

Esta es una propuesta que pretende la modernización de los procesos de desarrollo a través de mejoras en partes importantes del desarrollo de software: la metodología y los sistemas de desarrollo.

Para modernización de metodologías propongo la implantación de una de las metodologías ágiles de desarrollo más conocida y utilizada en la actualidad: SCRUM; que además es compatible con las metodologías de calidad actuales (no las sustituye, las complementa).

Como mejora en los sistemas de desarrollo se propone la creación de un ecosistema de software completo que permita la mejora de la calidad y reciclaje de software.


Modernización de la metodología: Metodología y flujo de información ágil

Implantación de dos formas de trabajo que agilicen losdesarrollos:

Implantación de una metodología ágil tipo SCRUM,que puede ser incluida en las ofertas a clientes o pliegos, mejorando dichasofertas. Permite agilizar el desarrollo al separar diseño y construcción, y escompatible con las metodologías de calidad actuales (métrica, CMMI,…).

  • Es un proceso ágil e iterativo que nos ayuda a poner nuestro mayor esfuerzo en entregar el valor más importante de un producto en el tiempo más corto posible.
  • Nos permite enviar, inspeccionar y evaluar periódicamente software funcionando (cada 2-6 semanas aproximadamente).
  • El negocio determina las prioridades, los equipos se auto-administran para encontrar la mejor forma de encontrar las características más prioritarias.
  • Cada 30 días aproximadamente se puede ver software real que funciona y decidir si se entrega así o se sigue refinando en el siguiente ciclo.

Ventajas:

  • Fácil de explicar y entender.
  • Máximo valor por el esfuerzo.
  • Equipos auto-organizados, multi-aprendizaje.
  • Liberación de versiones totalmente funcionales, aunque con funcionalidad limitada, en cada iteración.
  • Orientación al cliente: lo involucra y le permite establecer prioridades.
  • Satisface al cliente con entregas tempranas y continuas de productos parcialmente funcionales.
  • Provee a la gerencia o dirección con un vistazo diario sobre el nivel de productividad y los factores que la afectan.
  • Mayor productividad en el desarrollo de software.
  • Permite producir software de forma regular, consistente y competitiva.
  • Útil en entornos con requisitos inestables, se aceptan requisitos cambiantes, incluso en etapas avanzadas.

La principal desventaja de esta metodología de trabajo esque si se aplica de forma estricta no es aplicable a grandes proyectos, sinembargo, esto se puede resolver dividiendo el desarrollo de aplicacionesgrandes en módulos y separando por equipos y aplicando la metodología por cada equipode desarrollo o/o módulo (sería un SCRUM Modular).

Posteriormente se puede aplicar la metodología ágil en unnivel superior (que podría estar integrado por los analistas o los analistasprogramadores principales de cada grupo) por el cual se realice la comunicacióncon los clientes a través de las reuniones o conferencias que se aplican enesta metodología (SCRUM Jerarquizado).

La potencia de esta metodología se encuentra en laflexibilidad con la que se puede llevar a cabo según interese en cada proyecto,no hay que seguirla de manera estricta.


Modernización de los procesos: Ecosistema de desarrollo y de reciclaje deSoftware

Trataría en realizar la implantación de un ecosistema desoftware completo, en la cual se disponga de algunas de lasherramientas que la integran como son artifactory, jira o HGC, la Wiki…

Existe un grupo de google que habla acerca de este tema: http://groups.google.com/group/ecosistemas-software

Un ecosistema de desarrollo de software (developmentecosystem) es un espacio de trabajo en el que conviven una serie deherramientas que permiten a un equipo de desarrollo modelar una metodología detrabajo que les ayude a ser más eficientes. Un ecosistema de desarrollo desoftware:

-         Facilita la integración continua.
-         Facilita la automatización.

Algunas de las herramientas que pueden ayudar a tal fin sonlas siguientes:

-     Maven: Herramienta de gestión de proyectos desoftware y herramienta de comprensión y gestión de dependencias entrelibrerías. Sería interesante definir arquetipos o plantillas de integración delos proyectos en los repositorios
-     Apache Continuum:Servidor de integración continua, integrable con repositorios de código.Pruebas de calidad y de consistencia.
-     Hudson: Otroservidor, este extensible, para integración continua.
-     Sonar:Plataforma de medición de calidad del código.
-     OpenFire y/opandion: Proporcionan herramientas de servidor y cliente para colaboraciónen tiempo real (Servicios de mensajería corporativa).
-      JUnit: Testeo unitario de aplicaciones.
-      Apache JMeter: Herramienta de prueba de carga, pruebasunitarias o monitoreo.
-      Apache Archiva o artifactory: Repositorios deMaven y Maven2, gestión de dependencias, hace de proxy caché de un repositoriopropio con otros existentes. Habría que integrarlo con el resto de herramientas y utilizarlo como base enel reciclaje de software desarrollado en la empresa, ya sean utilidades(validaciones java por ejemplo), módulos extensibles  (por ejemplo, módulos configurables de integracióncon repositorios LDAP) o productos.
-      Jira o trac: Sistemasde gestión de tareas e incidencias.
-      Wiki: Sitio web cuyas páginas pueden sereditadas rápidamente por múltiples usuarios, donde gestionar la información delos proyecto, utilidades, módulos y productos de la empresa.
-     Repositorio Subversion o GIT: Sistema de control deversiones que mejora el desarrollo colaborativo.


Mejoras de la solución conjunta:

-      Aumenta la productividad y se reduce el tiempo de losdesarrollos:
o       Segúnla metodología SCRUM los desarrollos se pueden empezar en paralelo con eldiseño.
o       Mayorreutilización de código (reciclaje), componentes, soluciones y/o productos quepueden ser compartidos en el Artifactory y documentados en WIKI corporativa.

-      Mejora de la calidad del software: El uso deherramientas de pruebas unitarias JUNIT no es obligatorio, por eso laintegración con herramientas como Sonar puede permitir la evaluación de lacalidad de cada proyecto integrado en artifactory.

-      Mayor grado de implicación y satisfacción del cliente:
o       Mejorael conocimiento del cliente sobre la evolución del proyecto.
o       Elcliente puede ver como evoluciona su producto y hacer pequeñas rectificacionessobre la marcha.

-      Fiabilidad, estabilidad y escalabilidad: se detectanerrores con mayor antelación a lo largo de las distintas etapas de desarrollo,por lo que el producto será mucho mejor y se acercará más a las necesidades delcliente, que haciendo una única entrega al final.

-      Fomenta la colaboración para el desarrollo/evolución de productos quepueden ser vendidos bajo  licencia en el mercado actual o abriendo mercado enotros sitios (si un proyecto es innovador, es más fácil convertirlo enproducto).

lunes, 9 de noviembre de 2009

Nuevas funcionalidades incluidas en Java 6

Voy a hacer un poco de autoaprendizaje, y voy a empezar por la parte principal de mi trabajo (siendo analista j2ee no puede ser otro que el lenguaje Java). Este el primero de lo que espero sea una indeterminada y larga lista de artículos de programación centradas en los entornos de programación basados en Java.

Creo que me había quedado un poco obsoleto y estancado en la versión 5 de este lenguaje, así que decidí dar un paso más y estudiar la versión de Java que se está utilizando ahora mismo en el panorama empresarial: Java 6, o  JDK 1.6 (del JSR 270).

Lo primero sería estudiar las diferencias con la versión anterior, aquí listo las mejoras que proporciona Java 6 con respecto a su anterior versión:

CAMBIOS EN EL CORE
  • Inclusión de motores de scripting: Se incluye el motor de Javascript  Rhino desarrollado por Mozilla.
  • Firma Digital XML (JSR 105): Sin necesidad de utilizar librerías externas (javax.xml.crypto). Esto viene muy bien para firmar peticiones SOAP.
  • API de compilación Java: Permitiría generar código automático en memoria, sin necesidad de fuentes. Esto pienso nos daría mucho juego, tiene muchas posibilidades (tengo que ver si se puede utilizar junto con el API Reflection), permitiendo generar clases dinámicas dependiendo de factores externos como, por ejemplo, datos de configuración o una bade de datos.
  • Procesamiento de anotaciones: Ahora siguiendo el JSR 269 en vez de la JSR 175 de la version 5, se estandariza el procesamiento de dichas anotaciones. Para procesar anotaciones únicamente hay que extender de la clase AbstractProccesor (indicando las anotaciones a capturar) y sobreescribir el método process.
  • Depurador en tiempo de ejecución: Se puede iniciar depuración en tiempo de ejecución, almacenando dentro de las clases compiladas más información que la que se almacenaba anteriormente. Para aplicaciones móviles JME CLDC, esto permite que éstas se ejecuten más rápidamente.
  • Nueva clase ServiceLoader: Permite estandarizar la creación de servicios de proveedores externos, realiza una búsqueda de la implementación de un servicio de forma más sencilla. Hay que indicar la clase que se quiere en el META-INF/services/{paquete.interfaz}. Se puede utilizar como una factoría para una interfaz dada que pueda tener una o varias implementaciones.
  • Colecciones Deque y BlockingDeque: Permiten crear colas doblemente enlazadas (permiten insertar datos al principio o al final). La implementación de la interfaz Deque es ArrayDeque, al cual no se accede a través de su índice. La inserción y obtención tiene un coste menor al de un ArrayList, a no ser que se necesite realizar búsquedas por índice. BlockingDeke, además, da soporte al bloqueo de operaciones de inserción y obtención.
  • Mejoras ordenamiento de colecciones Set y Map: Permitiendo realizar búsquedas bidireccionales y a partir o hasta un elemento dado si los elementos están ordenados (interfaces NavigableSet y NavigableMap).
  • Nueva clase java.io.Console: Permite leer contraseñas sin que se muestre en la pantalla.
  • Inclusión de Base de datos Derby JavaDB.
  • Modificación en la clase File para conocer el espacio en disco y poder cambiar sus atributos.
  • Mejoras en la concurrencia (JSR 166).
  • Inclusión del programa JConsole para monitorización de rendimiento de forma gráfica.
  • Incorporación de un pequeño servidor HTTP.
  • Implementación del manejador de cookies.
  • Internacionalización de los nombre de dominio IDN.
CAMBIOS ORIENTADOS AL CLIENTE
  • Acceso a las aplicaciones nativas.
  • Pantallas Splash.
  • Soporte barra de tareas del sistema.
  • Ordenamiento y filtrado de tablas.
  • SwingWorker.
CAMBIOS ORIENTADOS AL SERVIDOR
  • JDBC versión 4.0.
  • Procesamiento de XML usando StAX.
  • Anotaciones para Servicio Web.
  • Simplificación del mapeo Objeto/XML utilizando JABX 2.0.
  • Simplificación de la exposición de Servicios Web y la creación de clientes usando JAX-WS 2.0.
  • Estandarización de anotaciones comunes.
Son bastantes mejoras y cambios, sin embargo no tan significativos como los que se introdujeron con la versión Java 5 con respecto a su predecesora Java 1.4.

martes, 18 de noviembre de 2008

ConfiguratorPattern

OBJETIVO

En todos las aplicaciones hay funcionalidades básicas e imprescindibles que tienen su mayor defecto la dispersión (funcionalidades no agrupadas que se utilizan en todas partes, en todos los módulos funcionales): trazas, control de excepciones, configuración, multilenguaje...

En este artículo vamos a hacer hincapié en la configuración de una aplicación, que es la base de todo producto, y el mayor problema a la hora de desplegar en diferentes máquinas (quitando problemas de infraestructura) y de administrar versiones según el entorno de destino.

Vamos a intentar plantear un patrón de configuración (ConfiguratorPattern), basado en Java, utilizando buenas prácticas y la experiencia adquirida a lo largo de los años.

Como objetivos voy a intentar que se cumplan los siguientes:
  1. Acceso a cualquier variable de configuración de forma rápida y centralizada.
  2. Permitir el cacheo de la configuración en memoria, para un acceso más rápido.
  3. Permitir el refresco de dicha caché dado un tiempo determinado.
  4. Permitir la instalación y actualización de la aplicación de una manera rápida y lo más independiente del entorno posible.
  5. Impedir que cualquier cambio que se realice en el módulo de configuración pueda afectar al resto de código en el que se encuentra dispersa esta funcionalidad.
     - Estos objetivos implican reducción del acoplamiento y aumento de la cohesión interna del componente -

La configuración de cualquier aplicación basada en tecnología Java puede ser homogenea o heterogenea, es decir, puede estar basada en el mismo soporte (por ejemplo, un fichero xml) o en varios soportes de diferente naturaleza (ficheros de texto o properties, xml o una tabla en base de datos).

Echando a un lado aquellos módulos predefinidos que tienen una forma de generar su configuración de una manera predefinida (por ejemplo, log4j.properties o log4j.xml en trazas de log4j), se debe intentar que el resto de configuración propia del proyecto sea lo más homogenea posible, utilizando siempre el mismo soporte, esto quiere decir utilizar siempre ficheros de propiedades, un fichero xml o una tabla en base de datos.


IMPLEMENTACIÓN

Para cumplir los objetivos que nos hemos impuesto necesitamos una clase como la siguiente:

Datos de configuración obligatorios:
  • allowRefresh: true o false indicando si se debe autorefrescar la configuración
  • refreshTime: Número de minutos entre cada refresco (se actualizará cuando se llame la próxima vez a cualquier variable de configuración)

public final class Configurator {
 // ~ Campos estáticos / Constantes //
 // ------------------------------------------
 private static Map<String, Object> propertiesMap = new HashMap<>();
 private static long refreshTime = 60;
 // En minutos, por defecto una hora
 private static long lastRefreshTime = 0;
 private static boolean allowRefresh = false;

 static { // Se puede inicializar estaticamente o desde alguna clase o listener
  try {
   initialize();
  } catch (Exception ignored) {
  }
 }

 // ~ Métodos //
 // ----------------------------------------------------------------
 /**
  * * Comprueba si es necesario actualizar la configuracion *
  * 
  * @throws ConfigurationException
  */
 private static void refreshConfiguration() throws Exception {
  long currentTime = System.currentTimeMillis();
  if (allowRefresh) {
   if (currentTime > (refreshTime + lastRefreshTime)) {
    initialize();
   }
  }
 }

 /**
  * * Obtiene un subconjunto de propiedades dado un patrón de inicio Por *
  * ejemplo ('animales'): animales.leon animales.cabra animales.camaleon *
  * * @param key * @param pattern * * @return ArrayList * @throws
  * ConfigurationException
  */
 public static List getFilterKeySet(String key, String pattern) {
  List res = new ArrayList();
  try {
   refreshConfiguration();
   if (!pattern.endsWith(".")) {
    pattern = pattern + ".";
   }
   Set keys = ((Map) propertiesMap.get(key)).keySet();
   Iterator e = keys.iterator();
   while (e.hasNext()) {
    String akey = (String) e.next();
    if (akey.startsWith(pattern)) {
     res.add(akey);
    }
   }
  } catch (Exception e) {
   res = new ArrayList();
  }
  return res;
 }

 /**
  * Obtiene un parámetro de configuración del sistema como cadena *
  * @param group 
  * @param key 
  * @return String
  */
 public static String getPropertyAsString(String group, String key) {
  String value = null;
  refreshConfiguration();
  value = (String) ((Map) propertiesMap.get(group)).get(key);
  return value;
 }
 
 /**
  * Obtiene un parámetro de configuración del sistema como [TIPO], * , las
  * que se necesiten de este tipo u otro * * @param group * @param key *
  * @return [TIPO]
  */
 public static TIPO getPropertyAsTIPO(String group, String key){
  TIPO value = null;
  refreshConfiguration();
  value = new TIPO(((Map)propertiesMap.get(group)).get(key).toString());
  return value;
 }

 /** * Inicialización de la configuración de la aplicación */ 
 public static void initialize() throws Exception {
  try {    
   propertiesMap = new HashMap();    
   //CARGAR LOS DATOS DE CONFIGURACIÓN, desde la fuente de datos,    
   // y utilizando un mapa doble y agrupando por grupo    
   while (hayElementos) { 
    propertiesMap.add [....]   ;
   }    
   lastRefreshTime = System.currentTimeMillis();
  } catch (Exception e) {    
    System.out.println("Error al cargar la configuración de la aplicación: " + e);   
    throw e;  
  } 
 }
}


Se aconseja utilizar como soporte de la configuración una tabla en base de datos (la conexión se debe configurar por jndi utilizando la configuración del servidor de aplicaciones: pool de conexiones gestionado por contenedor), de este tipo:

CONFIGURACION (GRUPO, VARIABLE, VALOR, DESCRIPCION) FK (GRUPO, VARIABLE);

De esta forma, en cada entorno con su propia base de datos se podrá desplegar y redesplegar la aplicación las veces que se requieran sin tener que modificar la configuración en dicho entorno (únicamente la primera instalación y breves cambios). Esto viene muy bien si se trata de un producto en continuo desarrollo y se pueden tener diferentes versiones en diferentes clientes.

Hay muchos posibles variantes para este patrón:
  • Utilizando el patrón Factory para crear y obtener la instancia.
  • Utilizando el patrón Singleton en vez de una clase estática.
  • Añadiendo cuantas funciones se necesiten.
  • Cualquiera que no afecte al rendimiento ni la eficiencia de esta funcionalidad.
  • Cargando a la vez las variables allowRefresh y refreshTime desde configuración y actualizando.

Imágenes Dockers

Estoy aprendiendo bastante sobre el tema de docker y docker swarm , gestión de Stacks, Servicios, Containers, Volumenes, .. y sus configurac...