Archivo de la categoría: Ingeniería de Software

Explorando la metodología DWDP+1 parte I

Introducción

Más de alguno se estará preguntando ¡que diablos es la metodología DWDP+1 en inglés o DRDP en español!, pues la siglas vienen de Draw – Write – Draw – Prototype o en español Dibuja – Redacta/Escribe – Dibuja – Prototipa, posteriormente en el detalle explicaré de dónde viene el +1.

Esta metodología nace de la necesidad de poder llegar a una forma de trabajo que sea sencilla y práctica de poder levantar y detallar las primeras etapas de construcción de un software, sin complejizar demasiado el proceso.  Principalmente aquellas etapas que tienen que ver con la Ingeniería de Requerimientos o Requisitos, antes de entrar de lleno al diseño y construcción del software, lo anterior mirado desde una perspectiva ágil de desarrollo del software.

Hagamos un poco de historia

Con el transcurso de los años se han desarrollado recursos que conforman la ingeniería del software, es decir, herramientas y técnicas de especificación, diseño e implementación del software: la programación estructurada, la programación orientada a objetos, las herramientas CASE, la documentación, los estándares, CORBA, los servicios web, el lenguaje UML, etc.

En combinación con las herramientas, también se han hecho esfuerzos por incorporar los métodos formales al desarrollo de software, argumentando que si se probaba formalmente que los productos software hacían lo que se les requería, la industria del software sería tan predecible como lo son otras ramas de la ingeniería.

En general la ingeniería del software consiste en:

  • Proceso de desarrollo de software (especificación, implementación y diseño, etc…).
  • Metodologías para el desarrollo de software (RUP, patrones, framework…).
  • Herramientas de desarrollo de software.

Hay cuatro actividades fundamentales comunes a todo proceso software:

  • Especificación: usuarios e ingenieros definen el software a producir y las restricciones en su funcionalidad.
  • Desarrollo: fase en la cual el software se diseña y se programa.
  • Validación: el software debe ser probado para asegurar que cumple con las necesidades del cliente.
  • Evolución: el software debe poder ser modificado para adaptarse a cambios en el mercado y en las necesidades de los usuarios.

A mi me gustaría centrarme en la primera actividad fundamental: la especificación, pero con un enfoque más holístico que incorpore algunas técnicas de la Ingeniería de Requerimientos, no perdiendo el foco ágil.

Las metodologías actuales y el auge de la agilidad

Todas las metodologías ágiles coinciden en que un producto debe construirse de forma evolutiva en pequeñas entregas. Y aunque esto no es suficiente, sino que debemos hacerlo de forma criteriosa para que cada entrega pueda aportar valor suficiente a los usuarios finales. Esos grupos de características se denominan MMF: Minimum Marketable Features, y pueden definirse como “el conjunto más pequeño posible de funcionalidad que, por si misma, tiene valor en el mercado”.

Cuando nosotros nos acercamos al cliente, asumimos que él sabe exactamente qué quiere hacer (What?)  y nosotros le damos el cómo (How?). Sin embargo, esto no es así y nuestro trabajo se convierte en algo así como adivinar el futuro con una bola de cristal.

Todas las metodologías ágiles que he consultado e intentado aplicar (Scrum, xP), se basan en el hecho de que los implicados son “relativamente profesionales” y están muy orientados a resultados, con altas capacitaciones en sus campos. Cuando intentas llevar esto a la realidad práctica, los clientes no saben qué quieren, no están dispuestos a formalizar sus peticiones en algo parecido a un informe de requerimientos (porque el tiempo apremia), los programadores que trabajan para ti pueden ser lentos y tener una capacidad de adaptación baja, con lo cual los temas se eternizan (aunque no en todos los casos, no quiero generalizar).

En resumen, al final cada uno debe resolver el problema con lo que tenga a su alcance (quizá un buen analista funcional o un comercial especialmente preparado para “adivinar” las necesidades de los clientes).  Creo que muchos al leer esto se sentirán identificados con parte del problema.

El auge de las metodologías ágiles y las herramientas nuevas que aparecen (con mucha frecuencia) creo que tienden un poco a nublar la visión de los gestores de proyecto, porque a veces no consultan la fuente de la información y se arma un lío gigante que es complicado de desenmarañar, campo que ha sido cultivo para que muchos “coaches” vean esto como una oportunidad de negocio para emprender (lo que encuentro genial!).  Cuando la base de todo esto se encuentra en la filosofía especificada en el Manifiesto Ágil, y que creo muchas personas debiésemos retomar de vez en cuando.  En resumen el manifiesto ágil dice:

  1. Las personas (individuos) e interacciones entre los individuos están POR SOBRE los procesos y las herramientas

  2. Software funcionando POR SOBRE documentación extensiva

  3. Colaboración con el cliente POR SOBRE la negociación de un contrato

  4. Responder a los cambios ANTES que seguir un plan (punto cuestionable de acuerdo a algunos dinosaurios del PMP)

Sobre la base de este manifiesto se crearon los 12 principios de agilidad para el desarrollo de software.  Sin embargo no deseo entrar tanto en detalle para concentrarme de lleno en explicar el problema y el porqué creo que esta metodología que he credo puede aportar en la “etapa de análisis” de las metodologías ágiles u otras más tradicionales.

El problema

“Cuando nosotros nos acercamos al cliente, asumimos que él sabe exactamente qué quiere hacer y nosotros le damos el cómo. Sin embargo, esto no es así y nuestro trabajo se convierte en algo así como adivinar el futuro con una bola de cristal.”.

¿Cómo enfrentar desde la perspectiva ágil el hecho de que sigue siendo importante poder obtener con antelación una validación de los requerimientos del cliente antes de que el producto salga al mercado? teniendo en mente que el objetivo es evitar por todos los frentes posibles que nos transformemos en verdaderos adivinos con una bola de cristal.

Sabemos por ejemplo que de acuerdo a SCRUM, la validación que hace el cliente (product owner) de la pila de requisitos (backlog desde ahora en adelante) no la podrá obtener sino hasta que se construya el primer incremento (potentially shippable product), es decir, hasta que pueda obtener una versión funcional del producto (testeable).  Sin embargo también sabemos que el Product Owner (PO desde ahora en adelante) es un agente partícipe activo del Sprint Planning, área que puede usarse para obtener con antelación una validación de este mismo stakeholder (involucrado).

Desde las primeras etapas del proceso de SCRUM cuando se comienza a recopilar la pila del producto (backlog), la única inferencia que el PO tiene en dicha pila es: para ordenar las historias de usuario.

Luego de armar las características de las historias especificadas con el comportamiento deseado desde la perspectiva del usuario, el PO no tiene inferencia hasta la etapa de planificación del sprint, donde básicamente se define:

  1. el What?
  2. el How?

y con lo anterior se genera el Sprint Backlog.

Luego durante 10 o 15 días (configurable de acuerdo al proyecto y las necesidades del PO), se comienza el desarrollo del primer sprint, y ya nos desconectamos completamente de la validación que podría hacer el PO sino hasta la entrega del incremento funcional.  De acuerdo a mi perspectiva la pregunta inicial planteada a modo de hipótesis sigue siendo:

¿Cómo enfrentar desde la perspectiva ágil el hecho de que sigue siendo importante poder obtener con antelación una validación de los requerimientos del cliente (PO) antes de que el producto salga al mercado?

Para poner más claro el problema me gustaría compartir con ustedes una discusión entre Zach Bonaker, agile coach de Willis Towers Watson y Jaya Shrivastava, coach de AGILE++ Engineering.  Obviamente personas que saben mucho más que yo.

Destaqué en rojo los temas que creo relevantes para el problema en cuestión.  Fuente: https://www.scrumalliance.org/community/articles/2014/august/why-definition-of-minimum-marketable-feature%E2%80%9D-is-a

La traducción es:

Zack:

Un equipo que desarrolla historias que resultan en un software que no se puede usar o que no tiene utilidad no es un fallo de una “definición de característica comercial mínima” (MMF). Es debido a un backlog muy pobre, probablemente el resultado de prácticas ágiles fallidas en las etapas iniciales donde el equipo planeó realmente el sprint.

Jaya:

Sí, cada iteración produce algo valioso, pero ¿los clientes lo usan?

En el mundo real, la respuesta es un rotundo NO. Los clientes no están dispuestos a asignar recursos para probar o liberar lo que se produce al final de los sprints.

En su lugar, los clientes están dispuestos a tomar incrementos que creen que pueden ser liberados al mercado.

Esto falta ya que no trabajamos lo necesario para poder liberar una característica mínima que sea comercializable.

Vaya problema…

El asunto importante es que si llegásemos a poder tener una validación inicial antes de la entrega del incremento funcional, podríamos disminuir un riesgo importante: que es justamente que el producto llegue defectuoso al mercado.

En una próxima entrega iré desmenuzando la solución (de acuerdo a mi visión) que adopté a través de la creación de esta metodología DWDP+1, que busca ir en apoyo de una definición más concreta y sencilla de requerimientos antes de entrar a las etapas de construcción.

Cualquier aporte es siempre bienvenido, sobre todo para corregir algunos temas principalmente relacionados con el mundo ágil.

Nos vemos en la siguiente entrega y buena lectura!

Deja un comentario

Archivado bajo CMMI, Desarrollo de Software, Ingeniería de Software

Estimación de proyectos de software: cálculo usando el método PROBE (PROxy Based Estimation)

La estimación de proyectos software es una tarea muy compleja, pero de vital importancia en toda la etapa de desarrollo del software.

Algunos de los principios a tener en cuenta para la realización de una estimación de software:

  • Retrasar la estimación lo máximo posible. Cuanto más se retrase, más precisa será.
  • Hacer estimación por analogía. Utilizar el costo de proyectos similares.
  • Ley de Parkinson. El trabajo se extiende para rellenar el tiempo disponible.
  • Precio para ganar. El coste se estima en todo el dinero que el cliente puede gastar en el proyecto.
  • Existen técnicas de descomposición. Estimas el costo descomponiendo el producto y/o el proceso.
  • Existen modelos empíricos. Modelos de regresión que relacionan esfuerzo con tamaño o funcionalidad.

Factores importantes a considerar:

  • Complejidad del proyecto.
  • Tamaño del proyecto.
  • Estabilidad de los requerimientos.
  • Facilidad de identificar funciones.
  • Estructura de la información.
  • Disponibilidad de información histórica.

El método PROBE

Este método está descrito en el libro PSP A Self-Improvement Process for Software Engineers, aunque es un poco complicado de seguir, por eso que mejor hacer un trabajo más práctico para tratar de enfocar el aprendizaje haciendo, más que diciendo.

Un proxy es una unidad de software que se puede identificar en un proyecto. Ejemplos de ello son las pantallas (User Interfaces), archivos, objetos, entidades lógicas, funciones (Stores Procedures) y puntos de función. La representación se pueden visualizar fácilmente a partir de las especificaciones del proyecto tales como documentos de requisitos. A continuación, se pueden traducir en líneas de código en función de los tamaños de los proxies históricos similares en proyectos de desarrollo anteriores. La líneas de código junto con cifras de productividad se pueden utilizar para predecir los recursos necesarios para un proyecto.

El método completo está organizado en una planilla Excel de construcción propia:

2016-11-09_16-40-40

Proxy’s

En esta Hoja de Trabajo se establecen las estimaciones por Proxy, y a partir de la estimación de los tiempos de construcción se estiman los de las otras fases del desarrollo. Si estas estimaciones porcentuales no aplican para el caso específico, pueden reemplazarse por valores históricos (en caso de contar con ellos).

La distribución de los porcentajes de referencia va a depender de la metodología o del criterio utilizado por los evaluadores del proyecto.

¿Cómo determinar la cantidad de días de construcción?

Este es el dato que mejor se puede estimar por los expertos o por consenso. A partir de este valor se calculan los otros de acuerdo a los porcentajes de referencia.  Son los desarrolladores (expertos) los que mejor saben cuánto se demorar en construir un proxy.  De todas formas existen tablas de complejidad de referencia por lenguaje de programación que pueden utilizarse, aunque en la práctica es mucho mejor el juicio experto.

2016-11-09_17-01-40

Estimación

En esta hoja, se desglosan las funcionalidades en los proxys definidos en la etapa anterior. Las columnas en azul son el resultado de la ponderación de la cantidad de Proxys requeridos por su tiempo definido en la hoja ‘Proxy’.

Para cada funcionalidad del sistema se especifican la cantidad de proxy’s a desarrollar, por ejemplo en el caso de la funcionalidad “Login”, se requiere 1 página web sencilla, 1 mediana, 1 procedimiento almacenado (en BBDD), 1 clase mediana y 1 tabla.  Lo anterior solo para efectos del ejemplo.

Sobre esta base la planilla va calculando la cantidad de días de análisis, construcción, integración y pruebas (para efectos del ejemplo) que se requieren en este proyecto.  Las etapas por supuesto pueden ser personalizadas por el evaluador.

Aplicaciones para otras áreas que no sean de construcción de piezas de software

Cualquiera donde sea factible definir y estructurar vía proxys.  Solo basta usar un poco la imaginación.

Link a planilla de ejemplo:

https://drive.google.com/file/d/0B3-y5EFvrO7ec3drWlJhZmhfaUk/view

Referencia:

http://www.sei.cmu.edu/reports/06tn017.pdf

Método y proceso implementado con éxito en una empresa de desarrollo de software de Santiago de Chile.  https://drive.google.com/file/d/0B3-y5EFvrO7eeEdJVzlTWEdkczQ/view

Deja un comentario

Archivado bajo Gerencia de Proyectos, Ingeniería de Software

La ingeniería detrás de Uber (Parte II). The Foundation

La misión de Uber es ser tan fiables como el transporte de agua corriente, en todas partes, para todo el mundo. Para hacer esto posible, creamos y trabajamos con datos complejos. Luego agrupamos muy ordenadamente la plataforma que permite a los conductores poder conseguir que las empresas y los pilotos se desplacen.

Capturas de pantalla que muestran la aplicación piloto de Uber en Nueva York, China e India para la primavera de 2016.

Capturas de pantalla que muestran la aplicación piloto de Uber en Nueva York, China e India para la primavera de 2016.

Si bien queremos que la interfaz de usuario de Uber sea simple, diseñamos sistemas complejos detrás de él para mantenerse, manejamos interacciones difíciles, y servimos grandes cantidades de tráfico de datos. (Principio KISS)

Hemos roto la arquitectura monolítica original en muchas partes a escala con el crecimiento. Con cientos de microservicios que dependen el uno del otro, dibujando un diagrama de cómo funciona Uber en este momento es tremendamente complicado, y todo cambia rápidamente. Lo que se puede cubrir en un artículo de dos partes es la pila que se utilizó para la primavera de 2016.

Desafíos de la Ingeniería de Uber: No hay usuarios gratuitos, Hyper crecimiento

Tenemos los mismos problemas de escala global como algunas de las compañías de software más exitosas, pero 1) estamos a sólo seis años de edad, por lo que no las hemos resuelto todavía, y 2) Nuestro negocio está basado en el mundo físico en tiempo real.

En abril de 2015, 300 ciudades operativas de Uber estaban dispersos por todo el mapa.

En abril de 2015, 300 ciudades operativas de Uber estaban dispersos por todo el mapa.

A diferencia de los servicios freemium, Uber tiene solo los usuarios transaccionales: pilotos, controladores y ahora los comedores y los mensajeros. La gente confía en nuestra tecnología para poder hacer dinero, ir a donde tienen que ir, así que no hay tiempo para hacer una pausa. Damos prioridad a la disponibilidad y escalabilidad.

A medida que nos ampliamos en las carreteras, nuestro servicio debe escalar. La flexibilidad de nuestra pila fomenta la competencia por lo que las mejores ideas pueden ganar. Estas ideas no son necesariamente únicas. Si existe una herramienta fuerte, la usamos hasta que nuestras necesidades exceden sus capacidades. Cuando necesitamos algo más, construimos soluciones internas. La Ingeniería de Uber ha respondido al crecimiento con gran capacidad de adaptación, la creatividad y la disciplina en el último año. Para el 2016, tenemos planes aún más grandes. En el momento en que usted lea esto, mucho habrá cambiado, pero esto es una instantánea de lo que estamos usando ahora. A través de nuestras descripciones, esperamos demostrar nuestra filosofía entorno al uso de herramientas y tecnologías.

El Stack Tecnológico de Uber

En lugar de una torre de restricciones, como la imagen de un árbol. En cuanto a las tecnologías en Uber, se ve una pila común (como un tronco de árbol) con énfasis diferentes para cada equipo o en la oficina de ingeniería (sus ramas). Es todo hecho de la misma materia, pero las herramientas y servicios florecen de manera diferente en diferentes áreas.

botswana_baobab-768x477

En pocas palabras: La plataforma

Este primer artículo se centra en la plataforma de Uber, es decir, todo lo que le da el poder más grande a la organización de la ingeniería de Uber, equipos de plataforma crean y mantienen las cosas que permiten a los ingenieros para posteriormente construir otros programas, funciones, y las aplicaciones que se utilizan.

Infraestructura y almacenamiento

Nuestro negocio se ejecuta en un modelo de nube híbrida, usando una mezcla de proveedores de la nube y múltiples centros de datos activos. Si un centro de datos falla, viajes (y todos los servicios asociados con viajes) conmutación por error a otro. Asignamos ciudades para el centro de datos más cercano geográficamente, pero cada ciudad se copian en un centro de datos diferente en otra ubicación. Esto significa que todos nuestros centros de datos son los viajes en todos los tiempos de funcionamiento; no tenemos noción de un centro de datos como “copia de seguridad”. Para la provisión de esta infraestructura, se utiliza una mezcla de herramientas internas y Terraform.

Las nubes híbridas combinan los modelos de nubes públicas y privadas. Un usuario es propietario de unas partes y comparte otras, aunque de una manera controlada. Las nubes híbridas ofrecen la promesa del escalado, aprovisionada externamente, a demanda, pero añaden la complejidad de determinar cómo distribuir las aplicaciones a través de estos ambientes diferentes. Las empresas pueden sentir cierta atracción por la promesa de una nube híbrida, pero esta opción, al menos inicialmente, estará probablemente reservada a aplicaciones simples sin condicionantes, que no requieran de ninguna sincronización o necesiten bases de datos complejas. Se unen mediante la tecnología, pues permiten enviar datos o aplicaciones entre ellas. Un ejemplo son los sistemas de correo electrónico empresarial.  https://es.wikipedia.org/wiki/Computaci%C3%B3n_en_la_nube

Nuestras necesidades de almacenamiento han cambiado con el crecimiento. Un ejemplo sencillo de Postgres nos llevó a través de nuestra infancia, pero a medida que fue creciendo tan rápidamente, fue necesario aumentar el tiempo de almacenamiento en disco y la disminución de respuesta del sistema disponibles.

Al final del verano de 2014, Proyecto Mezzanine rediseñado el sistema para que coincida con la arquitectura de alto nivel.

Al final del verano de 2014, Proyecto Mezzanine rediseñando el sistema para que coincida con la arquitectura de alto nivel.

Actualmente usamos un modelo sin esquema (construido in-house en la parte superior del stack de MySQL), Riak, y Cassandra. Sin esquema es para el almacenamiento de datos a largo plazo; Riak y Cassandra se reúnen como plataforma de alta disponibilidad, y las demandas de baja latencia. Con el tiempo, las instancias sin esquema reemplazaron instancias individuales de MySQL y Postgres, y Cassandra reemplazó a Riak debido a la velocidad y el rendimiento. Para el almacenamiento y análisis de datos complejos distribuidos, utilizamos un almacén Hadoop. Más allá de estas bases de datos, nuestros ingenieros de Seattle se centran en la construcción de una nueva plataforma de datos en tiempo real.

Utilizamos Redis tanto para el almacenamiento en caché y la puesta en cola. Twemproxy ofrece escalabilidad de la capa de almacenamiento en caché sin sacrificar la tasa de aciertos de caché a través de su algoritmo de hash coherente.

Logging

Nuestros servicios interactúan entre sí y con los dispositivos móviles, y esas interacciones son valiosas para usos internos como la depuración, así como los casos de negocios como precios dinámicos. Para el registro, utilizamos varios clústeres Kafka, y los datos se archivan en Hadoop y/o en un servicio web de almacenamiento de archivos antes de que caduque Kafka. Estos datos también se ingiere en tiempo real por los diversos servicios e indexados en una pila ELK para la búsqueda y visualización (ELK significa Elasticsearch, Logstash, y Kibana).

App Provisioning

Utilizamos contenedores Docker sobre Mesos para hacer funcionar nuestros microservicios con configuraciones consistentes de manera evolutiva, con la ayuda de Aurora para los servicios de larga duración y los trabajos de cron. Uno de nuestros equipos de infraestructura, la plataforma de aplicaciones, produjo una biblioteca de plantillas que se basa en los servicios de imágenes fáciles de enviar y acoplables.

Routing and Service Discovery

Nuestra arquitectura orientada al servicio (SOA) hace que el descubrimiento de servicios de enrutamiento sea crucial para el éxito de Uber. Los servicios deben ser capaces de comunicarse entre sí en nuestra compleja red. Hemos utilizado una combinación de HAProxy y Hyperbahn para resolver este problema. Hyperbahn es parte de una colección de software de código abierto desarrollado en Uber: Ringpop, TChannel, y Hyperbahn todos comparten una misión común para agregar la automatización, la inteligencia, y el rendimiento de una red de servicios.

Los servicios legados utilizan instancias locales HAProxy para encaminar JSON sobre peticiones HTTP a otros servicios, con el servidor front-end web Nginx a los servidores en el extremo posterior. De esta forma bien establecida de la transferencia de datos hace que la solución de problemas sea fácil, que era crucial a lo largo de varias migraciones a sistemas recientemente desarrollados en el último año.

Sin embargo, estamos dando prioridad a la fiabilidad a largo plazo sobre la capacidad de depuración (debuggability). Usando protocolos alternativos para HTTP (como spdy, HTTP/2, y TChannel) junto con los lenguajes de definición de interfaz como Thrift y Protobuf que ayudarán a evolucionar nuestro sistema en términos de velocidad y fiabilidad. Ringpop, una capa de hash coherente, trae la cooperación y la auto-sanación (self-healing) a nivel de aplicación. Hyperbahn permite que los servicios puedan encontrarse y comunicarse con los demás de forma sencilla y fiable, así como los servicios se programan de forma dinámica con Mesos.

En lugar del arcaico pooling para ver si algo ha cambiado, nos estamos moviendo a un patrón de pub-sub (publicación de actualizaciones a los suscriptores). HTTP/2 y spdy permiten más fácilmente este modelo de inserción. Varias características basadas en este “pooling” dentro de la aplicación de Uber verán una tremenda aceleración de mover para empujar usando pub-sub.

Development and Deploy

Phabricator provee una gran cantidad de poder para poder manejar nuestra gran cantidad de operaciones internas, a partir de la revisión de código hasta el proceso de la documentación automatizado. Buscamos a través de nuestro código en OpenGrok. Para proyectos de código abierto de Uber, desarrollamos utilizando GitHub para proyectos de código abierto y para el seguimiento de problemas y revisiones de código.

Los ingenieros de Uber  se esfuerzan por hacer que el desarrollo pueda simular el ambiente de producción lo más cerca posible, por lo que desarrollan principalmente en máquinas virtuales que se ejecutan en un proveedor de la nube o en el portátil de un desarrollador. Construimos nuestro propio sistema de despliegue interno para gestionar las construcciones. Jenkins hace la integración continua. Se combinaron Packer, Vagrant, Boto, y Unison para crear herramientas para la construcción, gestión y desarrollo de las máquinas virtuales. Utilizamos Clusto para la gestión de inventarios en el desarrollo. Puppet gestiona la configuración del sistema.

Trabajamos constantemente para construir y mantener canales de comunicación estables, no sólo para nuestros servicios, sino también para nuestros ingenieros. Para el descubrimiento de información, construimos uBlame (un guiño a git-blame) para realizar un seguimiento de qué equipo es propietario de un determinado servicio, y Whober para buscar nombres, caras, información de contacto, y la estructura organizativa. Utilizamos un sitio de documentación interna que auto construye documentos contactándose con repositorios utilizando Sphinx. Un servicio empresarial de alerta a nuestros ingenieros de guardia para mantener los sistemas en funcionamiento. La mayoría de los desarrolladores ejecutar OS X en sus computadoras portátiles, y Linux la mayoría de nuestros casos de producción se ejecutan con Debian Jessie.

Languages

En los niveles más bajos, los ingenieros de Uber escriben principalmente en Python, Node.js: Go, y Java. Comenzamos con dos lenguas principales: Node.js para el equipo del mercado, y Python para todos los demás. Estas primeras lenguas todavía alimentan la mayoría de los servicios que se ejecutan en Uber hoy.

Adoptamos Go y Java por razones de alto rendimiento. Proporcionamos soporte de primera clase para los lenguajes. Java se aprovecha del ecosistema de código abierto y se integra con las tecnologías externas, como Hadoop y otras herramientas de análisis. Go nos da eficiencia, simplicidad y velocidad de ejecución.

Nosotros sustituimos el viejo código Python mayor dado que el objetivo es romper el código base original en microservicios. Un modelo de programación asíncrona nos da un mejor rendimiento. Utilizamos Tornado con Python, pero el soporte nativo de Go, para la concurrencia es ideal para la mayoría de los nuevos servicios de rendimiento crítico.

Escribimos herramientas en C y C ++ cuando es necesario (como por alta eficiencia, código de alta velocidad a nivel del sistema). Utilizamos software que está escrito en los lenguajes de HAProxy, por ejemplo-, pero en su mayor parte, no  trabajamos en ellos.

Y, por supuesto, los que trabajan en la parte superior de la pila de escritura en las lenguajes más allá de Java, Go, Python, y Node.

Testing

Para asegurarnos de que nuestros servicios pueden manejar las demandas de nuestro entorno de producción, hemos desarrollado dos herramientas internas: Tormenta de granizo y uDestroy. Tormenta de granizo impulsa las pruebas de integración y simula la carga máxima fuera de las horas pico, mientras que uDestroy rompe intencionadamente cosas por lo que podemos mejorar en el manejo de fallos inesperados.

Nuestros empleados utilizan una versión beta de la aplicación para poner a prueba continuamente nuevos desarrollos antes de que lleguen a los usuarios. Hicimos un reportero de comentarios sobre la aplicación de atrapar cualquier error antes de que llegue a los usuarios. Cada vez que se toma una captura de pantalla de las aplicaciones Uber, esta característica nos lleva a presentar una tarea de corrección de errores en Phabricator.

Fin…

No pude traducir el artículo completo por cuestiones de tiempo, pero eso si, traté de centrarme en las cosas importantes (una parte en realidad) y en el stack tecnológico, que creo podrá darnos algunas buenas pautas para que aprendamos como escalar a partir de una arquitectura monolítica.  Estos temas son relevantes para quienes desean formarse como arquitectos de software.  Conocer de tecnología es de hecho una habilidad dura que debiese correr por las venas de quienes deseen formarse en este interesante (y hermoso) mundo.  En la siguiente parte espero poder hablar más acerca de los asuntos relacionados con las app móviles y como interactuar en tiempo real cuando nos enfrentamos al problema geográfico, como distribuir la arquitectura lógica del software en capas que ayuden en parte a ir resolviendo estos problemas.  Espero les sea de utilidad…  Nos vemos!

Fuente: https://eng.uber.com/tech-stack-part-one/

1 comentario

Archivado bajo Arquitectura de Sistemas, Arquitectura de Software, Ingeniería de Software

La Ingeniería detrás de Uber (PARTE I)

El principio detrás de la compleja ingeniería de Uber se basa en algo que ya he comentado en otras oportunidades en este mismo blog: ¿Cómo escalar a partir de una arquitectura monolítica simple? ¿Cómo romper este esquema de trabajo para formar una arquitectura que soporte grandes cantidades de datos y tráfico y además nos provea de seguridad?.  La respuestas a estas preguntas las abordé en detalle en mi tesis de Magister en la cuál realicé un trabajo de investigación de las que en ese tiempo eran las principales plataformas de redes sociales: Facebook, Twitter, Instagram, Flirck. Y aunque Uber no entra directamente en la categoría de “red social”, usa los principios sociales y por supuestos los de ingeniería del software para hacer que su plataforma tecnológica vaya creciendo de la mano de su modelo de negocios.

La Arquitectura inicial monolítica de Uber

Inicialmente Uber partió en la ciudad de San Francisco, California, teniendo todo su código base y los repositorios diseñados para trabajar en esta parte geográfica del mundo, lo cuál les permitía resolver los problemas de negocio de manera “sencilla”, lo que incluía: conectar a los pasajeros con los transportistas, el sistema de pagos y facturación.  Para cumplir con estos requerimientos era razonable contar con toda esa lógica de negocios en un solo lugar, pero en la medida en que comenzaron a expandirse a otras ciudades y agregar nuevas funcionalidades, esto ya no era tan razonable.

En la medida en que los “domain models” comenzaron a crecer en conjunto con la adición de nuevas características, los componentes se comenzaron a tornar ALTAMENTE ACOPLADOS (recordemos que uno de los principios fundamentales de ingeniería de software es mantener los componentes lo menos acoplados posible), y esto logró que la encapsulación y la separación de intereses se tornara un trabajo difícil.  Por lo tanto la tarea primordial del equipo de ingeniería de Uber era encontrar una forma en que rápidamente se pudieran integrar piezas de código al modelo de negocio; y acá es donde entra la integración continúa.

¿Cómo lograr un buen escalamiento cuando tenemos diseñada nuestra plataforma para un solo repositorio?

El cambio a SOA

Uber decidió seguir el ejemplo de empresas como: Amazon, Twitter, Netflix, SoundCloud y romper el esquema monolítico base para formar una arquitectura orientada a servicios (SOA).  En concreto, SOA puede significar una variedad de cosas distintas (como término, algo que abordé en el artículo Distinguiendo entre SaaS y SOA), sin embargo Uber decidió abordar SOA a partir del uso del patrón de microservicios.  Para no inventar la rueda, voy a recurrir a la genial explicación de Martín Fowler:

Una arquitectura monolítica pone toda su funcionalidad en un único proceso, y la forma en que tiene de escalar (crecer) es agregando múltiples servidores.

Una arquitectura de microservicios pone cada funcionalidad (lo más atómica posible) en un servicio separado, y la forma que tiene de crecer es distribuyendo estos servicios a través de los servidores, replicando de acuerdo a las necesidades del negocio.

Cada servicio puede ser escrito en su propio lenguaje y puede o no tener su propia base de datos.

Esto resuelve varios problemas, pero también aparecen algunos nuevos, los cuales están clasificados en las siguientes áreas:

  1. Obviousness
  2. Safety
  3. Resilience

PD: uso los términos en inglés porque a veces es difícil encontrar una correcta traducción al texto sin que esto vaya en desmedro del contexto.

Obviousness

Con más de 500 servicios, encontrar el servicio adecuado puede tornarse en una ardua tarea.  Toda vez identificado el servicio, la forma en que se utilizará este servicio no es tan obvia, ya que cada microservicio tiene estructurado su propio camino.  Los servicios que ofrecen REST o RPC (donde es posible acceder a su funcionalidad dentro de su propio dominio -lo que se conoce como stateless-), se caracterizan por ofrecer contratos débiles, y en el caso de Uber, los contratos varían mucho entre microservicios.  La adición de un esquema JSON a una API REST puede mejorar la seguridad y el proceso de desarrollo contra el servicio, pero no es trivial de escribir o mantener.  Por último, estas soluciones no ofrecen ninguna garantía con respecto a la tolerancia a fallos o la latencia. No hay manera estándar para manejar los tiempos de espera del lado del cliente y las interrupciones, o garantizar que una interrupción de un servicio no cause interrupciones en cascada. La capacidad de recuperación global del sistema se vería afectada negativamente por estas debilidades. Como un desarrollador escribió,  “convertimos nuestra API monolítica en una API monolítica distribuida”.

Se ha hecho evidente que necesitamos una forma estándar de comunicación que ofrezca la seguridad de tipos, la validación y la tolerancia a fallos. Otros objetivos incluyen:

  • Formas sencillas para proporcionar bibliotecas de cliente
  • Soporte “Cross Language”
  • Tiempos de espera sintonizables con políticas de reintento
  • Desarrollo y Testing Eficiente

En esta etapa de nuestro hiper-crecimiento, los ingenieros de Uber continúan evaluando tecnologías y herramientas para adaptarse a nuestras metas. Una cosa que sí sabemos es que el uso del ya existente Lenguaje de definición de interfaz (IDL) que proporciona una gran cantidad de herramientas pre-construidas desde el primer día es ideal.

Se evaluaron las herramientas existentes y encontramos que Apache Thrift (popularizada por Facebook y Twitter) cumplió con nuestras necesidades. Thrift es un conjunto de bibliotecas y herramientas para la construcción de servicios de lenguajes cruzados altamente escalables. Para lograr esto, los tipos de datos y las interfaces de servicios se definen en un archivo que es agnóstico del lenguaje de programación. A continuación, el código se genera para abstraer el transporte y la codificación de mensajes RPC entre los servicios escritos en todos los lenguajes que usamos (Python, Node, Go, etc.)

Safety

El argumento más convincente para Thrift es su seguridad. Thrift garantiza la seguridad de la unión (binfing) de los servicios al utilizar contratos estrictos. El contrato describe cómo interactuar con ese servicio incluyendo como llamar a los procedimientos de ese servicio, lo que proporcionan entradas y salida de lo que se espera al momento de ejecutarlo.

La adhesión a un estricto contrato significa menos tiempo que se dedica a encontrar la manera de comunicarse con un servicio y hacer frente a la serialización. Además, como microService evoluciona no tenemos que preocuparnos acerca de las interfaces que cambian repentinamente, y somos capaces de desplegar servicios de forma independiente de los consumidores. Esta es una muy buena noticia para los ingenieros de Uber. Estamos en condiciones de pasar a otros proyectos y herramientas desde Thrift resolviendo el problema de la seguridad fuera de la caja.

Resilience

Por último, nos inspiramos en la tolerancia a fallos y las bibliotecas de latencia en otras empresas que se enfrentan a problemas similares, tales como Netflix que usa la biblioteca Hystrix y de Twitter la biblioteca Finagle , para abordar el problema de la resistencia. Con esas bibliotecas en mente, escribimos bibliotecas que aseguran los clientes son capaces de hacer frente a situaciones de fallo con éxito (que se discutirá con más detalle en un próximo post).

¿Hacia dónde se dirige Uber?

Claramente a mejorar la escalabilidad organizacional y proveer mayor resistencia y tolerancia a fallos usando la arquitectura de microServicios.  Ellos entienden que hasta este punto la solución no es perfecta y requiere de cambios, desafortunadamente existen pocas herramientas alternativas para Python y Node que son parte del stack de desarrollo de Uber y se requiere de buena inversión de tiempo para construirlas.  Lo interesante, es ver que si es posible migrar un modelo monolítico a uno de mayor escalabilidad como SOA (implementado a través de micro servicios) considerando la evolución de nuestro modelo de negocios, ya lo ha hecho Facebook y Twitter en el pasado, y los chicos de Uber no quisieron quedar fuera.

Lo que se viene en la Parte II:

Ya nos adentraremos completamente en el stack de Uber, hablaremos tanto de su backend como de casi todo su stack tecnológico pasando por la arquitectura lógica y física, plataformas, lenguajes de programación, entre otros.  Créanme que lo que estos chicos realizan a nivel de Frontend y Backend es muy interesante.

Fuentes de información:

  1. https://eng.uber.com/soa/
  2. http://highscalability.com/

2 comentarios

Archivado bajo Arquitectura de Sistemas, Arquitectura de Software, Ingeniería de Software, SOA

Implementación del Proceso Personal de Software (PSP) en un primer curso de Programación de Computadores

Resumen— En este artículo, se muestran aspectos relacionados con el desarrollo de la tesis de maestría titulada “Diseño de una estrategia de aprendizaje para implementar prácticas de PSP (Personal Software Process) en cursos básicos de Programación”. En esta tesis, se propone una propuesta metodológica de enseñanza que promueve la adopción de las prácticas de PSP en un curso de Fundamentos de Programación, que hace parte del currículo del Programa de Ingeniería de Sistemas y Computación de la Universidad del Quindío en Armenia (Colombia). Los resultados obtenidos en esta investigación, permiten realizar un diagnóstico y aportar una serie de reflexiones acerca de la importancia de implementar enfoques orientados a procesos que incorporen buenas prácticas y conceptos de calidad en el desarrollo de software desde etapas tempranas en la formación de los estudiantes. Con la introducción de PSP, los estudiantes van apropiando buenas prácticas de desarrollo de software y adquieren disciplina para planear y gestionar sus proyectos.

Fuente y texto completo: http://ciinti.info/memorias2012/Full%20Papers/16_Proceso%20Personal%20de%20Software%20PSP.pdf

Deja un comentario

Archivado bajo Ingeniería de Software

Casos a incluir y casos a extender

Un tema que genera mucha polémica entre la gente que modela casos de uso es la elección entre la relación de <<include>> y <<extend>>. Lo peor es que muchas de esas discusiones generan muy poco valor en el resultado final en el modelo y en cambio quitan tiempo valioso del proyecto. Esto se debe a que dichas relaciones, muchas veces no son del todo comprendidas por la persona que la modela, y mucho menos son comprendidas por las personas que leen el modelo. Así que al final no se le saca el provecho que en todo caso debería de tener dicha elección.

Es mejor mantener el modelo simple, incluso si esto significa utilizar menos elementos gráficos de UML, si eso va a facilitar el modelado y la comunicación en el proyecto. Pero, después de todo este tiempo y de los diferentes temas que hemos venido tratando, es importante avanzar y adentrarnos en algunos pormenores del lenguaje unificado.

Antes que todo, ¿qué es el “include” y el “extend”?

Gráficamente lo que mostramos es una relación de dependencia entre el par de casos de uso, con el nombre correspondiente al tipo de relación de la que se trate: ya sea <<include>> o <<extend>>.
Estas, son relaciones que usamos para ligar gráficamente dos casos de uso, cuyos flujos de eventos están unidos, normalmente en una sola sesión del usuario. En otras palabras, un caso de uso que está ligado, por medio de una de estas dos relaciones, a otro caso de uso; también podría leerse o ejecutarse como un sólo caso de uso en lugar de dos. Obviamente, hay una razón por la cual decidimos separarlos en dos, lo cual explicaremos más adelante.
Imagina el conjunto de pasos que ocurren al realizar una compra en una tienda departamental. Seguramente no tendrás problema en visualizar el conjunto de pasos para solicitar la autorización de la tarjeta de crédito con la que vas a pagar, ligado a los pasos donde el vendedor registra los productos a comprar. Es decir, los flujos de eventos de ambos procesos forman una sola cosa; juntos podrían formar un solo caso de uso, en lugar de dos casos de uso unidos por alguna de estas relaciones que aquí estamos tratando.

Figura 1. Relacionando casos de uso.  Fuente: http://www.milestone.com.mx/

Figura 1. Relacionando casos de uso. Fuente: http://www.milestone.com.mx/

Include. En términos muy simples, cuando relacionamos dos casos de uso con un “include”, estamos diciendo que el primero (el caso de uso base) incluye al segundo (el caso de uso incluído). Es decir, el segundo es parte esencial del primero. Sin el segundo, el primero no podría funcionar bien; pues no podría cumplir su objetivo. Para una venta en caja, la venta no puede considerarse completa si no se realiza el proceso para cobrarla en ese momento. El caso de uso “Cobrar Renta” está incluido en el caso de uso “Rentar Video”, o lo que es lo mismo “Rentar Video” incluye (<<include>>) “Cobrar Renta”.

Figura 2. Ejemplo de Include.  Fuente: http://www.milestone.com.mx/

Figura 2. Ejemplo de Include. Fuente: http://www.milestone.com.mx/

Extend. La polémica al querer seleccionar una de las dos relaciones es que en el “extend” también podemos ver, desde la perspectiva del usuario, a los dos flujos como si fueran uno sólo. Y en ciertos escenarios el caso de uso base no podría cumplir su objetivo si no se ejecutara la extensión. Pero, una de las diferencias básicas es que en el caso del “extend” hay situaciones en que el caso de uso de extensión no es indispensable que ocurra, y cuando lo hace ofrece un valor extra (extiende) al objetivo original del caso de uso base. En cambio en el “include” es necesario que ocurra el caso incluído, tan sólo para satisfacer el objetivo del caso de uso base. Ejemplo: Puedes “Realizar Venta” sin “Acumular Puntos de Cliente VIP”, cuando no eres un cliente VIP. Pero, si eres un cliente VIP sí acumularás puntos. Por lo tanto, “Acumular Puntos” es una extensión de “Realizar Venta” y sólo se ejecuta para cierto tipo de ventas, no para todas.

Figura 3. Ejemplo de Extend.  Fuente: http://www.milestone.com.mx/

Figura 3. Ejemplo de Extend. Fuente: http://www.milestone.com.mx/

Casos de Abuso

Uno de los riesgos que existe cuando la gente sabe que tiene estas relaciones como un elemento a utilizar en sus modelos de casos de uso, consiste en su abuso. Mucha gente, y sobre todo la que arrastra prácticas de métodos estructurados, la suele utilizar en exceso. No es raro ver modelos de casos de uso que llegan a tener decenas de inclusiones y extensiones, incluso las inclusiones y extensiones se vuelven a extender a varios niveles, generando una maraña de casos de uso que no ofrecen valor al ser mostrados explícitamente.

Figura 4. Abuso de relaciones.  Fuente: http://www.milestone.com.mx/

Figura 4. Abuso de relaciones. Fuente: http://www.milestone.com.mx/

Es importante comprender que el objetivo de estos tipos de relaciones NO consiste (remarco la negación) en motivar la división de los casos de uso en la mayor cantidad de pedazos. Debe de existir una razón importante para que decidamos dividir un caso de uso en dos que serán unidos por medio de alguna de estas relaciones. Si entendemos esto y somos congruentes, obtendremos un beneficio real para el proyecto; fin último del uso de UML.

La razón por la que la gente suele partir sus casos de uso en infinidad de “include” y “extend” es porque quieren conocer, entender y comunicar el máximo detalle de los casos de uso en el diagrama. Hay quien llega a utilizar, erróneamente, estas relaciones para mostrar el orden en que se ejecutan estos casos de uso. Debemos de recordar que al modelar el diagrama de casos de uso no buscamos analizar el detalle, y mucho menos los flujos. Todo ese detalle lo podremos plasmar en otro tipo de diagramas, como los diagramas de interacción, de actividad, de estados, o simplemente un texto en una especificación.

Relaciones de Análisis o Diseño

Otra situación donde abusamos de estas relaciones se da cuando queremos representar la unión de casos de uso por una decisión de diseño del sistema, específicamente por una decisión de navegabilidad entre funciones. Pensemos en cierta funcionalidad en un sistema, la cual corresponde a la ejecución de cierto caso de uso (por ejemplo “Registrar Préstamo de un Video”). Y estando en dicho caso de uso tienes a la vista en la pantalla, y decides utilizar, un botón que te permitiría iniciar otro caso de uso que tiene poco o nada que ver con el objetivo del caso de uso inicial (digamos, “Consultar Promociones”). Esto no debería de mostrarse como una relación entre estos dos casos de uso en el modelo.

No deberíamos modelar al primer caso de uso incluyendo ni siendo extendido con el segundo caso de uso ni viceversa, pues la razón por la que se ligaron (no gráficamente, sino en su ejecución) fue por una facilidad otorgada por la manera en que se diseño el sistema, la cual permite navegar fácilmente entre las diferentes funciones del sistema. La navegabilidad que otorga el sistema entre uno y otro caso de uso normalmente tiene que ver poco con que exista o no una relación entre dichos casos de uso.

Reuso: Evitando el Retrabajo

Una de las razones por las cuales deberías de considerar el uso de este tipo de relaciones, es porque identificas que hay pasos que son iguales en dos o más casos de uso. No querrás tener que escribir y darle mantenimiento a esos pasos en los documentos asociados a cada uno de ellos. Peor aún, no querrás correr el riesgo de que esos pasos se diseñen, programen y prueben de maneras diferentes y con esfuerzos aislados por ti o tu equipo de desarrollo. Finalmente son la misma cosa, ¿para qué querríamos trabajar doble? Lo que queremos es economizar, ser más eficientes en el desarrollo, y ahí es cuando viene el beneficio de identificar estos tipos de relaciones; porque es una oportunidad de identificar reuso.

Figura 5. Identificación de reuso.  Fuente: http://www.milestone.com.mx/

Figura 5. Identificación de reuso. Fuente: http://www.milestone.com.mx/

Si te sientes preparado para desarrollar modelos de casos de uso más sofisticados y de mayor valor, entonces considera la posibilidad de utilizar estos tipos de relaciones. Sólo asegúrate de aprovecharlas adecuadamente, buscando el beneficio real que deberían de proporcionar en tu modelo y proyecto con base en las recomendaciones mencionadas. Y recuerda unificar los criterios dentro de tu empresa para que el lenguaje sea realmente unificado o estandarizado dentro de tu empresa.

Por Sergio Orozco y Leticia Ortiz

Fuentehttp://www.milestone.com.mx

Deja un comentario

Archivado bajo Diseño, Ingeniería de Software

El método científico y la Metodología del diseño de Software

Cuadro Sinóptico comparando método científico y metodología del diseño de software

metodo_cientifico_metodologia_software

Método científico

Observación, es aplicar atentamente los sentidos en un objeto,

Inducción, efecto de extraer, a partir de determinadas observaciones o experiencias particulares.

Hipótesis, Planteamiento mediante la observación siguiendo las normas establecidas por el método científico.

Verificación, solo se examina si es correcto o no el experimento.

Refutación o aceptación, si la verificación fue aceptada el experimento término si no se realiza una retroalimentación hasta continuar con la hipótesis.

Metodología del diseño de software

Análisis del problema Es una similitud entre observación e inducción porque en el se plantea el problema y para ello tuvo que ver una observación previa.

Diseño preliminar-Programación-Implementación es un anteproyecto el cual puede ser considerada como hipótesis por que a partir de ella se lleva acabo la experimentación.

Prueba si es aceptada el experimento termina que es muy similar a la refutación y/o aceptación.

Etapas del proceso

La ingeniería de software requiere llevar a cabo numerosas tareas, dentro de etapas como las siguientes:

Análisis de requisitos,

Mientras que los clientes piensan que ellos saben lo que el software tiene que hacer, se requiere de habilidad y experiencia en la ingeniería de software para reconocer requisitos incompletos, ambiguos o contradictorios. El resultado del análisis de requisitos con el cliente se plasma en el documento ERS, Especificación de Requerimientos del Sistema, cuya estructura puede venir definida por varios estándares. La captura, análisis y especificación de requisitos (incluso pruebas de ellos), es una parte crucial; de esta etapa depende en gran medida el logro de los objetivos finales.

Especificación,

Es la tarea de describir detalladamente el software a ser escrito, en una forma matemáticamente rigurosa.

Diseño y arquitectura,

Se refiere a determinar como funcionará de forma general sin entrar en detalles. Consiste en incorporar consideraciones de la implementación tecnológica, como el hardware, la red, etc. Se definen los Casos de Uso para cubrir las funciones que realizará el sistema, y se transforman las entidades definidas en el análisis de requisitos en clases de diseño, obteniendo un modelo cercano a la programación orientada a objetos.

Programación,

Reducir un diseño a código puede ser la parte más obvia del trabajo de ingeniería de software, pero no necesariamente es la que demanda mayor trabajo y ni la más complicada. La complejidad y la duración de esta etapa está íntimamente relacionada al o a los lenguajes de programación utilizados, así como al diseño previamente realizado.

Prueba,

Consiste en comprobar que el software realice correctamente las tareas indicadas en la especificación del problema. Una técnica de prueba es probar por separado cada módulo del software, y luego probarlo de forma integral, para así llegar al objetivo.Hay dos grandes formas de organizar un área de pruebas, la primera es que esté compuesta por personal inexperto y que desconozca el tema de pruebas, de esta forma se evalúa que la documentación entregada sea de calidad, que los procesos descritos son tan claros que cualquiera puede entenderlos y el software hace las cosas tal y como están descritas.

Documentación,

Todo lo concerniente a la documentación del propio desarrollo del software y de la gestión del proyecto, pasando por modelaciones (UML), diagramas, pruebas, manuales de usuario, manuales técnicos, etc; todo con el propósito de eventuales correcciones, usabilidad, mantenimiento futuro y ampliaciones al sistema.

Mantenimiento,

Mantener y mejorar el software para enfrentar errores descubiertos y nuevos requisitos. Esto puede llevar más tiempo incluso que el desarrollo inicial del software. Alrededor de 2/3 de toda la ingeniería de software tiene que ver con dar mantenimiento.

Metodología (ingeniería de software)

La rama de la metodología, dentro de la ingeniería de software, se encarga de elaborar estrategias de desarrollo de software que promuevan prácticas adoptativas en vez de predictivas; centradas en las personas o los equipos, orientadas hacia la funcionalidad y la entrega, de comunicación intensiva y que requieren implicación directa del cliente.

Método científico

El método científico está sustentado por dos pilares fundamentales. El primero de ellos es la reproducibilidad, es decir, la capacidad de repetir un determinado experimento en cualquier lugar y por cualquier persona. El segundo pilar es la falsabilidad. Es decir, que toda proposición científica tiene que ser susceptible de ser falsada (falsacionismo). Esto implica que se pueden diseñar experimentos que en el caso de dar resultados distintos a los predichos negarían la hipótesis puesta a prueba.Según James B. Conant no existe un método científico. El científico usa métodos definitorios, métodos clasificatorios, métodos estadísticos, métodos hipotético-deductivos, procedimientos de medición, etcétera. Según esto, referirse al método científico es referirse a este conjunto de tácticas empleadas para constituir el conocimiento, sujetas al devenir histórico, y que pueden ser otras en el futuro. Ello nos conduce tratar de sistematizar las distintas ramas dentro del campo del método científico.

Francis Bacon definió el método científico de la siguiente manera:

1. Observación: Observar es aplicar atentamente los sentidos a un objeto o a un fenómeno, para estudiarlos tal como se presentan en realidad.

2. Inducción: La acción y efecto de extraer, a partir de determinadas observaciones o experiencias particulares, el principio particular de cada una de ellas.

3. Hipótesis: Planteamiento mediante la observación siguiendo las normas establecidas por el método científico.

4. Probar la hipótesis por experimentación.

5. Demostración o refutación (antítesis) de la hipótesis.

6. Tesis o teoría científica (conclusiones).

Fuente: Luis Miguel Salazar Burgos (http://apuntessig01a31.blogspot.com/)

Referencias:

“El papel del método científico en el desarrollo del software”. Dra. Natalia Juristo Catedrática de Ingeniería de Software de la Universidad Politécnica de Madrid, Facultad de Ingeniería, Universidad ORT Uruguay, 24 de marzo de 2011.  Recurso online: http://www.ort.edu.uy/fi/pdf/nataliajuristo240311.pdf

1 comentario

Archivado bajo Diseño, Ingeniería de Software