Archive for September, 2007

Unblubbing

Tuesday, September 25th, 2007

Sem querer começar uma language war mas postando mesmo assim… :)

Ultimamente tem se falado muito dessas novas linguagens como Ruby/Python e técnicas e padrões de várias letrinhas. Até parece o paradoxo do programador Blub aflorando.

Aqui vai uma dica de vídeo para quem se interessa por programação: Structure and Interpretation of Computer Programs - Video Lectures. É o curso de introdução a computação do MIT (primeiro semestre) gravado em 1986. É muito interessante ver que desde essa época nem as linguagens nem os métodos de programação evoluiriam em quase nada. Nesse curso introdutório eles vão de programação procedural, passam por OO, programação funcional, programação lógica (baseadas em regras), constroem um interpretador e novas linguagens (DSLs anyone?) entre outras coisas. Além dos vídeos o livro também é free e pode ser acessado nesse link.

Buscando qualidade de código (parte 1)

Monday, September 17th, 2007

Essa semana durante uma sessão de refatoração, tive a idéia de sempre que me deparar com situações de códigos que precisam ser alterados afim de se adequarem a alguns princípios de boas práticas de desenvolvimento de software, vou compartilhar aqui, explorando os pontos negativos do código e as vantagens de se adequar a um desses princípios, falando também um pouco sobre eles, um caso de cada vez, começando agora com OCP (Open-Closed Principle).

The Open-Closed Principle

Este princípio é a fundação para construção de códigos reutilizáveis e de fácil manutenção. Módulos que se adequam a este princípio são, ao mesmo tempo, abertos para serem extendidos, de maneira que se comporte de maneiras diferentes, a medida que surgem novos requisitos para a aplicação, ou a medida que estes são modificados. E fechados para modificação, o que significa que o código fonte deste módulo não pode ser violado, ninguém pode fazer mudanças neste código fonte.

A descrição deste princípio pode parecer conflitante, já que para extender a funcionalidade de um módulo, é necessário modificá-la, logo deduzimos que uma funcionalidade que não pode ser alterada é dada como fixa. Como este conflito pode ser resolvido? A melhor maneira de demonstrar é através de um exemplo.

No projeto CartolaFC, que estou trabalhando atualmente, existe um gerenciador de tarefas que é responsável pela execução assíncrona de tarefas enfileiradas pela aplicação. Basicamente ele percorre uma lista de pendencias, executando cada uma das tarefas, na ordem em que aparecem. O código abaixo está modificado em relação ao original, para podermos visualizar com mais facilidade.

public class GerenciadorDeTarefas {

    public List<Tarefas> pendentes;
    public void executaTarefasPendentes() {
	for (int i=0; i<pendentes.length; i++) {
	    Tarefa tarefa = pendentes[i];

	    switch (tarefa.tipo()) {
	    case calculoTrofeus:
	    	engine.calculaTrofeus();
	    	break;

	    case calculoEstatisticas:
	    	engine.calculaEstatisticas();
	    	break;
	    }

	    case fechamentoDeMercado:
	    	engine.fechaMercado();
	    	break;
	    }

	    case aberturaDeMercado:
	    	engine.abreMercado();
	    	break;
	    }

	    // .... e assim continua ....
	}
    }
}

O método executaTarefasPendentes() não se adequa ao Open-Closed Principle, pois não está fechado para novos tipos de implementação. Se um dia o cliente decidir extender esta funcionalidade para incluir novas tarefas a serem executadas, que é o que acontece hoje em dia, o método terá que ser modificado para atender este requisito, incluindo mais um bloco “case”, que já não é nada elegante, e assim continuará, para cada novo tipo de tarefa.

O código, na vida real é ainda pior, atualmente são 18 blocos “case”, o que torna a implementação de novas tarefas uma prática intrusiva, suja e acoplada (imagine se todos os métodos a serem executados para as tarefas ficassem espalhados… quantos objetos teríamos que instânciar no gerenciador de tarefas…)

O código a seguir mostra a solução que pretendo dar para este problema, uma solução que se adequa ao Open-Closed Principle. Resumindo, a classe Tarefa se torna abstrata e acrescentamos a ela um método abstrato chamado executar(). Com esse approach, TODOS os tipos de tarefas criados, serão classes concretas que derivam desta classe, implementando seu método abstrato.

public class abstract Tarefa {
    public abstract void executar();
}
public class CalculoDeTrofeus extends Tarefa {
    public void executar() {
	// lógica para cálculo de troféus...
    }
}
public class CalculoDeEstatisticas extends Tarefa {
    public void executar() {
	// lógica para cálculo de estatísticas...
    }
}

E a partir de agora, para o nosso gerenciador de tarefas, o ato de invocar as tarefas pendentes fica totalmente transparente. Tudo que ele precisa fazer é percorrê-las, e para cada uma, invocar seu método executar(), tornando o código não intrusivo, limpo e desacoplado.

public class GerenciadorDeTarefas {

    public List<Tarefas> pendentes;
    public void executaTarefasPendentes() {
	for (int i=0; i<pendentes.length; i++) {
	    Tarefa tarefa = pendentes[i];
	    tarefa.executar();
	}
    }
}

Agora, se quisermos extender a funcionalidade de executarTarefasPendentes() do nosso gerenciador para que passe a executar uma tarefa nova qualquer, tudo o que precisamos fazer é adicionar uma nova implementação para a classe abstrata Tarefa. O nosso método executarTarefasPendentes() não precisa ser alterado, se adequando ao Open-Closed Principle. Seu comportamento pode ser extendido, sem que ele seja alterado.

Tracking agile projects

Tuesday, September 11th, 2007

Este artigo fala sobre a utilização de gráficos visíveis, colados na parede, para o acompanhamento do status de projetos ágeis, explicando o funcionamento de alguns destes, como os diversos tipos de kanban boards e um chamado niko cale.

niko cale

Este último em especial chamou minha atenção, pois possibilita a conexão do humor e motivação de cada pessoa da equipe com o andamento do projeto.

Niko-niko Calendar (or Smiley Calendar), a Japanese creation, showing team member’s mood for each day. Everyone puts a smiley mark onto their own calendar after the day’s work, before leaving the team room [Sakata06]. It looks at the project from the viewpoint of member’s mental health and motivation.

Saiba mais aqui.