Posted on

Agile & Scrum – una guía rápida

Scrum es un proceso en el que se aplican de manera regular un conjunto de buenas prácticas para trabajar colaborativamente, en equipo, y obtener el mejor resultado posible de un proyecto

En Scrum se realizan entregas parciales y regulares del producto final, priorizadas por el beneficio que aportan al receptor del proyecto.

Scrum está especialmente indicado para proyectos:

  • en entornos complejos
  • donde se necesita obtener resultados pronto
  • donde los requisitos son cambiantes o poco definidos
  • donde la innovación, flexibilidad y productividad son necesarias
  • donde no se está entregando al cliente lo que necesita
  • donde las entregas se alargan demasiado
  • donde los costes se disparan o la calidad no es aceptable
  • cuando se necesita capacidad de reacción ante la competencia
  • cuando la moral de los equipos es baja y la rotación alta
  • cuando es necesario identificar y solucionar ineficiencias

 

FUNDAMENTOS DE SCRUM (buenas prácticas)
  • El desarrollo incremental de los requisitos del proyecto en bloques temporales cortos y fijos (iteraciones de un mes natural y hasta de dos semanas, si así se necesita)
  • La priorización de los requisitos con valor para el cliente y coste de desarrollo en cada iteración
  • El control empírico del proyecto:
    • Al final de cada iteración se demuestra al cliente el resultado real obtenido, de manera que pueda tomar las decisiones necesarias en función de lo que observa y del contexto del proyecto en ese momento
    • El equipo se sincroniza diariamente y realiza las adaptaciones necesarias
  • La potenciación del equipo, que se compromete a entregar unos requisitos y para ello se le otorga la autoridad necesaria para organizar su trabajo
  • La sistematización de la colaboración y la comunicación tanto entre el equipo como con el cliente

 

BENEFICIOS DE SCRUM
  • Entrega mensual (o quincenal) de resultados:
    • Gestión regular de las expectativas del cliente y basada en resultados tangibles
    • Resultados anticipados (time to market)
    • Flexibilidad y adaptación respecto a las necesidades del cliente, cambios en el mercado, etc
    • Mitigación sistemática de los riesgos del proyecto
  • Productividad y calidad
  • Alineamiento entre el cliente y el equipo de desarrollo
  • Equipo motivado

 

REQUISITOS PARA USAR SCRUM
  • Cultura de empresa basada en trabajo en equipo, delegación, creatividad y mejora contínua
  • Compromiso del cliente en la dirección de los resultados del proyecto, gestión del ROI y disponibilidad para poder colaborar
  • Compromiso de la dirección de la organización para resolver problemas endémicos y realizar cambios organizativos, formando equipos autogestionados y multidisciplinares y fomentando una cultura de gestión basada en la colaboración y en la facilitación llevada a cabo por líderes al servicio del equipo
  • Compromiso conjunto y colaboración de los miembros del equipo
  • Relación entre proveedor y cliente basada en ganar-ganar, colaboración y transparencia
  • Facilidad para realizar cambios en el proyecto
  • Tamaño de cada equipo entre 5 y 9 personas (con técnicas específicas de planificación y coordinación cuando varios equipos trabajan en el mismo proyecto)
  • Equipo en un mismo espacio común para mejorar la comunicación
  • Dedicación del equipo a tiempo completo
  • Estabilidad de los miembros del equipo

 

CÓMO FUNCIONA SCRUM
Actividades
  • Planificación de la iteración (Sprint Planning)
  • Ejecución de la iteración (Sprint)
  • Reunión diaria de sincronización del equipo (Scrum Daily Meeting)
  • Demostración de los requisitos completados (Sprint Review)
  • Retrospectiva (Sprint Retrospective)
  • Refinamiento de la lista de requisitos y cambios en el proyecto
Responsabilidades
  • Cliente (Product Owner)
  • Facilitador (Scrum Master)
  • Equipo (Team)
Herramientas
  • Lista de requisitos priorizada (Product Backlog)
  • Lista de tareas de la iteración (Sprint Backlog)
  • Gráficos de trabajo pendiente (Burndown Chart)

MANIFIESTO AGILE
Valorar:
  • Individuos e interacciones más que procesos y herramientas
  • Software que funciona más que documentación exhaustiva
  • Colaboración con el cliente más que negociación de contratos
  • Responder ante el cambio más que seguimiento de un plan

 

PRINCIPIOS DEL DESARROLLO AGILE
  • La prioridad es que el cliente esté satisfecho y siempre informado del estado del proceso. Entrega temprana y contínua de software que aporte valor
  • Los requisitos del proyecto pueden cambiar y no se verá como un problema, sino como una ventaja competitiva
  • Las entregas se realizan periódicamente y en periodos cortos. La planificación se realizará desde las dos semanas, a los dos meses
  • El equipo de desarrollo debe trabajar de forma conjunta y coordinada con la gente de negocio
  • Es prioritario motivar al equipo, confiar en los miembros y proporcionarles los recursos o apoyos que necesiten
  • Las reuniones Scrum son el método más efectivo de comunicarse
  • El éxito depende de si el producto final funciona y es satisfactorio
  • Los procesos deben ser sostenibles, tanto en recursos materiales, como en la gestión del tiempo y el ritmo de trabajo
  • En todo proceso o etapa debe prevalecer la excelencia técnica
  • Prevalece la ley de la simplicidad: menos es más
  • La autoorganización de los equipos es esencial para buen diseño
  • Los tiempos para la reflexión y buscar mejoras es necesario e igual que importante que el resto de fases

 

Posted on

Clean Code – una guía rápida

Existen dos tipos de desarrolladores, los que programan y los que programan bien.

Todos sabemos programar, al fin y al cabo nos han enseñado que para llegar a una solución hay muchos caminos. Incluso el peor código posible es capaz de darnos la resolución al problema.

Es hora de adentrarse en el camino de baldosas amarillas, es hora de Programar Bien.

A continuación dejo una serie de pautas a tener en cuenta para entrar de lleno en el mundo del Clean Code. A modo de cheat sheet, graba estas ideas en tu mente, cuélgalas de tu tablón en la oficina, ponlas en la nevera de casa, haz con ella lo que quieras, pero tenlas en cuenta siempre a la hora de desarrollar.

Consideraciones generales a tener en cuenta sobre tu código:

  • Hace UNA COSA y la hace BIEN
  • Es SIMPLE y directo
  • No está duplicado
  • Se puede leer
  • Piensa en tí como un escritor
  • Programar es un arte, un trabajo de artesanía
  • Tu código te importa
  • Es bonito
  • Deja el código más limpio de como lo encontraste
  • Mejora tu código con la práctica

 

Creando buenos nombres
  • Un nombre debe responder todas las preguntas
  • Debe revelar su intención
  • Debe tener significado
  • Debe ser pronunciable
  • Se debe poder buscar dentro del código
  • Los nombres de una letra SÓLO como variables locales en métodos cortos
  • Los nombres de las clases deben ser SUSTANTIVOS en singular
  • Los nombres de los métodos deben ser VERBOS
  • Usar siempre sólo una palabra por concepto (no usar get y fetch para hacer lo mismo)
  • Evitar usar la misma palabra para diferentes propósitos
  • No usar prefijos en nombres de clases (GSD_Address)

MAL:

class Wizards {
   let m:Int //mana available
   let typmgc:String //type of magic wizard use
   var l:Int //lives

   func lose(x:Int) {
      self.l -= x
   }
   ...
}

BIEN:

class Wizard {
   let manaAvailable:Int
   let typeOfMagic:String
   var lives:Int

   func loseLives(livesLost:Int) {
      self.lives -= livesLost
   }
   ...
}

 

Clean Code en Funciones
  • Una función debe hacer UNA COSA. Y la debe hacer BIEN
  • El control de errores ya es UNA COSA
  • Deben ser pequeñas (de 1 a 5 líneas máximo)
  • Con nombre descriptivo que indica lo que hace
  • No más de 3 argumentos
  • Si requiere más de 3 argumentos, usa una clase
  • Lo ideal son 0 argumentos
  • No usar argumentos de salida, usar returns
  • Sólo un nivel de abstracción
  • Usar excepciones, no devolución de códigos de error
  • Estructuras if, else, where … con sólo una línea (llamada a otra función)

MAL

class Wizard {
   let manaAvailable:Int
   let typeOfMagic:String
   var lives:Int

   func castSpell(name:String, manaRequired:Int, lifeCost:Int) {
      if manaRequired <= self.manaAvailable {
         print("Spell \(name) casted")
         self.lives -= lifeCost
         if self.lives <= 0 {
            print("You lost the game")
         }
      } else {
         print("Spell \(name) failed")
      }
   }
   ...
}

BIEN:

class Spell {
   let name:String
   let manaRequired:Int
   let lifeCost:Int

   func cast(manaUsed:Int) -> Bool {
       if self.manaRequired <= manaUsed {
           print("Spell \(self.name) casted")
           return true
       } else {
           print("Spell \(self.name) failed")
           return false
       }
   }
   ...
}

class Wizard {
   let manaAvailable:Int
   let typeOfMagic:String
   var lives:Int

   func castSpell(spell:Spell) {
       if spell.cast(manaUsed:self.manaAvailable) {
           self.loseLives(livesLost:spell.lifeCost)
       }
   }
 
   func loseLives(livesLost:Int) {
       self.lives -= livesLost
       self.checkDeath()
   }
 
   func checkDeath() {
       if self.lives <= 0 {
           print("You lost the game")
       }
   }
   ...
}

 

Clean Code y los Comentarios
  • NO hacen falta. Exprésate usando el código
  • Son difíciles de mantener
  • Los comentarios mienten (pueden referirse a una situación anterior)
  • La verdad sólo está en el código
  • Usar comentarios sólo para situaciones de Warnings o To-Do

MAL:

   //check if the wizard is dead
   func dead() {
      //if wizard's lives are below 0, wizard dies and lost the game
      if self.lives <= 0 { 
         print ("You lost the game") //print message
      }
   }
   //function ends

BIEN:

   func checkDeath() {
       if self.lives <= 0 {
           print("You lost the game")
       }
   }

 

Clean Code en Clases
  • NO exponer detalles de las Clases
  • Usar abstracciones
  • NO usar getters y setters para todas las propiedades
  • No todas las propiedades tienen que ser públicas
  • Los objetos ESCONDEN sus datos y EXPONEN sus métodos
  • Las estructuras de datos EXPONEN sus datos y no tienen comportamientos
  • Evitar híbridos, mitad objetos mitad estructura de datos

 

Formato de código
Vertical
  • Ficheros pequeños (pocas líneas por fichero)
  • El nombre del fichero debe ser explicativo
  • Usar saltos de líneas en blanco para separar conceptos
  • Declarar variables cerca de donde van a ser usadas
  • En funciones, declarar variables en la parte superior
  • Las propiedades de las clases en la parte superior
  • Mantener cerca las funciones que llaman a otras funciones
  • La función llamadora antes de la función llamada
  • Mantener cerca funciones de concepto similar
Horizontal
  • Mantener líneas cortas, no más de 120 caracteres
  • Evitar scroll hacia la derecha
  • Separar operadores con espacios en blanco ( a = b + c )
  • Mantener juntos el nombre de la función con su paréntesis ( callFunction(parameter) )
  • Usar sangría en cada ámbito
  • Usar apertura de llave de ámbito al final de la línea ( if a == b { )
  • Separar argumentos en funciones con espacios tras coma ( print(a, b, c) )