domingo, 28 de março de 2010

Scrum e o contexto

Quando Scrum se popularizou alguns anos atrás, promoveu uma grande reviravolta na comunidade de desenvolvimento. Isso porque, muito mais do que uma nova metodologia, Scrum prega uma nova abordagem, uma nova filosofia na construção de software - fortemente baseada nas ideias do manifesto ágil.

Quando incentiva práticas como ter um representante do cliente diretamente envolvido no projeto ou manutenção de times auto-gerenciados Scrum influencia diretamente na estrutura, na cultura das organizações – naquilo que convencionou-se chamar de contexto da equipe: o ambiente no qual ela se insere. Obviamente tais mudanças são muito custosas e por vezes impraticáveis.

Com a popularização das metodologias ágeis, e o crescente questionamento em torno de sua real efetividade, surge um grupo que defende mais rigidez na manutenção do contexto da equipe. De acordo com este grupo, estabelecer que um conjunto X de práticas definem uma metodologia ágil, sem levar em consideração o contexto da equipe é, na verdade, um contrassenso. Tais práticas seriam, na verdade, pura burocracia – exatamente uma das coisas que os métodos ágeis buscam eliminar!

Inclusive, vale lembrar que a filosofia ágil não entra no mérito de práticas. O manifesto ágil não fala nada sobre manter o cliente próximo ao time de desenvolvimento ou mesmo sobre ciclos curtos de construção. Esses são conceitos do Scrum e certamente é possível ter um time ágil sem estas características.

Por outro lado, penso que afirmar que a metodologia deve curvar-se ao contexto é descabido. A adoção de uma metodologia ágil requer alguma mudança cultural e na estrutura da organização devido a sua natureza inovadora. Se for para ignorar a abrangência da mudança que a introdução de uma metodologia ágil requer, é melhor nem começar!

O ideal seria, como a maioria das coisas na vida, o caminho do meio: Adaptação do contexto na medida adequada e adoção criteriosa de práticas levando sempre o contexto em consideração. Qual seria então a medida deste equilíbrio? O time sem dúvida. Afinal, não podemos esquecer que indivíduos e sua interação são mais importantes processos e ferramentas.


Referência
 http://xprogramming.com/blog/2009/01/30/context-my-foot/
http://www.noop.nl/2009/02/the-decline-and-fall-of-agilists.html
http://jamesshore.com/Blog/The-Decline-and-Fall-of-Agile.html
http://martinfowler.com/bliki/FlaccidScrum.html 

domingo, 21 de março de 2010

A Page to rule them all

Você é capaz imaginar uma aplicação web/web site composto inteiramente de uma única página? Esta é a proposta do Single Page Interface Manifesto, publicado recentemente por Jose Maria Arranz Santamaria.

Movido inicialmente pela curiosidade, resolvi conferir o tal manifesto. Este post resume a proposta do manifesto e as discussões que ele motivou.
Motivação

A internet foi concebida como uma forma de compartilhar documentos científicos, que comumente contém referências para outros documentos relacionados. Daí sua natureza baseada em páginas e links.

Hoje a internet abriga muito mais que documentos científicos. A possibilidade de gerar conteúdo dinamicamente abriu as portas para aplicações web de propósito geral. Verdade seja dita: hoje o protocolo HTTP é usado para suportar funcionalidades para as quais definitivamente não foi planejado.

Por este motivo desenvolver para a web sempre foi demasiadamente complexo. Pode-se afirmar que toda evolução do desenvolvimento web se deu no sentido de tornar-se mais parecido com o desenvolvimento desktop - mais simples e natural. Neste sentido, vimos o surgimento de front controllers que "capturam" requisições para páginas que sequer existem, criação de frameworks web baseados em eventos, e uso extensível de Ajax para criação de interfaces mais "desktop-like".

SPI (Single Page Interface) seria o último passo desta jornada. Seria possível ter uma aplicação web rodando inteiramente em uma única página- exatamente como uma aplicação desktop roda em uma única janela principal. Esta abordagem acabaria com uma série problemas que tira o sono de desenvolvedores web: back button, caching, navegação e preenchimento automático de formulários só para citar alguns.

Princípios

A principal idéia por trás de SPI é a substituição do conceito de página pelo conceito de estado. Uma aplicação é composta por um conjunto de estados (primários e secundários) que determinam, entre outras coisas, a interface a ser exibida.

O controle dos estados é feitos através das referências da URL (a parte final, que vem depois do '#'). alterações neste trecho não causam recarga da página.

Ajax é a tecnologia fundamental para SPI - sem ela esta abordagem seria inviável. De fato uma aplicação SPI faz uso intenso de chamadas Ajax para evitar recarga completa da página.

Entre as críticas a SPI, encontramos dificuldades de integração com sistemas de busca e de contabilização de visitas. O manifesto propõe solução para tais problemas na forma de diversos códigos javascrit.
Seguindo o paradigma associado a evolução das aplicações web, esta nova abordagem poderia ser chamada de model 4.

Conclusão

Considero a idéia SPI válida como abordagem alternativa em casos particulares, fundamentalmente que envolvam iterações complexas por parte do usuário - que resultariam em regras de navegação complexas em aplicações baseadas em páginas.

O fato das soluções apresentadas no manifesto constituírem-se majoritariamente de "workarounds" mostra a necessidade de maturação da abordagem.

Apesar do manifesto mostrar a viabilidade técnica da abordagem, é preciso muito mais para ganhar espaço na comunidade: é preciso produtividade. É preciso que surjam frameworks e toolkits que abracem SPI.

Apesar de tudo a idéia é bastante instigante. Seria esse o futuro do desenvolvimento web?

terça-feira, 16 de março de 2010

Novos Tempos em Java SE 7

Em se tratando de Java, trabalhar com datas - e tempo de uma forma geral - sempre foi bastante problemático. Uma série de problemas de design faz com que o uso da API atual seja complexo e sujeito a bugs. JSR-310 to the rescue! A nova API de data e hora, ainda em desenvolvimento e a ser integrada na versão 7 da plataforma Java SE, promete finalmente por fim a esta dor de cabeça que 11 em cada 10 desenvolvedores Java certamente já tiveram de suportar.

Problemas com a API Atual

Todos concordam que a API atual de data e hora da plataforma Java, exposta principalmente através das classes java.util.Date e java.util.Calendar, apresenta uma série de inconveniências. Entre elas:
  • Ausência de classes que representem conceitos bastante comuns como data sem hora, hora sem data, ou mesmo um período ou intervalo. A ausência destas classes faz com que o desenvolvedor acabe usando a API de uma forma diferente daquela para a qual ela foi desenhada.
  • Os objetos não são imutáveis, requerendo sincronização externa em ambientes multi-thread.
  • As classes limitam-se a representar a data como um número incremental a partir de um momento inicial (epoch). Além de ser pouco intuitiva, esta abordagem dificulta a manipulação dos objetos de forma adequada.
Estes são alguns problemas que a JSR-310 se propõe a resolver.

Características da JSR-310

As principais características da JSR-310 são:
  • Baseada na ISO-8601 - padrão internacional para representação de datas e horas.
  • Thread-safe - Seus principais objetos são imutáveis.
  • Mais coesão e legibilidade- As classes e seus métodos têm responsabilidades melhor definidas e os nomes representam estas responsabilidades de maneira mais clara.
  • Mais Extensível - A API fornece uma série de "pontos de extensão" através dos quais - fazendo uso principalmente do desing patern Strategy - É possível customizar e estender o comportamento da API, facilitando certas tarefas do cotidiano.
  • Duas escalas distintas: Máquina (representa a passagem do tempo usando um único número incremental) e Humana (representa a passagem do tempo através do valor de um certo número de campos, tais como ano, mês, hora, etc.)

 Conceitos e principais classes

A JSR-310 foi construída em torno de alguns conceitos básicos, que refletem as principais classes da API. São eles:
Instantes
Instantes representam um momento específico na linha do tempo, com precisão de nanosegundos. Um exemplo de um instante seria "3 de Junho de 1983 as 12:03:00.0 UTC". Alternativamente, um instante pode ser definido como um deslocamento, em nanosegundos, de um momento inicial padrão - o epoch (que continua sendo meia noite de 1 de janeiro de 1970).

Existem diversas classes que representam um instante na API JSR-310: Instant, OffSetDateTime e ZonedDateTime.

Instant é uma das classes mais básicas da API. Usa a escala de máquina. Deve ser vista como a substituta da java.util.Date. Possui métodos de comparação com outros Instant e adição e subtração de certa duração (lembrando que a classe é imutável)

Instant agora = Clock.systemDefaultZone().instant();

Instant umMinutoAMais = agora.plusSeconds(60); //retorna um novo Instant!

Boolean test = agora.isAfter(umMinutoAMais); //false 

OffSetDateTime representa um dia, momento do dia e um deslocamento do UTC (coordinated universal time). Usa, portanto, escala humana.

OffsetDateTime hoje= Clock.systemDefaultZone().offsetDateTime();

OffsetDateTime aniversario= OffsetDateTime.of(2009, MonthOfYear.NOVEMBER, 24,19,20,15,ZoneOffset.hours(-3));

System.out.println(aniversario); //2009-11-24T19:20:15-03:00


ZonedDateTime é similar a OffSetDateTime, incorporando o ID de uma zona, como America/New_York. Esta informação é importante na medida em que o deslocamento do UTC pode variar ao longo do ano de acordo com a região (no horário de verão, por exemplo). Quando capturar estas variações é importante para o negócio, uma ZonedDateTime deve ser utilizada.

TimeZone timeZone = TimeZone.of("Europe/Paris");
ZonedDateTime agora= Clock.system(timeZone).zonedDateTime();
System.out.println(agora); //hora atual no time zone de paris

Parciais
Parciais são representações de data/hora insuficientes para especificar determinado momento na linha do tempo. 25 de Dezembro ou 12:15 são exemplos de parciais. Como não determinam um instante específico, não podem ser representados através de um deslocamento em nanosegundos do epoch. Usam, portanto, exclusivamente a escala humana.

Alguns exemplos de parciais na API: MonthDay (que representa um dia em um mês), LocalTime (hora sem data!)  e LocalDate (Data sem hora!)

MonthDay pascoa = MonthDay.of(MonthOfYear.APRIL, 4);

  LocalDate hoje = Clock.system(TimeZone.UTC).today();
  Year ano = hoje.toYear();
  boolean bissexto = ano.isLeap(); //Determina se o ano atual é bissexto.
  
  LocalDateTime aniversario = LocalDateTime.of(1983, MonthOfYear.JUNE, 3, 12, 00);
  
  System.out.println(aniversario);
  
  LocalDateTime umMesDepois = aniversario.plusMonths(1);
  
  System.out.println(umMesDepois);
  
  System.out.println(aniversario.isBefore(umMesDepois)); //true 

Durações
Uma duração representa certa quantidade de tempo, com precisão em nanosegundos. Bastante similar ao conceito de período, difere deste por representar uma quantidade determinada de instantes. Na API, a principal classe que representa uma duração é a Duration.

long segundos = 60L;
  
 Duration duration = Duration.seconds(segundos); //cria uma duração de 1 minuto
 
 Instant instante1 = Clock.system(TimeZone.UTC).instant(); //instante atual
 
 Instant instante2 = instante1.plus(duration); //Novo instante criado a parir do instante 1 + duração.
 
 Duration duration2 = Duration.durationBetween(instante1, instante2); // duração criada a partir de 2 instantes.
 
 boolean iguais = duration.equals(duration2);//true
 
 System.out.println(iguais);



Períodos
Assim como as durações, períodos representam certa quantidade de tempo. São representados, no entanto, através de um determinado número de campos (ano, mês, hora). Na API, períodos são representados principalmente pela classe Period.

Period thePeriod = Period.years(8); //cria um período de oito anos
  
  LocalDate data = Clock.system(TimeZone.UTC).today();  
  
  LocalDate daquiAOitoAnos =  data.plus(thePeriod); //adiciona o período a data atual.
  
  System.out.println(daquiAOitoAnos);


Customizando comportamento

Como foi mencionado, a JSR-310 oferece alguns pontos de extensão, de forma que é possível customizar seu comportamento e implementar algumas funcionalidade de forma mais fácil e direta. Alguns destes pontos de extensão:

  • Adjusters: Usados para "ajustar" datas, retornando outra data com certa característica desejada (um dia ou hora específicos, por exemplo). A API fornece alguns Adjusters built-in, para ajustar para o último dia do mês, por exemplo.
  • Resolvers: Indicam como tratar uma data inválida (se alguma operação resolver para o dia 29 de fevereiro de um ano que não seja bissexto, por exemplo). Neste caso a API também possui implementações padrão, sendo a mais comum a que resolve para a próxima data válida.
  • Matchers: Realizam consultas booleanas e datas e horas, para saber se a data possui determinada característica (um dia ou hora específicos, por exemplo). Como nos outros casos, implementações padrões são fornecidas, para determinar, por exemplo, se a data pertence a um determinado ano.

Conclusão

Este post discorreu sobre as principais características da JSR-310, a nova API Java para data e hora que deverá ser entregue juntamente com a versão 7 da plataforma SE. Esta API apresenta significantes melhorias em relação a API atual, como foi possível observar ao longo do post.

Referências


http://wiki.java.net/bin/view/Projects/DateTimeEDR1 - Casa da JSR-310 na java.net. Aqui é possível encontrar a referência, um user guide, java docs e uma implementação de referência. Vale salientar que a especificação ainda está em desenvolvimento!


Revista Java Magazine ano VII edição 69 - Excelente artigo sobre a JSR-310

sábado, 6 de março de 2010

The Law of the Leaky Abstraction

Algum tempo atrás, buscando conteúdo interessante na internet, me deparei com o excelente artigo The law of the leaky abstraction. (lei da abstração sujeita a vazamentos em uma tradução livre – por falta de termos mais adequados, decidi usar a expressão na língua inglesa ao longo do texto.) Gostei tanto, que resolvi fazer dele tema do primeiro post no Java.lang.Blog.

Recomendo a todos que leiam o artigo, mas resumidamente, ele chama atenção para o fato de que as abstrações que criamos no mundo da informática, cujo objetivo em geral é encapsular determinada complexidade, acabam deixando, sobre determinadas circunstâncias, esta complexidade “vazar”, ou seja, acabamos tendo que lidar com a complexidade anyway

Desta forma, o autor propõe a law of the leaky abstraction, enunciada da seguinte forma:

“Toda abstração não trivial é, em certo grau, sujeita a vazamentos”

Não vou entrar aqui nas inúmeras abstrações das quais fazemos uso no ambiente da computação. De fato, o artigo faz isso muito bem (Não deixem de ler!). Gostaria, no entanto, de convidar os leitores a refletir sobre as abstrações que temos na plataforma JEE. Seriam elas também vítimas da law of the leaky abstraction?

Penso que sim. E para ilustrar, vou citar exemplos em duas tecnologias chaves da especificação JEE: JSF e EJB. Além disso, tenho certeza que o leitor será capaz de identificar outros “vazamentos” na plataforma JEE.

“Vazamentos” e Java Server Faces (JSF)

Como a maioria dos frameworks web, JSF tenta abstrair “detalhes” pertinentes ao desenvolvimento deste tipo de aplicações, como submissão de formulários e conversão de tipos. O framework quer nos fazer crer , por exemplo, que é possível simplesmente associar um método ou uma propriedade em um managed bean (server-side) ao clique de um botão ou valor de um input na interface (client-side).

Apesar de louvável, esta abstração é sujeita a “vazamentos”. O que acontece quando a propriedade no managed bean não é uma String? Alguma conversão é necessária. E se esta conversão falhar por algum motivo? Se o usuário resolver digitar “a#4%fg” em um input associado a uma propriedade Integer no managed bean? A não ser que o desenvolvedor tenha instruído o framework como notificar este tipo de falha, o usuário permanecerá clicando no botão e a página seguirá sendo re-exibida pelo browser. Nenhum método de nenhum managed bean é chamado no server-side. Perceberam o “vazamento”?

O desenvolvedor agora deverá infiltrar-se no complexo ciclo de vida JSF e entender, neste contexto potencialmente novo, como o framework processa conversões e como lidar com possíveis falhas.

“Vazamentos” e Enterprise Java Beans (EJB)

Apesar de ter saído de voga nos últimos tempos, uma das questões centrais da tecnologia, EJB é o suporte a sistemas distribuídos. Ainda que estejam rodando em uma máquina remota, clientes EJB são capazes de fazer chamadas a estes componentes como se fossem locais. A complexidade envolvida na chamada de método remota (RMI) é, portanto, abstraída pela tecnologia.

Essa abstração, no entanto, também é sujeita a "vazamentos" – e de uma forma bastante sutil: parâmetros as chamadas dos métodos de um EJB remoto devem ser serializable. Isso porque estes objetos deverão trafegar pela rede, sendo reconstruídos na máquina remota que abriga, de fato, o componente EJB. Desta forma, o fato que o componente EJB é remoto transparece na necessidade dos parâmetros de seus métodos serem obrigados a ser serializable, caracterizando o "vazamento".

Vale lembrar que este "vazamento" era mais visível nas primeiras versões da especificação, quando o cliente de um EJB era obrigado a tratar exceções checadas relacionadas a chamadas remotas (RemoteException e subclasses). Esse aspecto foi melhorado a partir da versão 3.0, substituindo as exceções checadas por equivalentes não checadas.

Consequências

Algumas consequências da law of the leaky abstraction:

1) Abstrações não nos ajuda tanto como imaginamos. Em uma ambiente onde se recorre tão constantemente a este recurso, isso é algo importante de se ter em mente.

2) Paradoxalmente, quanto mais camadas de abstração são criadas visando simplificar o desenvolvimento, mais difícil se torna a tarefa de se tornar um desenvolvedor proficiente. Esta talvez seja a consequência mais intrigante. Será que os esforços no sentido de simplificar o desenvolvimento na plataforma Java estariam tendo o efeito oposto do esperado?

3) Desconfie de ferramentas que prometem, como em um passe de mágica, simplificar o desenvolvimento e multiplicar a produtividade da equipe (alguém falou em geradores de código ai?). As abstrações nas quais estas ferramentas se baseiam certamente iram "vazar", e quando isto acontece, muitas vezes o custo é bastante alto.