segunda-feira, 21 de junho de 2010

Scrum e XP das trincheiras

INTRODUÇÃO

É grande o número de empresas e instituições de TI que tentaram implantar SCRUM em em seus times de desenvolvimento e falharam. A principal causa, a meu ver, é a ausência de uma normatização a respeitos das práticas que constituem SCRUM. De fato, considero esta a maior força e a maior fraqueza do SCRUM: Ele pode e deve ser adaptado ao ambiente e ao contexto da instituição onde será implantado. Esta questão rende debates acalorados e já foi tema de um post deste blog (aqui ó).

Scrum and XP from the trenches” (“Scrum e XP das trincheiras” em uma tradução livre) Descreve em detalhes o conjunto de práticas que funcionou em uma empresa sueca sob a liderança de Henrik Kniberg. Longe de ser uma “implementação de referência”, trata-se de uma caso de sucesso que acredito valer a pena ser lido e estudado.

O livro aborda temas comuns como:
  • Como conduzir cada cerimônia SCRUM
  • Como organizar o backlog do produto e do sprint
  • Interação e responsabilidades de cada papel (PO, SCRUM master, time)
  • Como lidar com múltiplos times e times geograficamente distribuídos
  • Tamanho dos Sprints
E também temas menos comuns, tais:
  • Arranjo físico do time
  • Pausas entre sprints
  • Comunicação do andamento do sprint para o restante da instituição. 
Seguem informações comentadas sobre alguns trechos do livro que julguei mais relevantes:

BACKLOG DO PRODUTO

O Backlog do produto é basicamente uma lista priorizada de requisitos, estórias, funcionalidades (escolha um nome, por aqui vamos ficar com estória). São coisas que o cliente quer descritas na linguagem do cliente.

É mantido em uma planilha do excel que fica em um drive compartilhado para todo o time. Cada item é composto pelos seguintes campos:

  • ID – Identificador numérico único. Serve principalmente para evitar confusão caso uma estória mude de nome.
  • Nome – Um nome que seja curto e mais descritivo possível. Normalmente entre 2 e 10 palavras.
  • Importância – O grau de importância da história para o cliente (informado pelo PO). Quanto maior a importância maior a prioridade da estória.
  • Estimativa Inicial – A estimativa do time com relação a esta estória.
  • Como demonstrar – Uma descrição de auto nível de como a história será demonstrada na sprint review.
  • Notas – Qualquer outra informação ou observação que o PO julgar necessária.
É importante manter o backlog do produto em um nível bastante negocial. Isso pode ser um problema se o PO possui background técnico, já que ele pode querer adicionar estórias como: “Incluir índice na base de dados”. Nestes casos o ideal é substituir o nome da estória por aquilo que seria na verdade o objetivo da tarefa técnica (neste caso, algo como “acelerar a resposta do sistema nas pesquisas”). O time é o papel mais adequado para decidir como isso será alcançado (embora a ideia original do PO pode e deve ser levada em consideração).

PLANEJAMENTO DO SPRINT

Esta é a cerimônia mais importante do SCRUM. Seu objetivo é levantar informação suficiente para que o time possa trabalhar tranquilamente por todo um sprint. Ao fim da reunião, é importante ter:

  • O objetivo do sprint.
  • Lista de membros do time.
  • Sprint Backlog.
  • Data da review.
  • Local e hora para o daily meeting.

A presença do PO é fundamental não apenas para explicações e remoção de dúvidas, mas para negociar escopo e importância das estórias de forma a influenciar o sprint backlog de acordo com os interesses do cliente.

É comum que sprints plannings demorem mais do que esperado. Nestes casos o melhor a fazer é interromper a reunião no momento planejado e deixar o sprint sofrer. Da próxima vez a tendência é que todos se esforcem para concluir tudo no tempo pre estabelecido.

BACKLOG DO SPRINT

Para decidir os itens do backlog do produto que irão compor o backlog do sprint, o time pode usar 3 abordagens:
  • Aproximação pelo sentimento
  • Cálculo de velocidade através da média dos sprints passados.
  • Cálculo de velocidade através cálculo de recursos.
Na aproximação pelo sentimento o time simplesmente inclui as estórias que acredita ser capaz de entregar ao fim do sprint.

No cálculo de velocidade através da média dos sprints passados o time inclui um total de pontos de estória equivalente a média dos pontos de estória entregues nos sprints passados.

No cálculo de velocidade usando cálculo de recursos é feita uma equivalência entre os pontos de estória e a quantidade de trabalho que um membro do time realiza em um dia. São incluídos um total de pontos de estória equivalentes a capacidade do time (que é o total de membros vezes o total de dias do sprint) multiplicado por um fator redutor que representa imprevistos e momentos não produtivos do time (o chamado fator de foco).

O ideal é usar essas abordagens em conjunto. Primeiro calcula-se a velocidade através do cálclo de recursos (aplicando o fator de foco adequado). Compara-se a velocidade obtida com a velocidade dos sprints passados para eventuais ajustes. Após incluir estórias de acordo com esta velocidade, faz-se uma análise de aproximação pelo sentimento possivelmente incluindo ou removendo estórias.

Quebrar uma estória em tarefas é útil para obter estimativas mais precisas. Além disso, melhora a eficiência dos daily meetings.

A melhor forma de manter um backlog do sprint é um quadro de tarefas como este aqui:



Notar:
  • Área para estórias (e tarefas) não iniciadas (mas planejadas), em execução e prontas.
  • Ordem de importância de cima para baixo.
  • Gráfico burndown
  • Área específica para tarefas não planejadas
  • Área específica para tarefas não incluídas no backlog, caso sobre tempo.

ESTÓRIAS NÃO NEGOCIAIS

Em todo Sprint existem tarefas que não constituem entregáveis, nem estão ligadas a nenhuma estória específica, enfim, não adicionam valor diretamente ao produto. São coisas como Configurar e manutenir o servidor de integração contínua, ou refatorar determinada camada da aplicação. Encarar estas tarefas normalmente como itens do backlog do produto não é bom porque naturalmente o PO vai negligenciá-las na hora de priorizar. Eis algumas possíveis soluções:

  • Evitar estórias não negociais. Tentar ao máximo adicionar valor negocial a este tipo de estória e deixar que o PO priorizar normalmente.
  • Verificar se a tarefa pode ser realizada como parte de outra estória negocial.
  • Manter um backlog separado de estórias não negociais e incluir algumas em cada sprint, tentando conscientizar o PO sobre sua importância (é possível usar o cálculo da velocidade para barganhar!)

REUNIÃO DIÁRIA

A reunião diária é basicamente “by the book”. O time se reúne diante do quadro de tarefas do backlog do sprint, responde às três perguntas básicas e cada membro atualiza o quadro enquanto fala.

REVIEW

Esta reunião tende a ser subestimada, mas é importante principalmente porque:
  • O time obtém crédito pelo seu trabalho.
  • Outras pessoas ficam sabendo no que o time está trabalhando.
  • Atrai feedbacks importantes dos clientes.
  • Força o time a terminar os sprints com estórias realmente prontas.
Em uma review, não esquecer:
  • Apresentar claramente o objetivo do sprint
  • Foco em mostrar o produto funcionando.
  • Manter sempre em nível negocial
  • Se possível, deixe a audiência usar o produto.

RETROSPECTIVA

Essa é a segunda reunião mais importante do SCRUM. Como devem ser organizadas:
  • Aloque de 1 a 3 horas, dependendo de quanto discussão é prevista.
  • O time, o Scrum Master e o PO devem participar.
  • A reunião deve ocorrer em uma sala isolada.
  • Alguém é designado secretário
  • O scrum master exibe o sprint backlog e com ajuda do time faz um resumo do sprint, incluindo acontecimentos importantes e decisões relevantes.
  • Cada pessoa, na sua vez, fala, sem ser interrompida, o que achou bom, o que poderia ter sido melhor e o que gostaria de fazer diferente no próximo sprint.
  • Compara-se a velocidade estimada e a real. Havendo grande discrepância, discute-se as possíveis causas.
  • No final o scrum master resume as sugestões concretas sobre o que pode ser melhorado para o próximo sprint.
  • Faz-se uma votação para decidir quais destas sugestões devem ser levadas a cabo no sprint que vai iniciar.

CONCLUSÃO

Obviamente há muito mais no livro do que foi enumerado aqui. Em especial, a parte de múltiplos times e times distribuídos, deixada de fora aqui por motivos de espaço, são bastante interessantes. Além disso, existem diversas dicas de como lidar com situações comuns que encontramos no dia a dia de um time que usa SCRUM. Enfim, trata-se de uma excelente leitura!

sábado, 12 de junho de 2010

Apache Commons: Lang

Continuando a série sobre as bibliotecas apache commons, Este post irá se aprofundar nos componentes da biblioteca Lang, cujo principal objetivo é estender as funcionalidades das classes do pacote java.lang. Além disso, a commons Lang inclui componentes de uso comum a outras bibliotecas.

Existem vários componentes do tipo “XXXUtils” na biblioteca commons Lang. Seus métodos, estáticos e autossuficientes, funcionam como funções globais presentes em outras tecnologias.

Devido a diversidade dos componentes desta biblioteca, examinaremo-os por categoria de acordo com as funcionalidades que julguei mais interessantes:

Manipulação de Strings

Suporte a manipulação de String é, sem dúvida, o ponto forte desta biblioteca. Existe uma série de componentes com este propósito, sendo os principais:
  • StringUtils - Encapsula uma série de funcionalidades null-safe de propósito geral que atuam sobre Strings. Minhas favoritas:
    • isEmpty/isBlank - Verifica se uma string contém texto. Uma string empty (vazia) seria o equivalente a “” e uma string blank (branca) cotém apenas caracteres brancos “    ”.
    • upperCase/lowerCase/swapCase/capitalize/uncaptalize - Mudam a capitalização de uma String. Atenção para o método captalize que coloca em caixa alta apenas o primeiro caractere. Nice hum?
    • isAlpha/isNumeric/isWhitespace/isAsciiPrintable - Faz verificações sobre uma string. IsNumeric é bem legal, mas seria mais útil se pudéssemos aferir sobre o tipo de numérico, algo como isInteger ou isShort.
    • abbreviate - Faz abreviação de uma string usando reticências.
    • difference - Compara duas Strings, retornando suas diferenças.
  • RandomStringUtils - Ajuda na criação de string randômicos, úteis na geração de senhas, por exemplo.
  • WordUtils  - Contém métodos que manipulam palavras de um texto, seja obtendo as iniciais (initials) ou colocando-as em caixa alta (captalize)
  • StrSubstitutor – Substitui variáveis em uma string por valores pré-definidos.

Exemplos StringUtils

String nullString = null;
String emptyString = "";
String blankString = "  ";
String regularString = "apache commons lang";

StringUtils.isEmpty(nullString); // true
StringUtils.isEmpty(emptyString);// true
StringUtils.isEmpty(blankString);// false
StringUtils.isEmpty(regularString);// false

StringUtils.isBlank(nullString); // true
StringUtils.isBlank(emptyString); // true
StringUtils.isBlank(blankString); // true
StringUtils.isBlank(regularString); // false


String lowcase = "lang";
  String uppercase = "LANG";
  String nullString = null;

  StringUtils.upperCase(lowcase); // LANG
  StringUtils.upperCase(uppercase); // LANG
  StringUtils.upperCase(nullString); // null

  StringUtils.lowerCase(lowcase); // lang
  StringUtils.lowerCase(uppercase);// lang
  StringUtils.lowerCase(nullString);// null

  StringUtils.swapCase(lowcase); // LANG
  StringUtils.swapCase(uppercase);// lang
  StringUtils.swapCase(nullString);// null

  StringUtils.capitalize(lowcase); // Lang
  StringUtils.capitalize(uppercase);// LANG
  StringUtils.capitalize(nullString);// null

  StringUtils.uncapitalize(lowcase); // lang
  StringUtils.uncapitalize(uppercase);// lANG
  StringUtils.uncapitalize(nullString);// null


String onlyAlphaString = "abcd";
  String onlyNumericString = "123";
  String mixString = "a1b 2c3";
  String blackString = "  ";

  StringUtils.isAlpha(onlyAlphaString); // true
  StringUtils.isAlpha(onlyNumericString); // false
  StringUtils.isAlpha(mixString); // false
  StringUtils.isAlpha(blackString); // false

  StringUtils.isNumeric(onlyAlphaString); // false
  StringUtils.isNumeric(onlyNumericString); // true
  StringUtils.isNumeric(mixString); // false
  StringUtils.isNumeric(blackString); // false

  StringUtils.isWhitespace(onlyAlphaString); // false
  StringUtils.isWhitespace(onlyNumericString); // false
  StringUtils.isWhitespace(mixString); // false
  StringUtils.isWhitespace(blackString); // true




String bigString = "this string is too big to fit you application's grid";

  String smallerString = StringUtils.abbreviate(bigString, 30);

  System.out.println(smallerString); // this string is too big to f...






String stringOne = "Luke, I'm your father!";
String stringTwo = "Luke, I'm your uncle!"; 
StringUtils.difference(stringOne, stringTwo); //uncle!
Exemplo WordUtils

String name = "carla gabriele batista dos santos";
  
  WordUtils.initials(name);//cgbds
  WordUtils.capitalize(name);//Carla Gabriele Batista Dos Santos



Exemplo StrSubstitutor

Map variablesMap = new HashMap();
   variablesMap.put("var1", "first variable");
   variablesMap.put("var2", "second variable");
   String templateString = "Let's print ${var1} and ${var2}";
   StrSubstitutor sub = new StrSubstitutor(variablesMap);
   String resolvedString = sub.replace(templateString);
   
System.out.println(resolvedString); //Let's print first variable and second variable



ObjectUtils e ClassUtils

Estes componentes merecem uma menção honrosa a parte. ObjectUtils pode ser usado para efetuar operações corriqueiras como comparações e obtenções de hashCode de forma null-safe. ClassUtils contém método para obtenção de uma série de informações a respeito de uma ou mais classes, como as interfaces que ela implementa e superclasses que estende, o pacote no qual se localiza, verificar se é uma classe interna, se pode ser assinalada para uma referência de um outro tipo, entre outros, e tudo isso de forma null-safe.

Integer intVariable = null;
  Integer anotherIntVariable = 5;
  
  ObjectUtils.hashCode(intVariable); //0
  
  ObjectUtils.toString(intVariable); //""
  
  ObjectUtils.equals(intVariable, anotherIntVariable); //false
  
 ObjectUtils.max(intVariable, anotherIntVariable); // 5 (podia ser genérico né?)



System.out.println(ClassUtils.getAllInterfaces(Integer.class)); // [interface java.lang.Comparable, interface java.io.Serializable]
  
  ClassUtils.getAllSuperclasses(Integer.class); //[class java.lang.Number, class java.lang.Object]
  
  ClassUtils.getPackageName(Integer.class); //java.lang
  
  ClassUtils.isInnerClass(Integer.class); //false
  
  ClassUtils.isInnerClass(Integer.class); //false

  ClassUtils.isAssignable(Integer.class, Number.class); //true





Builders

Esta categoria inclui 4 componentes que auxiliam na implementação de 4 métodos básicos, em especial para classes de domínio, de qualquer sistema: EqualsBuilder, HashCodeBuilder, CompareToBuilder e toStringBuilder. Através delas é possível obter uma implementação correta e eficiente dos métodos equals, hashCode, compareTo e toString, respectivamente, apenas informando as propriedades envolvidas.

Além disso, todos os componentes possuem métodos alternativos que permitem a execução de forma reflexiva, incluindo todas as propriedades. Nestes casos, é possível especificar propriedades a serem ignoradas, se for o caso.

public class Person implements Comparable {

 private String name;

 private Integer age;

 private Float weight;

 private Float height;

 private Person mother;

 /**
  * São consideradas iguais duas pessoas com mesmo nome, idade e filhas da
  * mesma mãe.
  */
 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Person other = (Person) obj;

  return new EqualsBuilder().append(age, other.age).append(mother,
    other.mother).append(name, other.name).isEquals();

  // Implementação alternativa que usa reflexão. É preciso informar os
  // campos a serem ignorados na compração para manter equivalência com a
  // implementação a cima.
  //
  // return EqualsBuilder.reflectionEquals(this, obj, Arrays.asList(
  // "weight", "height"));

 }

 /**
  * cálculo do hash code consistente com equals.
  */
 @Override
 public int hashCode() {

  return new HashCodeBuilder(17, 37).append(name).append(age).append(
    mother).toHashCode();

  // Implementação alternativa que usa reflexão. É preciso informar os
  // campos a serem ignorados. para manter equivalência com a
  // implementação a cima.
  //
  // return HashCodeBuilder.reflectionHashCode(this,
  // Arrays.asList("weight",
  // "height"));

 }

 /**
  * Define a representação em forma de String de um objeto da classe Person
  */
 @Override
 public String toString() {

  return new ToStringBuilder(this).append("name", name)
    .append("age", age).toString();

  // Implementação alternativa que usa reflexão. Não é possível informar
  // atributos a serem ignorados, portanto esta implementação não é
  // equivalente àquela a cima.
  //
  // return ToStringBuilder.reflectionToString(this);
 }

 /**
  * Determina forma de comparar objetos do tipo Person.
  */
 @Override
 public int compareTo(Person o) {
  return new CompareToBuilder().append(this.name, o.name).append(
    this.age, o.age).toComparison();

  // Implementação alternativa que usa reflexão. É preciso informar os
  // campos a serem ignorados. para manter equivalência com a
  // implementação a cima.
  //
  // return CompareToBuilder.reflectionCompare(this, o,
  // Arrays.asList("weight", "height","mother"));
 }

//getter e setter omitidos
} 

Math

A biblioteca commons lang inclui alguns componentes com funcionalidades matemáticas básicas. (as mais avançadas ficam na bilbioteca Math) Destaque para as classes que representam intervalos numéricos (IntRange, LongRange, FloatRange e DoubleRange), para a classe Fraction, que representa um número fracionário e para NumberUtils, que disponibiliza métodos utilitários interessantes.

IntRange firstRange = new IntRange(0, 10);
  IntRange secondRange = new IntRange(6,13);
  IntRange thirdRange = new IntRange(11,15);
  
  
  firstRange.containsInteger(5); //true
  firstRange.containsInteger(10); //true. ambos liites são inclusivos.
  firstRange.containsInteger(15); // false
  
  secondRange.getMaximumInteger(); //13
  secondRange.getMinimumInteger(); // 6
  
  firstRange.overlapsRange(secondRange); // true
  firstRange.overlapsRange(thirdRange); // false



Outros

Além dos componentes já mencinados, existem alguns outros que vale apena conferir, como aqueles relacioandos a tempo (destque para StopWatch) e para criação de tipe-safes enums que, devido a sua flexibilidade, continuam sendo muito utilizadas apesar das enumerações já terem sido padonizadas na versão 5 da linguagem.

domingo, 23 de maio de 2010

Apache Commons - BeanUtils - English Version

First of all I'd like to apologize for taking so long to update this blog. Lots of work to do, thanks God, but I'll try not to let it happen again.

Apache commons is a project dedicated to create reusable components. But that, of course, you already knew. Today I am inaugurating a series of posts whose goal is to delve into these components by exposing the available features, of which the details are ignored by most developers.

The project is divided into a variety of categories of components (FileUpload, Lang, Net, Collections, etc. ..). This post in particular will focus on just one: BeanUtils. First, however, it's worth reinforcing two important concepts: reflection and Java Beans.

Reflection, Introspection and Intercession

There is some confusion about these terms in the community (particularly in relation to the first two). Being quick and dirty, reflection is one's language's ability to manipulate, at runtime, elements of its own structure, such as classes, methods and properties. Introspection is a special kind of reflection limited to examining those factors, without changing them. Intercession would be just the other side of the coin:  change, at runtime, classes and methods of objects (http://goo.gl/dMZL in portuguese)

Despite the name of the package (java.lang.reflect), what Java provides us is actually just introspection. As we shall see the BeanUtils library tries to provide us with a basic form of intercession.

Java Beans

Java beans are a special type of class, which follow a naming standard defined in a specification (http://goo.gl/3fGL). That's it :P.

BeanUtils

BeanUtils is a library that combines the concepts of introspection and Java Beans, offering components that provide:

  • Access to properties and methods of Java Beans in an easier way, including integrated type conversion.
  • Dynamic definition of beans, a basic form of intercession. 

Access to properties via introspection
For the examples, let us consider the classes  JavaBean and AnotherJavaBean adhering to the Java Beans standards:

package main;

import java.util.List;

public class JavaBean {
 
 private String stringProp;
 
 private Integer intProp;
 
 private List listProp;
 
 private AnotherJavaBean anotherJavaBeanProp;


 public AnotherJavaBean getAnotherJavaBeanProp() {
  return anotherJavaBeanProp;
 }

 public void setAnotherJavaBeanProp(AnotherJavaBean anotherJavaBeanProp) {
  this.anotherJavaBeanProp = anotherJavaBeanProp;
 }

 public String getStringProp() {
  return stringProp;
 }

 public void setStringProp(String stringProp) {
  this.stringProp = stringProp;
 }

 public Integer getIntProp() {
  return intProp;
 }

 public void setIntProp(Integer intProp) {
  this.intProp = intProp;
 }

 public List getListProp() {
  return listProp;
 }

 public void setListProp(List colProp) {
  this.listProp = colProp;
 }

}

package main;

public class AnotherJavaBean {

 private Short shortProp;

 public Short getShortProp() {
  return shortProp;
 }

 public void setShortProp(Short shortProp) {
  this.shortProp = shortProp;
 }

}

To get the value of "stringProp" property of a JavaBean class instance via its getter method using the Java API you need to do something like the code lines below:


public static void main(String[] args) {

  // Creating an instance to be dynamically accessed
  JavaBean beanTest = new JavaBean();
  beanTest.setStringProp("test String");

  // Getter method name. In a more general scenario, this string
  //would have to be assembled dynamically.
  String nameGetter = "getStringProp";

  // Getting the class object of the class to be manipulated.
  Class clazz = JavaBean.class;

  try {

   // Getting instance of the Method class for the method to be invoked.
   Method stringPropGetter = clazz.getMethod(nameGetter);   
   
   //The invoke method of the Method class executes the method.
   String propertyValue = (String) stringPropGetter
     .invoke(beanTest);

   // Printing the value of the property
   System.out.println(propertyValue);

  } catch (SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }


Using the component PropertyUtils to perform the same task, the code looks like this:

/**
  * @param args
  */
 public static void main(String[] args) {

  // Creating an instance to be dynamically accessed
  JavaBean beanTest = new JavaBean();
  beanTest.setStringProp("Test String");

  //We use the property name. The name of the getter is derived internally by the API.
  String propertyName = "stringProp";

  try {
   
   //Getting the property value. Just pass the object and the name of the property.
   String propertyValue = (String) PropertyUtils.getProperty(beanTest,
     propertyName);
   
   // Printing the value of the property
   System.out.println(propertyValue);
   
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }



Besides the more compact code, it is worth noting the smaller number of exceptions to be treated, and how the component takes advantage of the Java Beans' naming standards to automatically derive the name of the getter method for property requested.

Besides access to simple properties, the component PropertyUtils provides facilities to access  indexed properties:

/**
  * @param args
  */
 public static void main(String[] args) {
  //  Creating an instance to be dynamically accessed
  JavaBean beanTest = new JavaBean();
  List list = Arrays.asList(1, 2, 3, 4, 5);
  beanTest.setListProp(list);

  //We use the property name. The name of the getter is derived internally by the API.
  String propertyName = "listProp";

  try {
   // Getting the property value. Just pass the object and the name of the property.
   Integer propertyValue = (Integer) PropertyUtils
     .getIndexedProperty(beanTest, propertyName, 3);

   // Printing the value of the property
   System.out.println(propertyValue);

  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }


and nested

/**
  * @param args
  */
 public static void main(String[] args) {
  // Creating an instance to be dynamically accessed
  JavaBean beanTest = new JavaBean();
  AnotherJavaBean anotherBeanTest = new AnotherJavaBean();
  anotherBeanTest.setShortProp((short) 1);
  beanTest.setAnotherJavaBeanProp(anotherBeanTest);

  // We use the property name. The name of the getter is derived internally by the API.
  String nameProperty = "anotherJavaBeanProp.shortProp";
  
  try {
   //Getting the property value. Just pass the object and the name of the property.
   Short propertyValue = (Short) PropertyUtils.getNestedProperty(beanTest, nameProperty);
   
   // Printing the value of the property
   System.out.println(propertyValue);
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }



Besides access them, you can assign values to properties of objects, and you can do it through very similar methods  (including for indexed and nested properties.)

Another interesting feature, provided by the BeanUtils component, is copying properties between objects. Through the methods copyProperty and copyProperties you can copy the value of one or all of the properties of similar name among beans, even if they are to unrelated classes.

public static void main(String[] args) {
  //instantiating beans to copy properties
  JavaBean oneBean = new JavaBean();
  JavaBean otherBean = new JavaBean();

  //assigning values to properties of the first bean
  oneBean.setIntProp(1);
  oneBean.setStringProp("string");
  oneBean.setListProp(Arrays.asList(0, 1, 2));
  
  try {
   
   //copying the properties of the first to the second bean
   BeanUtils.copyProperties(otherBean, oneBean);
   
   //printing the value of the properties of the second bean
   System.out.println(otherBean.getStringProp());
   System.out.println(otherBean.getIntProp());
   System.out.println(otherBean.getListProp());
   
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  

 }


Speaking of the BeanUtils component, it is worth mentioning it contains methods for accessing and assigning properties just like PropertyUtils, including automatic conversion. The library comes with built in converters and it is possible to register our  own converters in a very simple way.

public class BeanUtilsTest {

 //Class that will convert to a AnotherJavaBean
 public static class AnotherJavaBeanConverter implements Converter {

  //Method gets the class for which the conversion will be done and the value to be converted.
  @Override
  public Object convert(Class arg0, Object arg1) {

   AnotherJavaBean bean = new AnotherJavaBean();
   bean.setShortProp(Short.valueOf(arg1.toString()));

   return bean;
  }

 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  //Creating an instance to be dynamically populated
  JavaBean beanTest = new JavaBean();
  
  //registering converting to AnotherJavaBean
  ConvertUtils.register(new AnotherJavaBeanConverter(),
    AnotherJavaBean.class);

  try {
   // assigning value dynamically. the string "1" will be converted to Integer using the library's standard converter 
   BeanUtils.setProperty(beanTest, "intProp", "1");
   
   //assigning value dinaminamicamente. the integer value 123 is converted using the library's standard converter
   BeanUtils.setProperty(beanTest, "stringProp", 123);
   
   //assigning value dinaminamicamente. the integer value 2 is converted using the convert registered for the class AnotherJavaBean
   BeanUtils.setProperty(beanTest, "anotherJavaBeanProp", 2);

   // Printing the values of the properties of the beanTest
   System.out.println(beanTest.getIntProp());
   System.out.println(beanTest.getStringProp());
   System.out
     .println(beanTest.getAnotherJavaBeanProp().getShortProp());
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
} 
Dynamic Beans
Dynamic beans or DynaBeans allow a basic form of intercession: ie dynamic change in structure (properties) of beans.
Here's an example where we create the same bean JavaBean used in previous examples in a dynamic way:

public static void main(String[] args) {

  String nameStringProp = "stringProp";
  String nameIntProp = "intProp";
  String nameListProp = "listProp";
  String nameAnotherJavaBeanProp = "anotherJavaBeanProp";
  String shortPropAtAnotherJavaBean = "anotherJavaBeanProp.shortProp";

 
  
  //Creating a DynaProperty vector. A DynaProperty Instance represents a property in the DynaBean
  DynaProperty[] props = new DynaProperty[] {
    new DynaProperty(nameStringProp, String.class),
    new DynaProperty(nameIntProp, Integer.class),
    new DynaProperty(nameListProp, List.class),
    new DynaProperty(nameAnotherJavaBeanProp, AnotherJavaBean.class) };

 
  
  //Creating a DynaBean class, named "JavaBean" with the above defined properties.
  BasicDynaClass dynaClass = new BasicDynaClass("JavaBean", null, props);

  try {

   
   // Creating an instance of JavaBean
   DynaBean javaBeanTest = dynaClass.newInstance();

   // Assigning values to properties
   javaBeanTest.set(nameStringProp, "Test String");
   javaBeanTest.set(nameIntProp, 200);
   javaBeanTest.set(nameListProp, Arrays.asList(1, 2, 3, 4));
   AnotherJavaBean anotherJavaBean = new AnotherJavaBean();
   anotherJavaBean.setShortProp((short) 13);
   javaBeanTest.set(nameAnotherJavaBeanProp, anotherJavaBean);

   // printing the value of attributes. Note that the dynamic access methods work as expected even with DynaBeans.
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nameStringProp));
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nameIntProp));
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nameListProp));
   System.out.println(PropertyUtils.getNestedProperty(javaBeanTest,
     shortPropAtAnotherJavaBean));

  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InstantiationException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }



It is worth noting the use of classes DynaClass (through its subclass BasicDynaClass) and DynaBean. Another important point is the indistinct use of dynamic access methods we saw earlier.

Besides basic DynaBean (which we saw in the previous example) the library offers other types of DynaBeans such as the ResultSetDynaBeans and RowSetDynaBeans. The most interesting variety of DynaBean, however, is the LazyDynaBean. The main feature of this component is the creation of properties at the time of the assignment (no need to do it previously).

Conclusion

These are therefore the most important components of the apache commons BeanUtils library. Wait soon for other posts about co-sisters libraries!


















segunda-feira, 17 de maio de 2010

Apache Commons - BeanUtils

Primeiramente gostaria de me desculpar pela demora na atualização do blog. Muito trabalho, graças a Deus, mas vou me esforçar para que isso não aconteça novamente.
Apache commons é um projeto apache dedicado a criação de componentes reutilizáveis. Mas isto, é claro, você já sabia. Inauguro hoje uma série de posts cujo objetivo é se aprofundar nestes componentes expondo as funcionalidades disponibilizadas, cujos detalhes são ignorados pela maioria dos desenvolvedores.
O projeto é dividido em uma variedade de categorias de componentes (FileUpload, Lang, Net, Collections, etc..). Este post em particular irá se concentrar em apenas uma: BeanUtils. Primeiramente, no entanto, vale reforçar dois conceitos importantes: reflexão e java beans.
Reflexão, Introspecção e Intercessão
Existe alguma confusão a respeito destes termos na comunidade (em especial em relação aos dois primeiros). Sendo rápido e rasteiro, reflexão é a habilidade de uma linguagem de manipular, em tempo de execução, elementos de suas própria estrutura, como classes, métodos e propriedades. Introspecção é um tipo especial de reflexão limitada a examinar estes elementos, sem alterá-los. Intercessão seria justamente o outro lado da moeda: alteração em tempo de execução de classes e métodos dos objetos (http://goo.gl/dMZL).
A pesar do nome do pacote (java.lang.reflect), o que java nos oferece é na verdade apenas introspecção. Como veremos adiante a biblioteca BeanUtils tenta nos fornecer uma forma básica de intercessão.
Java Beans
Java beans são um tipo especial de classe, que segue um padrão de nomenclatura definido em uma especificação (http://goo.gl/3fGL). Só isso :P.
BeanUtils
BeanUtils é uma biblioteca que alia os conceitos de introspecção e java Beans, disponibilizando componentes que provêem:
  • Acesso a propriedades e métodos de java beans de forma facilitada, incluindo conversão de tipos integrada.
  • Definição dinâmica de beans, uma forma básica de intercessão.
Acesso a Propriedades via Introspecção
Para os exemplos, vamos considerar as classes JavaBean e AnotherJavaBean aderentes aos padrões JavaBeans:


package main;

import java.util.List;

public class JavaBean {
 
 private String stringProp;
 
 private Integer intProp;
 
 private List listProp;
 
 private AnotherJavaBean anotherJavaBeanProp;


 public AnotherJavaBean getAnotherJavaBeanProp() {
  return anotherJavaBeanProp;
 }

 public void setAnotherJavaBeanProp(AnotherJavaBean anotherJavaBeanProp) {
  this.anotherJavaBeanProp = anotherJavaBeanProp;
 }

 public String getStringProp() {
  return stringProp;
 }

 public void setStringProp(String stringProp) {
  this.stringProp = stringProp;
 }

 public Integer getIntProp() {
  return intProp;
 }

 public void setIntProp(Integer intProp) {
  this.intProp = intProp;
 }

 public List getListProp() {
  return listProp;
 }

 public void setListProp(List colProp) {
  this.listProp = colProp;
 }

}


package main;

public class AnotherJavaBean {

 private Short shortProp;

 public Short getShortProp() {
  return shortProp;
 }

 public void setShortProp(Short shortProp) {
  this.shortProp = shortProp;
 }

}





Para obter o valor da propriedade “stringProp” de uma instancia da classe JavaBean através do seu método getter usando a API Java é preciso fazer algo parecido com o código das linhas abaixo:

// Criando uma instancia para ser acessada dinamicamente
  JavaBean beanTeste = new JavaBean();
  beanTeste.setStringProp("String de teste");

  // Nome do metodo getter. Em um cenário mais generalista, esta string
  // teria que ser montada dinamicamente.
  String nomeGetter = "getStringProp";

  // Obtendo o class da classe a ser manipulada.
  Class clazz = JavaBean.class;

  try {

   // Obtendo instância da classe Method para o método a ser invocado.
   Method stringPropGetter = clazz.getMethod(nomeGetter);

   // O método invoke da classe Method executa o método, em uma
   // instancia e com argumentos passados por parâmetro. Neste caso não
   // há argumentos.
   String valorPropriedade = (String) stringPropGetter
     .invoke(beanTeste);

   // Imprimindo no console o valor da propriedade.
   System.out.println(valorPropriedade);

  } catch (SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 

Usando o componente PropertyUtils para executar a mesma tarefa, o código fica assim:

// Criando uma instancia para ser acessada dinamicamente
  JavaBean beanTeste = new JavaBean();
  beanTeste.setStringProp("String de teste");

  //Usa-se o nome da propriedade. O nome do getter é derivado internamente pela API.
  String nomePropriedade = "stringProp";

  try {
   
   //Obtendo o valor da propriedade. Basta passar o objeto e o nome da propridade.
   String valorPropriedade = (String) PropertyUtils.getProperty(beanTeste,
     nomePropriedade);
   
   // Imprimindo no console o valor da propriedade.
   System.out.println(valorPropriedade);
   
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }



Além do código mais compacto, vale observar a quantidade reduzida de exceções a serem tratadas, e o fato do componente tomar vantagem dos padrões de nomenclatura Java Bean para derivar automaticamente o nome do método getter para a propriedade requisitada.
Além de acesso a propriedades simples, o componente PropertyUtils fornece facilidades no acesso a propriedades indexadas:

// Criando uma instancia para ser acessada dinamicamente
  JavaBean beanTeste = new JavaBean();
  List list = Arrays.asList(1, 2, 3, 4, 5);
  beanTeste.setListProp(list);

  //Usa-se o nome da propriedade. O nome do getter é derivado internamente pela API.
  String nomePropriedade = "listProp";

  try {
   // Obtendo o valor da propriedade. Aqui passamos o objeto, o nome da
   // propriedade e indice a ser acessado.
   Integer valorPropiedade = (Integer) PropertyUtils
     .getIndexedProperty(beanTeste, nomePropriedade, 3);

   // Imprimindo no console o valor da propriedade.
   System.out.println(valorPropiedade);

  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }


e aninhadas:

// Criando uma instancia para ser acessada dinamicamente
  JavaBean beanTeste = new JavaBean();
  AnotherJavaBean anotherBeanTest = new AnotherJavaBean();
  anotherBeanTest.setShortProp((short) 1);
  beanTeste.setAnotherJavaBeanProp(anotherBeanTest);

  // Usa-se o nome da propriedade. O nome do getter é derivado
  // internamente pela API.
  String nomePropriedade = "anotherJavaBeanProp.shortProp";
  
  try {
   Short valorPropriedade = (Short) PropertyUtils.getNestedProperty(beanTeste, nomePropriedade);
   
   System.out.println(valorPropriedade);
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }



Além de acessar, é possível atribuir valores as propriedades dos objetos, de forma muito semelhante a usada para acessar os dados (inclusive para propriedades indexadas e aninhadas.)
Outra funcionalidade interessante, fornecida pelo componente BeanUtils é copia de propriedades entre objetos. Através dos métodos copyProperties e copyProperty é possível copiar o valor de uma ou todas as propriedades de nome semelhante entre beans, mesmo que sejam de classes não relacionadas.

JavaBean oneBean = new JavaBean();
  JavaBean otherBean = new JavaBean();

  oneBean.setIntProp(1);
  oneBean.setStringProp("string");
  oneBean.setListProp(Arrays.asList(0, 1, 2));
  
  try {
   BeanUtils.copyProperties(otherBean, oneBean);
   
   System.out.println(otherBean.getStringProp());
   System.out.println(otherBean.getIntProp());
   System.out.println(otherBean.getListProp());
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  


Falando do componente BeanUtils, vale ressaltar ele contém métodos de acesso e atribuição de propriedade semelhantes a PropertyUtils, incluindo conversão automática. A biblioteca vem com converters próprios mais é possível cadastrar os seus próprios de maneira simples.

public class BeanUtilsTest {

 //Classe que fará a conversão para um AnotherJavaBean
 public static class AnotherJavaBeanConverter implements Converter {

  //Método recebe a classe para a qual será feita a conversão e o valor a ser convertido.
  @Override
  public Object convert(Class arg0, Object arg1) {

   AnotherJavaBean bean = new AnotherJavaBean();
   bean.setShortProp(Short.valueOf(arg1.toString()));

   return bean;
  }

 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  //criando instancia a ser populada dinamicamente
  JavaBean beanTest = new JavaBean();
  
  //registrando converter para o AnotherJavaBean
  ConvertUtils.register(new AnotherJavaBeanConverter(),
    AnotherJavaBean.class);

  try {
   // atribuindo valor dinaminamicamente. a String "1" será convertida para Integer usando converters padrão da biblioteca
   BeanUtils.setProperty(beanTest, "intProp", "1");
   
   //atribuindo valor dinaminamicamente. o valor inteiro 123 será convertido usando converters padrão da biblioteca 
   BeanUtils.setProperty(beanTest, "stringProp", 123);
   
   //atribuindo valor dinaminamicamente. o valor inteiro 2 será convertido usando converter registrado para a classe AnotherJavaBean
   BeanUtils.setProperty(beanTest, "anotherJavaBeanProp", 2);

   System.out.println(beanTest.getIntProp());
   System.out.println(beanTest.getStringProp());
   System.out
     .println(beanTest.getAnotherJavaBeanProp().getShortProp());
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
}


Beans Dinâmicos
Beans dinâmicos ou DynaBeans possibilitam uma forma básica de intercessão: ou seja mudança dinâmica na estrutura (propriedades) dos beans.
Segue um exemplo onde criamos o mesmo bean JavaBean usado  nos exemplos anteriores de forma dinâmica:

String nomeStringProp = "stringProp";
  String nomeIntProp = "intProp";
  String nomeListProp = "listProp";
  String nomeAnotherJavaBeanProp = "anotherJavaBeanProp";
  String shortPropEmAnotherJavaBean = "anotherJavaBeanProp.shortProp";

  // criando um vetor de DynaProperty, que representa uma propriedade de
  // um DynaBean
  DynaProperty[] props = new DynaProperty[] {
    new DynaProperty(nomeStringProp, String.class),
    new DynaProperty(nomeIntProp, Integer.class),
    new DynaProperty(nomeListProp, List.class),
    new DynaProperty(nomeAnotherJavaBeanProp, AnotherJavaBean.class) };

  // Criando uma classe de DynaBeans, chamada 'JavaBean' com as
  // propriedades definidas a cima.
  BasicDynaClass dynaClass = new BasicDynaClass("JavaBean", null, props);

  try {

   // Criando uma instância de JavaBean
   DynaBean javaBeanTest = dynaClass.newInstance();

   // Atribuindo valores as propriedades
   javaBeanTest.set(nomeStringProp, "string Teste");
   javaBeanTest.set(nomeIntProp, 200);
   javaBeanTest.set(nomeListProp, Arrays.asList(1, 2, 3, 4));
   AnotherJavaBean anotherJavaBean = new AnotherJavaBean();
   anotherJavaBean.setShortProp((short) 13);
   javaBeanTest.set(nomeAnotherJavaBeanProp, anotherJavaBean);

   // imprimindo o valor dos atributos. Note que os métodos de acesso
   // dinâmico funcionam como esperado mesmo com DynaBeans.
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nomeStringProp));
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nomeIntProp));
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nomeListProp));
   System.out.println(PropertyUtils.getNestedProperty(javaBeanTest,
     shortPropEmAnotherJavaBean));

  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InstantiationException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

Vale observar o uso das classes DynaClass (através de sua subclasse BasicDynaClass) e DynaBean. Outro ponto importante é o uso indistinto dos métodos de acesso dinâmico que vimos anteriormente.
Além de DynaBean básicos (que seriam os do exemplo anterior) a biblioteca disponibiliza outros tipos de DynaBeans, como por exemplo os ResultSetDynaBeans e RowSetDynaBeans. A variedade mais interessante de DynaBean, no entanto, é o LazyDynaBean. A principal característica deste componente é a criação de propriedades no momento da atribuição (não há necessidade de fazer isso previamente).

String nomeStringProp = "stringProp";
  String nomeIntProp = "intProp";
  String nomeListProp = "listProp";
  String nomeAnotherJavaBeanProp = "anotherJavaBeanProp";
  String shortPropEmAnotherJavaBean = "anotherJavaBeanProp.shortProp";

  DynaBean javaBeanTest = new LazyDynaBean();

  //Criando e atribuindo valores as propriedades
  javaBeanTest.set(nomeStringProp, "string Teste");
  javaBeanTest.set(nomeIntProp, 200);
  javaBeanTest.set(nomeListProp, Arrays.asList(1, 2, 3, 4));
  AnotherJavaBean anotherJavaBean = new AnotherJavaBean();
  anotherJavaBean.setShortProp((short) 13);
  javaBeanTest.set(nomeAnotherJavaBeanProp, anotherJavaBean);

  try {
   // imprimindo o valor dos atributos. Note que os métodos de acesso
   // dinâmico funcionam como esperado mesmo com DynaBeans.
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nomeStringProp));
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nomeIntProp));
   System.out.println(PropertyUtils.getSimpleProperty(javaBeanTest,
     nomeListProp));
   System.out.println(PropertyUtils.getNestedProperty(javaBeanTest,
     shortPropEmAnotherJavaBean));
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }



Conclusão
Estes são, portanto, os componentes mais importante da biblioteca BeanUtils da apache commons. Esperem em breve por outros posts a respeito de bibliotecas co-irmãs!





















terça-feira, 27 de abril de 2010

Agile Design

INTRODUCTION
As a developer, I've always been fascinated by software design. Usually defined as the activity to specify software components (classes) and its interactions, I consider it both interesting and challenging. When I first get in touch with agile principles (SCRUM and XP in particular) I realized that there is a huge gap between what I learned back at college and what the methodologies enforce.

UP FRONT DESIGN
I learned back at college that design is the software engineering phase that bridges requirements specification and the coding. The analyst defines WHAT to do, the design HOW to do it and the programmer just DO it. The design phase products are documents and diagrams to be used by the programmer to code the software as the analyst idealized it. This approach is called up front design and it doesn't come without its drawbacks and challenges.

  • It is very hard (if not impossible) to come up, in advance, with such a design that both meets all requirements and is flawless.
  • It would be necessary to come up with a design so flexible to accommodate the dreaded change of requirements. Even if possible, what would be the cost, in terms of complexity, of such design?
With SCRUM there's not such thing as design phase. There's a meeting when the product owner detail the sprint backlog items so the analysts can start documenting, the testers can start write tests cases and the developers can start coding. That simple. There's no design at all? Well, not as I learned back at college.

EVOLUTIONARY DESIGN
If its not possible to come up with a design that meets all the requirements, that is flawless and its impossible to avoid requirements changes, what could justify the effort (usually a big one, considering the complexity and level of abstraction required) spent with an up front design? Accepting that coding is design, agile methodologies come up with an approach called evolutionary design.

With that approach, design and coding walk side by side. The design evolves according to the functionalities been developed needs. There's no a formal role as designer nor a particular moment to do the design. Every developer design and redesigns every day.

YAGNI
One of the most intriguing concepts related to evolutionary design is known as YAGNI (You Aren't Gonna Need It). “Always write only the code you need right now, never the one you thing you're gonna need tomorrow.” Even when you are absolutely sure you're gonna need the code and the cost of implementation is zero: just write it when you actually need it.

YAGNI is counter-intuitive because it goes against what is believed to be the greater benefit of a good design: anticipation of complexity and consequent risk mitigation. Nevertheless, there are very good arguments in favor of such approach:
  • Respects the clients ROI: write code that doesn't aggregate any value to the functionality under construction means to disregard the PO prioritization and , in consequence, the client's ROI.
  • Time saving: Time used to write code that is only going to be used in a later iteration may be missed when it comes to deliver the functionalities promised to the actual iteration.
  • Possible changes: To write code in advance is unnecessary risk because the understanding may have been incorrect or the logic/rule may simply change, what originates the need to rewrite the code.

MAKE IT WORK
By now the reader may have came to the conclusion that a evolutionary design projects may end up with no design at all, or a very poor design.

Critics accuse evolutionary design to be over-dependent on the maturity of the team, what is somewhat the true. On that matter, XP defines the role of a coach, who is a more experienced programmer responsible for guiding other developers in technical issues (including design).

Besides, there is a number of practices, from the agile environment or not, I believe should be judiciously used to maintain design quality:
  • Emphasis on tests (unit tests, integration tests, etc): It gives you some confidence during design changes.
  • Continuous Integration: keep the team synchronized with code and find out possible bugs earlier.
  • Pair Program: If the functionality is complex, maybe a god idea to get two developers working on it.
  • White box analysis: Its a good idea to keep an activity of code review to detect design issues that not necessarily show themselves as bugs.
  • Good practices list: To keep a list of design good practices so the developers can refer to it when in doubt. The list could evolve as the project goes and experience is gain.

CONCLUSIONS
The agile wold has no place to up front design on its conceptual manner, as a well defined phase and trying to anticipate all details  of the development of a functionality, but it could benefit from some of it features such as better risk management and strong standardization.

Evolutionary design is an alternative approach indicated by the agile principles, but it must be applied together with other practices in order to keep the quality of the design.

REFERENCES
Great Martin Fowler article on design and XP (http://martinfowler.com/articles/designDead.html)

Article on up front design problems (http://architects.dzone.com/news/great-lies-design-vs)




segunda-feira, 26 de abril de 2010

Design Ágil

INTRODUÇÃO
Como desenvolvedor, sempre fui fascinado por design de software. Comumente definida como a atividade de especificar os componentes de software (classes) e suas interações, considero a tarefa desafiadora e bastante interessante. Quando comecei a entrar em contato com princípios de desenvolvimento ágil (em especial SCRUM e XP), percebi que havia uma grande incompatibilidade entre o que aprendi na faculdade (e acreditava ser a forma correta de fazer design) e o que pregam as metodologias.

UP FRONT DESIGN
Aprendi na faculdade que design é fase da engenharia de software que faz a ponte entre a especificação de requisitos e a construção propriamente dita. O analista decide O QUE fazer, o projetista decide COMO fazer e o programador FAZ. O produto da fase de design são documentos e diagramas que o desenvolvedor irá usar para construir o software que o analista idealizou. Esta abordagem hoje é chamada de up front design e sem dúvida não é livre de seus problemas e desafios:

  • É muito difícil (senão impossível) criar antecipadamente um design tal que atenda todos os requisitos (funcionais e não-funcionais) e esteja livre de falhas.
  • Seria necessário criar um design que fosse flexível suficiente para acomodar as temíveis mudanças de requisitos. Mesmo que seja possível, qual seria o custo em complexidade de um design assim?

No SCRUM não há fase de design. Há uma reunião onde o product owner explica para o time em detalhes as características de cada item do sprint backlog e a partir daí analistas começam a documentar, testers especificam casos de testes e programadores começam a desenvolver. Simples assim. Não tem design? Não da forma como aprendi na faculdade.

EVOLUTIONARY DESIGN
Se não é possível gerar um design que atenda a todos os requisitos, seja livre de falhas e se não é possível evitar mudanças de requisitos, o que justifica o esforço (geralmente grande devido a natureza complexa da atividade) despendido na criação de um up front design? Entendendo que codificar é projetar as metodologias ágeis propõem algo chamado evolutionary design.

Nesta abordagem, o design e codificação andam lado a lado. O design evolui de acordo com as necessidades das funcionalidades sendo construídas. Não há o papel formal de projetista nem um momento específico para desenvolver o design: Todos os desenvolvedores fazem e refazem o design todos os dias.

YAGNI
Um dos conceitos mais intrigantes relacionados a evolutionary design é conhecido pela sigla YAGNI (You Aren't Gonna Need It). “Sempre escreva apenas o código que você precisa agora, nunca o que você vai precisar amanhã” Mesmo que você tenha absoluta certeza de que vai precisar daquele trecho de código e que o custo de escreve-lo seja zero: Deixe para fazê-lo quando for necessário.

YAGNI é contra-intuitivo porque vai contra aquilo que acredita-se ser maior benefício de um um bom design: antecipação de complexidade e consequente redução de riscos. Entretanto, existem bons argumentos em favor desta abordagem:

  • Respeito ao ROI do cliente: Escrever código que não agrega valor a funcionalidade em construção é desrespeitar a priorização do product owner e consecutivamente o ROI do cliente.
  • Economia de tempo: O tempo usado para escrever código que só será usado posteriormente pode fazer falta na hora de entregar as funcionalidades previstas para esta iteração.
  • Possíveis mudanças: Escrever código antecipadamente é um risco (desnecessário) porque o entendimento pode ter sido equivocado ou a lógica/regra pode mudar, gerando a necessidade de reescrever o código.  

FAZENDO EVOLUTIONARY DESIGN FUNCIONAR
Neste ponto, o leitor já deve ter percebido que um projeto que usar evolutionary design corre grandes riscos de acabar mesmo é sem design, ou com um design muito pobre.

Críticos acusam evolutionary design de ser super-dependente da maturidade do time, o que tem um fundo de verdade. Neste sentido, o XP define o papel do Coach, que seria um desenvolvedor mais experiente com a responsabilidade de orientar o time nas decisões técnicas (inclusive de design).

Além disso, existe uma série de práticas, do próprio mundo ágil ou não, que acredito devam ser empregadas criteriosamente de forma a manter a qualidade do design:
  • Ênfase em testes (unitários, de integração, etc..): É importante ter uma boa margem de segurança quando são feitas mudanças de design.
  • Integração contínua: Integrar o código do projeto como um todo (mantendo o time em sincronia) buscando detectar o mais cedo possível possíveis problemas de design.
  • Pair program: Se a funcionalidade for muito complexa, colocar 2 desenvolvedores responsáveis por ela pode ser uma boa ideia.
  • Análise caixa branca: Incluir uma tarefa de inspeção de código a fim de detectar design inadequado (devido ao auto custo, a análise poderia ser feita por amostragem apenas)
  • Lista de boa práticas: Manter uma lista de boas práticas que sirva de orientação aos desenvolvedores. Tal lista seria incrementada ao longo do projeto com a experiência adquirida. 

CONCLUSÕES
O mundo ágil não tem lugar para up front design em sua forma conceitual, como uma fase bem definida e buscando “prever” todas as nuances do desenvolvimento de uma funcionalidade, mas poderia se beneficiar de algumas de suas caraterísticas como redução de riscos e forte padronização.

Evolutionary design é a abordagem alternativa que os métodos ágeis indicam, porém ele deve ser empregada em conjunto com outras práticas que garantam a qualidade do design do software a ser construído.

REFERÊNCIAS
Excelente artigo de Martin Fowler sobre design e XP (http://martinfowler.com/articles/designDead.html)

Artigo sobre problemas de up front design (http://architects.dzone.com/news/great-lies-design-vs)












quinta-feira, 15 de abril de 2010

Flush-mode: Conversation

INTRODUCTION

Jboss Seam is a Java framework for web development which integrates technologies such as Asynchronous JavaScript and XML (AJAX), JavaServer Faces (JSF), Java Persistence (JPA), Enterprise Java Beans (EJB 3.0) and Business Process Management (BPM) into a unified full-stack solution, complete with sophisticated tooling. Its main feature is to easy the use of the technologies it integrates.

I thought about writing a post about jboss seam's main features and why I like it so much, but I won't do it for two reasons:
  1. There are already a lot of material on that topic (here, here, here, here, and here).
  2. The Jboss seam as we know it is coming to its end. The framework is so successful that it was, at least most part of it, incorporated by the JEE6 specification (mainly JSF2 and CDI). The future of the framework is at CDI's portable extensions, integrating the functionalities which were not standardized.



Nevertheless, I believe the actual version is still gonna be used for some time, so its worth to share a few clues related to specific points of the framework. This post in particular is about one of the main features of Jboss Seam: conversations.

CONVERSATION

The concept of conversation was not created by Seam, but it was the seam framework the first one to introduce it as a first class construct. In few words, a conversation is a context to hold application state, which scope is longer than a single request but shorter than the user's http session. A conversation represents a task the user can perform in the application and it is seam's default unit of work.

Under the hood, seam attaches the entity manager to the conversation context, so the entities remain persistent through the unit of work.  Also, it disables the automatic flush of the entity manager  (flush-mode: manual) so the changes don't get propagated to the database prematurely. That responsibility now stands with the developer, which issues a entity manager's flush at the end of the conversation.



The problem with that approach is the potential decrease of business method's re-usability as one method can be the last step of some conversation but not in another. 

AN EXAMPLE

Let's picture an human resources application which domain includes, obviously, employees and departments. It's acceptable to presume that such application includes a CRUD functionality to both models, being possible, in the latter one, to select a chief employee. The employee model includes a flag to determine whether she is a chief or not.

Accepting that a set of business rules are to be applied on a employee update (a conversation), we could come up with the following pseudo-method, responsible for the execution of such rules.

public void editEmployee(Employee employee){

peformRule1();

peformRule2();

peformRule3();

//Synchronize changes in the model with the database at the end of the conversation
this.entityManager.flush(); 


}


On the conversation responsible for editing departments, one of the steps would be exactly to update the chief employee (through the pseudo-method we just saw) and there's where the problem raises because this method executes an unexpected flush before the conversation is over.

public void editDepartamento(Department department, Employee employee){

peformRule1();

peformRule2();

employee.setChiefe(true);

//peforms an unwanted flush
editEmployee(employee); 

peformRule3();

//Synchronize changes in the model with the database at the end of the conversation
this.entityManager.flush(); 


}


For such a simple example, one could suggest some solutions such as force the employee's update to be the last step of the department's editing conversation, or to include a flag parameter to the employee editing method indicating whether it should perform a flush or not. None of these solutions is, nevertheless, adequate. What it's really needed is a way to ensure that the flush will be performed only at the end of a successful conversation, decoupling the database synchronization of the business logic.

//Refactored employee's editing method, receiving a boolean paramether inidicating whether the flush should be executed. Not the best solution!
public void editEmployee(Employee employee, Boolean peformFlush){

peformRule1();

peformRule2();

peformRule3();

if (peformFlush){
this.entityManager.flush(); 
//Synchronize changes in the model with the database at the end of the conversation
}

}

FLUSH MODE CONVERSATION

Even thought it doesn't exists built-in, seam provides mechanisms so we can get the same effect. The following solution is based on seam built-in events, specially one that's rose every time a conversation come to its end. We observe that event, performing a flush when it's needed.

@Name("endConverationObserver")
@Scope(ScopeType.CONVERSATION)
public class EndConverationObserver {

 @In
 private Boolean flushEntityManager;

 @In
 private EntityManager entityManager;

 @Observer(value = "org.jboss.seam.endConversation", create = true)
 public void DetermineflushEntityManager() {
  if (flushEntityManager) {
   this.entityManager.flush();
  }

 }

}

The weak point of such solution appears with the knowledge that not all ended conversations must perform a flush. Particularly, canceled conversations must not or the data will be synchronized with the database anyway. That's why a flag was included, so the component could ask the context whether it should perform the flush or not. It is the programmer's responsibility to feed the context with such boolean variable, whose default value would be true. It could be done, for example, in the actionListener of the cancel button.


@Name("editEmployeeController")
@Scope(ScopeType.CONVERSATION)
public class EditEmployeeController{

 @Out
 private Boolean flushEntityManager;

 @In
 private EntityManager entityManager;

 public String cancel() {
  this.flushEntityManager = false;
                return "editCancel"

 }

}

CONCLUSION

In this post we talked about seam's conversations and how they are usually implemented. An alternative approach was proposed, seeking to increase business methods reusability. Such approach uses bult-in mechanisms to decouple the database synchronization of the business methods.