Rodrigo Allemand

Maven Dependency Manager com Eclipse Dynamic Web Project

por Rodrigo Allemand em Nov.30, 2010, como Desenvolvimento, Maven

Ainda bem que eu demorei um pouco (?) pra escrever sobre Maven.

Pra quem não conhece, a Wikipédia tem uma ótima definição sobre Maven.

Apache Maven, ou simplesmente Maven, é uma ferramenta para gerenciamento e automação de projetos em Java. Ela é similar à ferramenta Ant, mas possui um modelo de configuração mais simples, baseado no formato XML.

Até algumas semanas atrás eu não concordava muito com essa definição. Eu achava que o PRÓ – gerenciamento de dependências e do ciclo de vida do projeto – era ofuscados pelo CONTRA – configuração e falta de simplicidade para se conseguir coisa que o Eclipse já fazia perfeitamente. Na verdade, grande parte desse CONTRA era por falta de conhecimento, mas mesmo depois que eu consultei sobre o assunto, ainda sim, a simplicidade era uma coisa que passava longe.

Muitos falavam que o ponto alto é a curva de aprendizado de um novo recurso no projeto, guiado por um modelo único de formato de projeto que pode ser compartilhado pelas diversas ferramentas, na utopia que cada um poderia utilizar a ferramenta que se sentisse melhor. Tudo bem, concordo, mas sabemos que essa realidade não é pra todos. O Eclipse é o Windows das IDEs Java, isso é fato!

Pois bem, meu primeiro problema foi montar o POM para o projeto que eu estou entrando. Onde encontrar a bendita dependência do Richfaces?! Por algum motivo, a JBoss não divulga alguns de seus projetos no servidor Maven default (conhecido como Central). Vasculhando na internet, sem perder muito tempo descobri o motivo. E começa a saga de configurar…

Depois me deparei com um problema, que era colocar em sincronia o Eclipse e o Tomcat em modo debug. O que é simples no Eclipse com o seu famoso Dynamic Web Project é um martírio em um projeto Maven! Depois de mais algumas pesquisas e mais um belo conjunto de configurações, adiciona um plugin aqui e outro ali… pronto! Funcionou! Não da maneira que eu esperava, mas dá pra levar!

Isso me fez pensar: MAVEN SUCKS!

Rodei a internet atrás de milhões de soluções pra deixar esse debub mais fácil e fazer que a integração com o Eclipse fosse simples, usando o que cada um tem de melhor. Usei várias – tentativas de – soluções. Umas até tinham uma linha de raciocínio coerente. Outras pareciam crença indígena! Até que me deparei com um tutorial (básico, mas completo) sobre como integrar o Dynamic Web Project com as dependências e o ALM do Maven, trazendo o que (ao meu ver) é de melhor nos dois.

Segue!

http://www.cloudchamp.com/2010/08/creating-maven-web-project-in-eclipse.html

PS: Não sei se é cedo falar que agora eu acho que o Maven tem a sua valia. Digamos que eu ESTOU ACHANDO NESTE MOMENTO que o Maven vai, sim, agregar alguma coisa para a minha equipe. O amanhã a Deus pertence! rs

Comente e Recomende!

Deixe um comentrio :, , , , mais...

O problema de múltiplos POs em um projeto ágil

por Rodrigo Allemand em Oct.07, 2010, como Matodologia Agil

Recentemente a revista MundoJ apresentou uma ótima matéria do Dairton Bassi intitulada “Você é ágil mesmo?” contendo uma série de questões que mostram falhas e auxilia uma equipe a se ajustar nos conceitos pregados pelas diversas metodologias ágeis, visando atingir o sucesso em um projeto.

Uma delas, focada no cliente e intitulada “O cliente com varias vozes”, diz respeito a um projeto onde não se pode eleger apenas um Product Owner [PO] ou a interferência dos Steakholders atrapalha a decisão a ser tomada.

Nesta matéria ele é taxativo e diz que o melhor é escolher um único PO dentre os muitos para que o “bater do martelo” seja responsabilidade dele, encapsulando as divergências de interesse do conjunto de POs.

No projeto que eu agora faço parte acontece este problema. Trata-se de uma empresa grande, familiar e sem um processo definido. Pra melhorar o cenário, a ferramenta que está sendo desenvolvida é uma ERP, que engloba desde a compra de subsídios até o recebimento dos serviços prestados.

Inicialmente, no primeiro Sprint – muito grande para um primeiro sprint ao meu ver – o eleito para PO foi o gerente comercial. Com o decorrer do tempo, ficou claro que as decisões que ele deveria tomar sobre outras áreas estava distorcendo a necessidade de outros setores da empresa.

Após isso, elegemos como PO o responsável pela auditoria geral do cliente. Teoricamente, esta pessoa deveria conhecer todos os pontos do processo da empresa. Porem, o problema persistia. Apesar da visibilidade do todo, o dia-a-dia, o chão de fábrica ainda era uma incógnita para o time.

Depois de uma conversa interna da equipe e com alguns conselheiros na metodologia Scrum, definimos os seguintes pontos:

  • criaríamos um board de POs, deixando a cargo de um diretor de operações o bater do martelo em caso de divergências
  • o board seria formado por um u mai especialistas de cada área – funcionário, operacional – e o seu gerente*
  • os sprints seriam divididos por área de atuação da empresa
  • a cada sprint, a voz do membro da área que está sendo analisada ganharia peso, deixando claro que a preferência é deste novo PO
  • todos os setores estão presentes nessa etapa de definição para que qualquer interferência sofrida seja antecipada

Não sei se esse é o modelo ideal, mas no cenário deste cliente é o que deve funcionar!

Momento de Teoria

Definitivamente, esta é a resposta para o problema citado. Este gráfico mostra o ponto de ação desejável dos projetos em Scrum. Neste projeto, pela falta de conhecimento do cliente no próprio processo, os requisitos ainda são complexos – tanto para o time quanto para os próprios gerentes.

Conclusão: Ao meu ver, projetos com muitas vozes de PO pode ser um indício de complexidade nos requisitos!

E vocês? O que acham?

Até!
Comente e Recomende!

* A figura do gerente se faz necessária porque o processo da empresa está sendo desenhado e muitas vezes alterados conforme o levantamento das estórias. Tais alterações necessitam de uma aprovação gerencial para ser executada operacionalmente.

Deixe um comentrio :, , , , mais...

DDD encapsula a minha Regra de Negócio

por Rodrigo Allemand em Oct.16, 2009, como DDD

Resolvi responder ao comentário do Diogo (no post Blindando o Domínio) em um post separado por achar que essa é a duvida mais frequente que eu vejo, seja em conversas informais, fóruns, palestras, etc.

Onde colocar as minhas regras de negócio?

A resposta é…. Depende! rs

Se você escolheu utilizar DDD no seu projeto é porque você conhece e já isolou o problema a ser resolvido que, por ser complexo, será baseado em um modelo, recebendo o foco e a prioridade necessárias para a solução deste domínio. Quando você isola este domínio, obviamente você deve encapsular tambem todas as regras de negócio dentro desse domínio.

Para exemplificar melhor vamos fazer a seguinte funcionalidade de exemplo no nosso dóminio.

Todos os pedidos com valor acima 1.000,00 e que são pagos com dinheiro em espécie são elegíveis a um desconto de 10% por produto.

Claro que esta informação tem que ser passada para o usuário final do sistema, mas é responsabilidade do sistema checar se as informações passadas estão corretas. Você pode até colocar a regra de validação tambem na camada de apresentação ou dentro do seu banco de dados em forma de triggers (argh, rs!), mas de qualquer maneira o domínio tem que ter esta validação, já que um dos princípios do DDD é justamente poder trocar a camada de apresentação sem que o domínio seja alterado ou compartilhar o mesmo domínio entre interfaces/sistemas diferentes.

Portanto, segue a primeira afirmação:

Por mais que a sua camada de apresentação faça as regras necessárias para uma determinada funcionalidade, o seu domínio tambem deve, obrigatoriamente, fazer com que estas regras estejam presente internamente, tornando-o coeso da camada que ele comunica.

Vamos melhorar este exemplo mostrando como ficariam as entidades envolvidas nesta funcionalidade.

public class Pedido {
	private List<ItemPedido> itens;
	private BigDecimal precoTotal;
	//Acessores omitidos
}
public class ItemPedido {
	private Produto produto;
	private BigDecimal precoVenda;
	private BigDecimal desconto;
	//Acessores omitidos
}

OBS.: Muitos podem perguntar porque a informação referente ao preço final é um atributo da classe e não um comportamento da entidade (um método que poderia somar todos os preços finais decrementando os descontos dados por cada produto, multiplicado pela quantidade de cada produto). Vamos pensar que o preço do Produto pode – e deve – variar e o sistema precisa manter a informação do preço de venda naquele momento, ok?

Eu encaro que esta regra de negócio deve estar em uma checagem no momento da inclusão, como por exemplo uma Specification destinada somente a esta regra. Lembro que, a Specification tem, neste caso, o intúito de validar uma informação e que ela não precisa ser necessariamente apenas uma única specification. Eu posso – e é até melhor – dividir a informação em várias Specifications, uma para cada regra de negócio que a minha funcionalidade exige.

Vamos pensar então que a minha classe ValidarDescontoDadoSpecification tem o seguinte código:

public class ValidarDescontoDadoSpecification
	implements Specification<ItemPedido> {

	public static final BigDecimal DESCONTO_MAXIMO_PGTO_DINHEIRO = 10;

	public boolean isSatisfiedBy(ItemPedido item){
		if(itemPedido.getFormaPagamento.equal(FormaPagamento.DINHEIRO){
			BigDecimal descontoDado =
				Calculadora.percentualEntre(
					item.getPrecoVenda(),
					item.getDesconto());
			if(descontoDado.compareTo(DESCONTO_MAXIMO_PGTO_DINHEIRO) > 1){
				//É necessário comunicar ao domínio o porque da falha
				//Neste caso, leia mais sobre Notification
				return false;
			}
		}
		return true;
	}
}

Pensando que você sempre salva o pedido, poderiamos ter uma outra Specification para isso, conforme abaixo:

public class PersistirPedidoSpecification
	implements Specification<Pedido> {

	public boolean isSatisfiedBy(Pedido pedido){
		/*
		  As boas maneiras de aplicativos internet diz que
		  vc deve validar tudo de uma unica vez, rs
		*/
		boolean resultado = true;

		//Validações referente ao Pedido

		ValidarDescontoDadoSpecification spec =
			new ValidarDescontoDadoSpecification();
		for(ItemPedido item : pedido.getItens()){
			if(!spec.isSatisfiedBy(item)){
				/*
				  Lembre que a informação da falha deve ser feita
				  pela outra Specification, não por esta!
				*/
				resultado = false;
			}
		}
		return resultado;
	}
}

Assim, no final de tudo, nós poderiamos ter no repositório Pedidos, o seguinte código:

public class Pedidos{

	public static void persistir(Pedido pedido){
		PersistirPedidoSpecification spec
			=  new PersistirPedidoSpecification();
		if(spec.isSatisfiedBy(pedido){
			dao.salvar(pedido);
		} else {
			//Comunica a falha encontrada às outras camadas
		}
	}
}

Espero ter ajudado!!!

Abraço a todos!!!

Comente e Recomende!!

13 Comentrios :, , mais...

Procurando por algo?

Use o campo abaixo para procurar por todo o site:

Ainda não achou? Deixe um comentário ou me mande um email que eu cuido disso!

Minhas indicações!

Alguns blogs que eu recomendo...