Pacotes, dependência, estabilidade and so for …

December 20, 2008

Continuando o assunto do post anterior, o livro de Uncle Bob é uma verdadeira salada. Só para se ter uma idéia, aqui vão alguns dos assuntos tratados: Manifesto Ágil, Extreme Programming, Design Ágil, Princípios de OO e Patterns, Princípios de Design de Pacotes, UML, vários casos de estudo e pra fechar a divertida “Sátira de duas companias” e um fabuloso artigo de Jack Reeves, de 1992, entitulado “What is Software Design”. Leitura mais que obrigatória!

A leitura deste livro me levou a algumas boas reflexões sobre como coisas escritas há anos, até decadas atrás estão presentes  (às vezes nas entranhas às vezes na cara) nos assuntos mais “badalados” e buzzwords dos artigos e foruns  a fora.

Quem inicia seus estudos em desenvolvimento de software acha que nunca irá “saber tudo”, afinal de contas “é muita coisa pra estudar”. A notícia ruim é que vocês têem razão, nunca saberão tudo. Mas nem tudo está perdido. Para a maioria dos softwares corporativos que são desenvolvidos, sólidos conhecimentos de Orientação à Objetos e algumas Práticas Ágeis de desenvolvimento já te deixarão anos luz à frente da maioria dos profissionais do mercado.

Mas o que quero tratar neste post e ouvir a opinião de vocês, é justamente um de meus devaneios durante a leitura.

Um dos temas que me interessou bastante, pois não tinha lido nenhum livro que tratasse do assunto foi sobre Design de Pacotes.
Imaginemos um caso de estudo: Um sistema bem simples para armazenar fotos. A pessoa cria um pefil. Cada perfil pode armazenar diversas fotos. Além disso cada perfil pode estar associado a vários amigos. Você só pode ver as fotos de quem for seu amigo.

Solução 1:

Solucao1

Consegue enxergar algum problema neste design?

Vamos imaginar que a atual implementação de FotoDaoImpl salve as fotos no sistema de arquivos da própria máquina. O primeiro release tinha que sair rápido, seria uma aplicação desktop e essa solução resolveria o problema por hora. Contudo, no próximo release será entregue uma versão web da aplicação e agora as fotos devem ser salvas em um SGDB, porém a versão desktop da aplicação continuará sendo usada (por qualquer razão que seja). Então, como reutilizar o pacote Domain sem ter que “levar de brinde” o pacote de Infra já que a classe Perfil busca as fotos a serem exibidas atraves da interface FotoDao, que por sua vez possui uma implementação para salvar e carregar as fotos do sistema de arquivos local da máquina?

O grande problema é que o pacote domain possui uma dependência direta com o pacote de infra estrutura. O que é uma péssima idéia. As classes de domínio devem depender apenas de classes do mesmo nível de abstração, ou seja, classes que fazem sentido ao negócio, nunca de classes de infra-estrutura. Quanto maior a dependencia do pacote Domain com outros pacotes, maior será o número de razões para este sofrer mudanças. Isso significa que, sempre que o pacote Infra alterar, você terá de revalidar o pacote Domain e verificar se nada foi quebrado.
Uma regra simples é: Pacotes instáveis dependem de pacotes estáveis. Pacotes estáveis não devem depender de pacotes instáveis.
A estabilidade de um pacote tem a ver com o “esforço necessário para se fazer uma mudança”. O que isso significa?
Imagine a siguinte situação: os pacotes B, C e D todos dependem do pacote A. Logo o esforço para realizar uma mudança no pacote A é muito grande, pois afetará outros três. A é um pacote estável!
Por outro lado se, nenhum outro pacote depende de B, então ele é instável. O esforço para uma mudança é muito baixo, só afeta ele próprio.
Muitas vezes a estabilidade de algo é confundida com a frequencia com que essa coisa muda, ou seja, se muda muito é instável se muda pouco é estável. Cuidado isso é um equivoco.
Uncle Bob dá o seguinte exemplo em seu livro: Coloque uma moeda em pé. Se ninguém mexer com ela, continuará ali, quietinha, sem nenhuma alteração. Por isso ela está estável?
Não, pois o esforço para mudar sua posição é mínimo. (outra tentativa de metáfora para esse problema)
Uma solução é colocar a interface FotoDao no pacote Domain. Dessa forma aplicamos DIP (dependency-inversion principle) e magicamente a dependencia é invertida. O pacote Infra é quem passa a depender do pacote Domain. Com essa mudança nosso pacote de maior nível de abstração, o domínio, passa a ter apenas um bom motivo para sofrer alterações. Ele próprio!

Solução 2:

Aplicar DIP foi uma boa solução. Mas ainda não fiquei satisfeito. Como a classe FotoDao faz parte do domínio da aplicação? O zé que vai publicar suas fotos sabe que raios isso significa?

O que precisamos é de um local para guardarmos e recuperarmos nossas fotos. Uma espécie de repositório de fotos (buzzword++), algo como FotoRepository. Assim não incluimos em nossa linguagem (ubiquotous language) conceitos especificos de tecnologia. Certo? Huunnn… ainda não.

Invertemos a dependencia, assim consiguimos reutilizar o pacote Domain. Retiramos o cheiro de termos tecnicos da nossa comunicação. Então o que falta?

Será que em uma conversa com com o usuário ele citaria o termo “repositorio de fotos”? Acho pouco provavel. Que tal album? Um album nada mais é do que uma coleção de fotos. Onde podemos incluir, retirar e consultar nossos fotos. Não? Um repositório de fotos. Aaahh, mas você só mudou o nome, grande coisa. Sim só mudamos o nome. Nomes são muito importantes e fazem toda a diferença.

Então ficariamos com alguma coisa mais ou menos assim:

Solucao2

Veja como conceitos de Orientação à Objetos, Design de Pacotes, Patterns como DIP (e outros SRP, LSP, OCP), Domain Driven Design, Refactoring, Design Ágil, Iterações curtas e pequenos releases, etc se sobrepoem e se completam. No fim das contas, quando você estudar DDD por exemplo irá aproveitar conceitos de OO que aprendeu. Quando for aplicar Refactoring idem, e por aí vai.

Advertisements

(e|in)stabilidade de pacotes

December 20, 2008

Em seu livro “Agile Software Development – Principles, Paterns, and Practices”, Robert C. Martin (também conhecido como Uncle Bob) dedica bastante atenção à um assunto que, muitas vezes não se dá a devida importância: design de pacotes.
Em meio à uma discusão sobre coesão e acoplamento dos pacotes surge o conceito de estável:

* “Something is stable if it is not easily moved”

Segundo Uncle Bob, a estabilidade de um pacote está relacionada não á frequencia em que este sofre alterações, mas sim no esforço necessário para a alteração.
Deste ponto de vista, um pacote do qual muitos outros dependem é considerado estável pois uma alteração fará com que todos os outros que dele dependam devam ser revisados. O esforço é grande. Seguindo esta linha, um pacote que depende de vários outros, porém não possui ninguem que dependa dele é considerado instável, pois é muito simples alterá-lo, o esforço é pequeno, ninguém mais será afetado.

Meio confuso não? Vamos tentar uma metáfora.

Cena 1
Imagine que você trabalhe em uma empresa quase perfeita, desenvolvendo software. Maravilhosamente quase nenhum projeto atrasa, são entregues no prazo e com qualidade.
Logo, seu gerente de projetos está sempre de bom humor, sorridente e fanfarrão.
Porém, como você trabalha nessa mesma empresa a 10 anos já o viu algumas vezes mudar de humor. Umas dez vezes mais ou menos. Média de 1 por ano. Fantástico pelo histórico da maioria dos projetos!
Quando isso acontece seu gerente muda completamente de temperamento, age como se fosse outra pessoa. Fica vermelho quando fala, aos berros, palavrões, ameaças de demissão, pressão total. Pede pra sair!
Apesar de ser uma ocasião muito rara em sua empresa dos sonhos, não precisa de muito para que seu gerente perca a paciência. Basta alguém pedir demissão, ou uma atividade atrasar 1 dia, ou um cliente reclamar de 1 funcionalidade, ou algumas outras coisas desse tipo.
Veja que basta que ocorra apenas 1 dessas situações para que ele mude de humor. Porém, como na maior parte do tempo tudo anda como esperado, é raro de se ver.
Pergunta: seu gerente é estável?
Apesar da baixa frequencia na mudança de estado, devemos concordar que é uma pessoa extremamante instável. É muito fácil provocar uma mudança.

Cena 2
Imagine que a empresa onde você trabalha esteja passando por uma nova fase. Muitas mudanças, readaptações, equipe nova, limitada, novos produtos.
Tudo ao mesmo tempo. Uma bagunça só.
Seu gerente de projetos está diariamente irritado. Sempre dando respostas curtas e grossas. Ordem atrás de ordem. Pressionando a equipe o tempo todo.
Como você trabalha nessa mesma empresa, com esse gerente a 10 anos sabe que essa situação não é normal.
Nesses 10 anos você viu o cara descer do salto uma meia duzia de vezes apenas. E mesmo assim nada muito agressivo. Normal.
Para que seu gerente perca a paciência é preciso que o projeto esteja atrasodo pelo menos 1 mês, as pessoas da sua equipe cheguem tarde todos os dias, passem horas no msn e orkut durante o expediente, não façam testes unitários e ainda torçam para o Corinthians. Tudo isso ao mesmo tempo. Como a empresa está passando por um momento difícil, nos ultimos meses isso anda acontecendo todos os dias. Logo, gerente extressado sempre.
Pergunta: seu gerente é instável?
Apesar da alta frequencia na mudança de seu comportamento, acho que não podemos considerá-lo uma pessoa instável. Basta ver como é difícil irritá-lo, mudar seu estado de espírito.

Concordo que é tentador pensar que algo que muda com pouca frequencia seja estável, enquanto que algo que muda constantemente seja instável. Mas tome cuidado!
E o que tudo isso me importa?

A organização de classes em pacotes e a dependência entre esses pacotes são extremamente importantes para a definição de um bom design de software, mas, ao contrário do que possa parecer não é uma tarefa simples.

Falando em Agile

October 27, 2008

Tenho certeza que terão muitos posts falando sobre o evento “Falando em Agile 2008”, porém não poderia deixar de expressar minha impressão sobre as palestras que achei mais interessantes.

Para quem se interessar, o objetivo principal de cada palestra pode ser encontrado aqui, logo, focarei mais na minha impressão e opinião pessoal de cada apresentação.

Começando pelo principal. Foi o melhor Coffe Break de todos todos os eventos da Caelum que já participei. =D

No primeiro dia o Danilo Sato e o Francisco Trindade falaram sobre “Agilidade de tartaruga. Métodos ágeis encontram o mundo real”. Eles focaram bastante na idéia de evolução contínua de um processo ágil e como “seguir a receita dos livros” (agile by the book) pode engessar o processo e acabar deixando de lado algo fundamental para um time ágil: a adaptação e melhoria constante do processo. A palestra foi muito interessante pois eles apresentaram exemplos reais de projetos em que participaram e de como o feedback e adaptação ajudam a “moldar” um processo ágil para a realidade daquele cliente ou daquele projeto especificamente. Mas fico um pouco preocupado com interpretações erradas. Imaginem o camarada que está começando a utilizar práticas ágeis e que ainda não conseguiu adaptar-se, por exemplo, à prática de TDD. Ao descobrir que pode adaptar o processo ele logo pensa: “Ahá, sabia que não precisava desse negócio de testar antes de escrever código”. Pronto, acontecerá exatamente o que o Phillip mostrou em sua palestra (continue lendo). Obviamente que não foi isso que o Danilo e o Francisco passaram, mas, sabemos até onde vai a criatividade humana. Alias, segundo o Pedro, a preguiça é o maior motivador para a criatividade humana. Preguiça, escrever testes, gerente que diz “se não tiver tempo não precisa testar” … Sugestivo né! Então fica o alertar: Para adaptar um processo (ágil ou não), primeiro você precisa experimentá-lo, conhecê-lo muito bem e saber exatamente quais as consequencias da exclusão de uma prática.

O destaque do dia foi a palestra do pessoal de Brasilia, da SEA tecnologia. Foi uma palestra muito divertida onde o pessoal mostrou a dificuldade que enfrentaram para introduzir métodos ágeis na Força Aérea Brasileira, um orgão militar bastante consevador, burocrático e cheio de regras e procedimentos rígidos. A todo momento o oficial militar responsável pelo projeto, que participou da aparesentação, contava momentos em que pensou “pronto agora eu vou em cana”. O relato mais curioso foi com relação aos post-its no quadro. Como o Coronel (não me lembro se era esta a patente correta) “não gostava de desorganização” a saída do pessoal foi colar os post-its em folhas A4 e estas no quadro. Guando o Coronel chegava, todos corriam para arrancar as folhas e escontê-las na gaveta. Que situação!

A ultima palestra do dia foi a do Guilherme Chapiewsky da globo.com, com o tema “Liderando equipes agéis”. A palestra do Guilherme foi incrível. Ele conseguiu deixar muito claro como ele lidera e como é a relação entre o lider e a sua equipe. Eu acompanho os blogs do pessoal da globo.com a algum tempo e é nítida, mesmo pra quem está de fora, a mudança de comportamento que o Scrum trouxe para organização. Das 12 palestras realizadas nesses dois dias, 4 foram do (ex-)pessoal da globo.com, e todos mostraram-se muito satisfeitos com a introdução de práticas ágeis. É muito legal vermos o surgimento de lideres jovens como o Guilherme, que não conduzem uma equipe de forma imperativa, “chefeando” mas sim guiando, ajudando e principalmente fazendo parte da equipe, porque geralmente, as equipes não enchergam o gerente como um membro e sim como chefe (Uga-uga!).

O segundo dia teve início com o KeyNote do Alexendre Magno sobre “Scrum em ambientes PMBok”. O Alexandre dispensa apresentações/comentários e como sempre sua palestra foi muito boa. O legal dessa apresentação foi ver como os gerentes de projeto tradicionais destorcem muito as práticas do PMBok, interpretando-as como convêm. O próprio PMBok fala sobre coisas como Rolling-Wave Planning e Progressive Elaboration, que se parecem muito com o nosso desenvolvimento iterativo. Alguém aí já viu algum PMP falando sobre essas coisas? Veja no link dos mesmos para a Wikipedia a importancia que se dá a essas coisas.

Continuando com o case da globo.com, o Danilo Bardusco contou um pouco de como aconteceu o primeiro projeto onde eles utilizaram efetivamente práticas ágeis. Precisavam colocar no ar em 40 dias uma aplicação para o BBB. Todos, inclusive o próprio Danilo, acreditavam que não conseguiriam cumprir esse prazo desenvolvendo software da forma como estavam acostumados a fazer. Quando propôs o uso de Scrum, os próprios membros da equipe, como de costume, continuaram duvidando que seria possível. A solução foi propor uma experiência de 3 dias e, caso não ouvesse evolução, desistiriam do projeto. O resultado foi a adoção de Scrum em todas as equipes da globo.com.

Outra apresentação que merece destaque foi a do Antônio Carlos, do Yahoo. Sua palestra foi um pouco mais específica, focando no papel do Product Owner. Muitas das palestras do evento foram em cima de relatos sobre a experiência na adoção de metodologias ágeis nas empresas. Foi realmente muito legal ouvir essas experiências, uma perspectiva bem diferente e mais prática do que lemos nos livros. Porem uma das coisas que senti falta no evento foram palestras com temas mais técnicos, específicos e práticos, por isso a palestra do Antônio foi diferenciada. Seria bom se tivessemos um evento em formato de Workshops, com simulação de casos reais e trabalhos em grupo.

Por último tivemos a palestra do Phillip Calçado (Shoes). Uma palestra bastante esperada pela maioria e que não deixou a desejar. Apesar do tema parece bem polêmico, “A maldição da fábrica de software ágil”, a apresentação foi bem amena. Depois de alguns minutos ofegantes, após a corrida atras do notebook, o Phillip apresentou dois exemplos de projetos em que teve a oportunidade de participar pela Thoughtworks Austrália e quais foram os problemas que encontraram. Conta Shoes que em um desses projetos, após obterem sucesso em uma parte do projeto, o gerente do projeto resolveu colocar mais pessoas e paralelizar as tarefas. “Nine women can’t make a baby in one month” já dizia Fred Brooks. A conclusão do Phillip, e aí entra o comentário que fiz sobre o tema do Danilo e do Francisco, é que com tantas pessoas no time perdeu-se na comunicação. A comunicação é um dos pilares do desenvolvimento ágil e, com a falta ou deficiência da mesma, torna-se necessária uma documentação formal mais pesada, já que de alguma forma as informações têem de ser transmitidas entre os membros da equipe. Ao tentar transformar o time em uma especie de fábrica, o gerente de projetos não percebeu que estava abrindo mão da comunicação, e isso colocou em xeque o sucesso de um time ágil.

Como em todo bom evento, ao final de cada dia fomos “tomar uma”. Esse é um momento muito interessante, pois temos oportunidade de conhecer pessoalmente várias pessoas que encontramos diariamente nos blogs e foruns. Entre Coffe Breaks e cervejas após o evento tive a oportunidade de conhecer pessoas como o Luiz Aguiar, Luca, Rodrigo Yoshima, Pedro (do Yahoo), Daniel Destro, diversos dos palestrantes e muitas outras pessoas que nem tivemos tempo de perguntar o nome uma das outras.

Quem não pode ir desta fez, não perca os próximos. Sem dúvida são essas coisas que ajudarão a formar seu conhecimento e opinião profissional.

assertEquals para BigDecimal

October 22, 2008

Quando, desenvolvendo software, nos deparamos com alguma situação um tanto quanto bizarra, qual a primeira coisa a se fazer?
Sair correndo para perguntar naquele forum bacana certo? É uma alternativa.
Acho os foruns fantásticos, frequento bastante. São sem dúvida uma ótima fonte de estudo. Porém uma outra solução um pouco mais difícil, demorada, porém menos preguiçosa mais … digamos … nobre, seria perder alguns poucos minutos realizando uma pesquisa.

Hoje, desenvolvendo um “Pet Project” me deparei com uma situação dessas.
Veja o seguinte código:

import java.math.BigDecimal;

import org.junit.Test;
import static org.junit.Assert.*;

public class BigDecimalTest {

	private final BigDecimal n1 = new BigDecimal("13.23");
	private final BigDecimal n2 = new BigDecimal("13.27");

	@Test
	public void should_not_be_equals_using_junit_assert_method()
	{
		assertEquals(n1, n2);
	}

	@Test
	public void should_not_be_equals_using_BigDecimal_equals_method()
	{
		assertTrue(n1.equals(n2));
	}
}

Ambos deveriam falhar correto? Mas não foi o que aconteceu.
Inexplicavelmente o primeiro teste passou. Ficou verdinho! Isso mesmo.
Minha primeira idéia foi uma pesquisa rápida no google (ooohhh), mas não encontrei nada. Talvez não tenha procurado direito, é verdade. Achei mais interessante baixar o código fonte do JUnit e eis que encontro o seguinte trecho de código:

static public void assertEquals(Object expected, Object actual) {
	assertEquals(null, expected, actual);

}

static public void assertEquals(String message, Object expected, Object actual) {
	if (expected == null && actual == null)
		return;
	if (expected != null && isEquals(expected, actual))
		return;
	else if (expected instanceof String && actual instanceof String) {
		String cleanMessage= message == null ? "" : message;
		throw new ComparisonFailure(cleanMessage, (String)expected, (String)actual);
	}
	else
	        failNotEquals(message, expected, actual);
}

private static boolean isEquals(Object expected, Object actual) {
	if (expected instanceof Number && actual instanceof Number)
		return ((Number) expected).longValue() == ((Number) actual).longValue();
	return expected.equals(actual);
}

Veja que o metodo assertEquals delega para o método isEquals cujo faz um instanceOf verificando se os objetos sendo comparados são do tipo Number. Caso sejam, o metodo os transforma em long para depois compará-los.
Bingo. Com isso compara-se apenas a parte inteira do número, logo, aquele primeiro teste passou.

Meu próximo passo foi procurar na lista de bugs do JUnit se este já era um velho conhecido.
Para minha não surpresa lá estava o danado.

Esse problema foi encontrado na versão 4.3.1 do JUnit, que vem no eclipse europa, e já foi corrigido, veja o metodo isEqual da versão 4.5

private static boolean isEquals(Object expected, Object actual) {
	return expected.equals(actual);
}

Agora sim …

Por que eu ainda estava usando o eclipse europa?
Eu sei lá. Só sei que, foi bem mais divertido que postar a pergunta e ficar dando F5 no aguardo da resposta.

SOA is this … SOA is that …

August 30, 2008

Não é tão novo mas ainda não tinha visto.
Qualquer semelhança com a realidade é mera coincidência.

http://www.gregthearchitect.com/episode_SOA_this.html

Curriculo (ou Um post de fúria)

August 21, 2008

Será que alguma empresa me contrataria se eu lhe apresentasse este currículo?

Objetivo profissional

  • Desenvolver software de forma simples, não burocrática, (até prazerosa, porque não?) entregando ao cliente o que ele realmente necessita – Software funcionando (jura!?)

Qualificações profissionais

  • Não sou especialista em toda e qualquer tecnologia de 3 ou 4 letras surgida desde mil novecentos e bolinha até o último hipe do momento. Ex: TCP/IP, HTTP, XML, XSD, XSTL, SOAP, JSON, POX, EBJ, JSP, JSTL, HTML, DHTML, DOM, CSS, UML, CVS, SVN, SQL, AJAX, BPM, ESB só para citar algumas. Mas conheço um pouco de cada.
  • Não tenho vergonha, medo, pavor nem calafrios em dizer “Não sei, mas posso estudar e lhe digo”.
  • Não sei mentir. Não, nem para aquele cliente mala que está exigindo da sua consultoria um mega-blaster, power, ultra profissional, que tenha 25 anos de experiência em todas as tecnologias do primeiro item acima e “entenda do negócio”, apenas para ficar “especificando o sistema” em Microsoft Word e Enterprise Architect.
  • Odeio trabalhar mais de 8 horas por dia todos os dias. Eventualmente, veja bem, EVENTUALMENTE pode acontecer.
  • Não acho que a melhor forma de avaliar quantitativamente e/ou qualitativamente o trabalho das pessoas seja através dos entediantes e inúteis Timeshets. (Atenção para a palavra em itálico. Você trabalha com pessoas. Repita comigo pes-so-as. Recursos são impressoras, computadores, aparelhos de fax, etc).
  • Discordo da visão na qual o analista de sistemas é o cara inteligente, que pensa em tudo e faz o trabalho intelectual de especificar, enquanto o operário programador não precisa pensar pois apenas tem de apertar os parafusos, ops codificar.
  • Não tenho a “ambição” de “subir de cargo” até virar gerente de projetos, assim como não tenho nada contra “programar para sempre”. (Isso não significa que eu não queira evoluir, paguá!)
  • Não acho que esses caras (famosos: 1, 2, 3, 4, 5, 6, 7, 8 & ainda não tão famosos: 9, 10, 11, 12, 13 …) são xiitas, prepotentes que se acham e inventam ou dizem um monte de coisas simplesmente para promoverem a si mesmos ou suas empresas e/ou vender seus livros pois “essas coisas só funcionam na teoria”. (Você pelo menos já tentou?)
  • Aprecio muito, muito mesmo, uma cervejinha com os amigos de vez em quando (isso, isso mesmo, tenho amigos fora da empresa sim).

O engraçado (se não fosse trágico) é que, grande parte dessas colocações são verdades para a maioria dos desenvolvedores. Quem não gostaria de trabalhar 8 horas por dia?Quem conhece a fundo todas as tecnologias? Quantos de nós odiariamos ser gerentes de projeto?
Do outro lado, o empregador não perderia em nada prestando atenção nesses pontos. Todos eles dizem respeito a qualidade de vida, trabalho bem feito, cliente satisfeito, dinheiro no bolso.
Então qual é o problema?
Só me resta concluir que a maioria das empresas gostam de ser enganadas. Dão valor aos mentirosos, aqueles que “manjam” tudo de tudo e tem orgasmos multiplos trabalhando 15 horas por dia.

O problema, como já disse, é que não sei mentir!