<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CUYGQng7eCp7ImA9WhRUEU8.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856</id><updated>2012-01-21T03:18:43.600-02:00</updated><category term="DPatterns" /><category term="processos" /><category term="scrum" /><category term="metodologias" /><category term="agile" /><category term="workshop" /><category term="mps.br" /><category term="código" /><category term="modelos" /><category term="cmmi" /><category term="OObjetos" /><category term="gerência de projetos" /><category term="xp" /><title>Craft Nicely</title><subtitle type="html">Qualidade de software em geral, de processos e metodologias a questões de design, boas práticas, padrões, etc.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://craftnicely.blogspot.com/" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/craftnicely" /><feedburner:info uri="craftnicely" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A04NQ3w6cCp7ImA9WhZSFU8.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-1712496312374080706</id><published>2011-03-30T21:06:00.000-03:00</published><updated>2011-03-30T21:06:32.218-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-30T21:06:32.218-03:00</app:edited><title>Introduzindo novas tecnologias</title><content type="html">Em conversa recente com amigos, levantamos a dificuldade de se introduzir novas tecnologias, como um novo ambiente ou uma nova linguagem de programação em uma organização.&amp;nbsp;A questão não se resume a problemas técnicos, mas a problemas pessoais, barreiras psicológicas, etc.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Por exemplo, se uma pessoa se considera em uma zona de conforto (por exemplo, se ela domina bastante uma linguagem de programação popular) pode haver uma certa resistência em colocá-la para aprender uma nova tecnologia (como outra linguagem de programação).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Para resolver problemas como estes, há diversos tipos de abordagens, envolvendo, inclusive, tirá-la da zona de conforto. No entanto, o propósito deste post é discutir questões organizacionais e levantar 5 pontos interessantes para definir uma estratégia para a introdução de novas tecnologias, mais especificamente, de uma nova linguagem de programação, na esperança de que alguns destes pontos possam ser úteis inclusive em outros contextos.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Existem vários motivadores para que uma organização resolva adotar uma nova tecnologia. Entre eles, a exigência de um projeto específico ou de um cliente importante ou até uma meta organizacional. Estes cenários tem suas peculiaridades e devem ser exploradas de forma diferenciada.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Se um projeto específico deve ser feito com uma tecnologia diferente da que a equipe está acostumada a trabalhar, pode ser conveniente, para reduzir os riscos do projeto, investir em treinamentos, contratar gente especializada ou encontrar algum colaborador que detenha conhecimento suficiente e possa dedicar atenção suficiente à equipe do projeto. Após a conclusão do projeto e seu período de manutenção, a mesma demanda por aquela tecnologia pode não ser mais necessária e evoluções podem ser feitas por membros da equipe que adquiriram conhecimento através do primeiro projeto.&lt;br /&gt;
&lt;br /&gt;
Diferentemente deste cenário, a de exigência de um cliente importante ou uma meta estratégica da organização são questões mais duradouras e mais impactantes na organização pois outros futuros projetos serão garantidamente construídos sobre a nova base tecnológica.&lt;br /&gt;
&lt;br /&gt;
O início de todo projeto já traz suas próprias complicações. Todos os envolvidos estão se familiarizando com os objetivos do cliente, com os padrões do projeto, sua arquitetura, suas funcionalidades e restrições. Além da própria curva de aprendizado do projeto, trazer uma nova linguagem de programação traz as curvas de aprendizado do ambiente de desenvolvimento e da linguagem em si, além de bibliotecas e frameworks de terceiros, sem as quais se torna muito custoso desenvolver softwares profissionalmente.&lt;br /&gt;
&lt;br /&gt;
Assim, iniciar com uma equipe inexperiente um projeto com tantas novidades pode ser bastante caótico. Enquanto uma organização pode achar que um projeto pequeno pode ser utilizado, vale lembrar que um atraso de 1 semana em um projeto de 1 mês é muito pior que um atraso de 2 semanas em um projeto de 6 meses. Por outro lado, passar 2 meses na construção de um projeto para descobrir que é inviável na tecnologia escolhida pode inviabilizar o projeto completamente.&lt;br /&gt;
&lt;br /&gt;
Então, quais ações poderiam ser adotadas para minimizar o impacto da introdução de uma nova tecnologia, como uma linguagem de programação?&lt;br /&gt;
&lt;br /&gt;
Minha primeira sugestão é simples:&lt;br /&gt;
&lt;br /&gt;
Quando se trata de atingir um objetivo/meta organizacional, o custo deve ser organizacional e o treinamento da equipe deve ser encarado da mesma forma: como um investimento para se atingir um objetivo.&lt;br /&gt;
Logo, pode ser contratado um treinamento, uma consultoria especializada para coaching/mentoring ou tentar orientar o aprendizado individual dos colaboradores.&lt;br /&gt;
Uma forma simples de fazer isto é a minha primeira proposta:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1- Alocar pequenas tarefas para cada colaborador.&lt;/b&gt;&lt;br /&gt;
Por exemplo, um fica responsável por configurar o ambiente e documentar de forma que outros consigam fazê-lo. Outro configura de acordo com o conhecimento registrado e cria uma projeto de exemplo, como o famoso "hello world", registrando seu aprendizado. Um terceiro pode implementar algo simples, como um cadastro de usuários, e um quarto, um sistema de login.&lt;br /&gt;
Através de atividades simples e pequenas, pode-se construir e incrementar o conhecimento organizacional, levando à minha segunda proposta.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2- Projeto startup.&lt;/b&gt;&lt;br /&gt;
Um projeto configurado com algumas funcionalidades simples e comuns pode ser replicado para servir como ponto de partida para outro projeto. Além de servir como exemplo, pode já trazer algumas funcionalidades comuns já implementadas, bastando fazer pequenos ajustes. Isto diminui o tempo e custo do projeto, compensando pelos gastos no aprendizado. Como outros projetos serão feitos na mesma tecnologia, a cada projeto, uma parte deste investimento será retornado.&lt;br /&gt;
Um projeto interno também pode ser utilizado se for considerado que seu investimento trará retorno para organização, no entanto, às vezes vale mais a pena escolher um pacote de funcionalidades comuns que irão se repetir em projetos externos ao invés de escolher um projeto interno com muitas especificidades.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3- Investigar, no início do projeto, como resolver as partes mais complicadas, as que se julga serem mais difíceis de serem feitas.&lt;/b&gt;&lt;br /&gt;
Muitas vezes pode-se descobrir frameworks ou bibliotecas que sozinhos ou combinados podem resolver o problema de forma satisfatória, no entanto, pode-se descobrir que tudo terá que ser construído do zero ou que esta é a forma mais apropriada para aquele cenário. Saber disto no início do projeto ajuda a determinar se a escolha da tecnologia foi adequada, se as necessidades serão atendidas e a minimizar o impacto destes riscos. Também, resolver estas questões pode trazer uma sensação de confiança e tranquilidade à equipe, o que pode ajudar a garantir o sucesso do projeto e até animá-los no aprendizado da nova tecnologia.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4- Escolher o cliente é tão importante quanto escolher o projeto.&lt;/b&gt;&lt;br /&gt;
Alguns clientes são mais tolerantes a pequenos atrasos que outros, alguns podem aceitar compensações (como uma ou outra funcionalidade extra) ao contrário de outros. Às vezes esta questão tem que ser levada em consideração na escolha de um primeiro projeto em uma nova tecnologia.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;5- Rever o plano de implantação com antecedência.&lt;/b&gt;&lt;br /&gt;
Se a sua organização não tem um plano de implantação mas mesmo assim irá implantar o projeto, convém não só fazer um teste da implantação antes do primeiro release como documentar os passos tomados e as dificuldades encontradas, para que no momento do primeiro release, tudo siga suavemente. Isto é importante tanto para a moral da equipe, em saber que o primeiro release foi implantado e está funcionando corretamente quanto para que não se virem noites tentando resolver problemas de última hora, o que pode inclusive afetar a imagem da organização para o cliente.&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-1712496312374080706?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/JGwoSA4lvJQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/1712496312374080706/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2011/03/introduzindo-novas-tecnologias.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1712496312374080706?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1712496312374080706?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/JGwoSA4lvJQ/introduzindo-novas-tecnologias.html" title="Introduzindo novas tecnologias" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2011/03/introduzindo-novas-tecnologias.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMNSXwyfip7ImA9Wx9VGU4.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-5236637749737412677</id><published>2011-02-05T18:24:00.000-02:00</published><updated>2011-02-05T18:24:58.296-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-05T18:24:58.296-02:00</app:edited><title>O diferencial Ágil</title><content type="html">Desenvolvimento iterativo e incremental em ciclos curtos. Só isso?&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Em todas as palestras que já fui até hoje sobre metodologias ágeis, seja quais forem (XP, Scrum, FDD, etc), é sempre a mesma história:&lt;br /&gt;
&lt;br /&gt;
Métodos Ágeis são melhores que cascata porque ...&lt;br /&gt;
ou&lt;br /&gt;
Métodos Ágeis são melhores que métodos tradicionais (ou engenharia de software tradicional) porque...&lt;br /&gt;
&lt;br /&gt;
Invariavelmente a frase segue comparando o modelo de ciclo de vida iterativo e incremental com o modelo cascata. Este último, sempre conhecido por altíssimos índices de fracasso foi introduzido à comunidade em um artigo de 1970 que dizia que seguí-lo era normalmente um tiro no pé e já falando de absorver feedback ao longo do projeto.&lt;br /&gt;
&lt;br /&gt;
Então vamos a alguns pontos para melhorar o discurso Ágil:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Ainda estou para ver uma metodologia Ágil que preconize o uso de cascata. São todas iterativas e incrementais. Sendo assim, dizer que metodologia A ou B é legal porque é iterativa e incremental é chover no molhado. Este é o mínimo. Quando for apresentar uma metodologia, enfatize o seu diferencial.&lt;/li&gt;
&lt;li&gt;Só mostrar as vantagens do uso do ciclo de vida iterativo e incremental não é nem de longe o suficiente para dizer que uma metodologia é boa ou é ágil, visto que pode-se usar o mesmo modelo de ciclo de vida associado a qualquer metodologia ou processo, ainda que totalmente "tradicional".&lt;/li&gt;
&lt;li&gt;"Métodos tradicionais" ou "Engenharia de Software tradicional" NÃO são sinônimos de cascata. Se você teve uma péssima experiência na empresa onde trabalhou porque usou cascata, o problema foi onde&amp;nbsp;você&amp;nbsp;trabalhou ou a forma de trabalhar. Não culpe a Engenharia de Software porque&amp;nbsp;você&amp;nbsp;trabalhou em algum lugar onde as pessoas tinham pouco conhecimento sobre o assunto. No máximo você pode por a culpa nas universidades que não preparam direito ou que não deixam claro para o formado que ele não sabe o suficiente para fazer determinadas coisas, como montar um processo de desenvolvimento. O fato de você ter feito de uma maneira incompatível com as necessidades, contexto e restrições do projeto não significa que a Engenharia de Software está errada.&lt;/li&gt;
&lt;li&gt;E quanto ao "tradicional", se você acha que o modelo de ciclo de vida iterativo-incremental, revisão por pares/pair programming, escrever testes antes de desenvolver/testar enquanto se desenvolve, e outras práticas são super modernas... well, think again...&lt;/li&gt;
&lt;li&gt;Falar bem de A comparando com um B que você escolheu por ser pior é fácil. Faça diferente. Diga porque você acha bom, compare com coisas similares. Mostre vantagens mas mostre também as desvantagens.&lt;/li&gt;
&lt;li&gt;Por último, PMBOK não é um processo nem uma metodologia. É um conjunto de práticas apenas. RUP não é um processo específico, é um framework para construção de processos. Muito menos é cascata. Do &lt;a href="http://www-01.ibm.com/software/awdtools/rup/"&gt;site do RUP&lt;/a&gt;: "RUP &lt;b&gt;promotes iterative development&lt;/b&gt; and organizes the development (...)". Da &lt;a href="http://en.wikipedia.org/wiki/IBM_Rational_Unified_Process"&gt;wikipedia&lt;/a&gt;: "The Rational Unified Process &lt;b&gt;(RUP) is an iterative software development process framework&lt;/b&gt; (...)". CMMI e MPS.BR, não são processos, não exigem que seja utilizado cascata e não restringem o uso de métodos Ágeis. De fato, se você segue um destes modelos e escolheu um ciclo de vida, vai ter que apresentar uma justificativa, o que pode tornar um pouco difícil a adoção de cascata. Sem falar de inúmeros relatos de adoção bem sucedida destes modelos juntamente com metodologias ágeis.&amp;nbsp;&lt;a href="http://craftnicely.blogspot.com/2010/11/agile-e-tradicional-pingos-nos-is.html"&gt;Não fale do que não conhece, e principalmente, não fale mal.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-5236637749737412677?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/rhqrRMwDURw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/5236637749737412677/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2011/02/o-diferencial-agil.html#comment-form" title="4 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/5236637749737412677?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/5236637749737412677?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/rhqrRMwDURw/o-diferencial-agil.html" title="O diferencial Ágil" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2011/02/o-diferencial-agil.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYEQHcyfCp7ImA9Wx9SE0U.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-5729945093695441151</id><published>2010-12-03T12:21:00.000-02:00</published><updated>2010-12-03T12:21:41.994-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-03T12:21:41.994-02:00</app:edited><title>Design Emergente no TI Master</title><content type="html">Amigos, a Nicolly Vimercate, jornalista do portal TI Master (&lt;a href="http://www.timaster.com.br/"&gt;http://www.timaster.com.br/&lt;/a&gt;) me entrevistou sobre Design Emergente e a matéria entitulada "&lt;a href="http://timaster.com.br/revista/materias/main_materia.asp?codigo=1766"&gt;Projeto de software: antes ou durante?&lt;/a&gt;" foi publicada ontem:&amp;nbsp;&lt;a href="http://timaster.com.br/revista/materias/main_materia.asp?codigo=1766"&gt;http://timaster.com.br/revista/materias/main_materia.asp?codigo=1766&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Meus agradecimentos à Nicolly, à equipe editorial do TI Master e ao Vinícius Morgado (que tem um blog também, o &lt;a href="http://viniciusmorgado.blogspot.com/"&gt;Bit Design&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Espero que gostem!&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-5729945093695441151?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/R8wvkvmIFRA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/5729945093695441151/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/12/design-emergente-no-ti-master.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/5729945093695441151?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/5729945093695441151?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/R8wvkvmIFRA/design-emergente-no-ti-master.html" title="Design Emergente no TI Master" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/12/design-emergente-no-ti-master.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IGQH05fyp7ImA9Wx9TE0w.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-2206090345032389625</id><published>2010-11-21T01:52:00.000-02:00</published><updated>2010-11-21T01:52:01.327-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-21T01:52:01.327-02:00</app:edited><title>Agile e "tradicional": pingos nos i's.</title><content type="html">Bom, como vocês podem já ter notado pelos meus posts, me interesso tanto Agile como não-agile. Inclusive já postei sobre o que eu considero ser Agile e não-agile (o que muitos chamam de tradicional). O caso é que desde que comecei a estudar processos e metodologias, estudo nos dois flancos. RUP, XP, PMBOK, MPS.BR, CMMI, Scrum, Kanban, Cascata, Iterativo e Incremental, etc.&lt;br /&gt;
Bom, pra quem conhece estas coisas, sabe que eu listei coisas que tem a ver e coisas que não tem a ver entre si. &amp;nbsp;Entre processos, metodologias, modelos de maturidade, e afins, fiz uma mistura proposital.&lt;br /&gt;
&lt;br /&gt;
Em muitas conversas, vejo pessoas comparando coisas diferentes, falando coisas sobre estes assuntos e tratando-os como sendo a mesma coisa ou fazendo outros tipos de confusões. Ok, são muitas siglas, eu sei. Se você se confunde, está perdido ou conhece muito pouco sobre estas coisas, chegou a hora de desfazer a confusão:&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;

O modelo Cascata&lt;/h4&gt;
&lt;a href="http://en.wikipedia.org/wiki/Waterfall_model"&gt;Cascata&lt;/a&gt; não é um processo. Cascata não é uma metodologia. Cascata, assim como Iterativo e Incremental, é um Modelo de Ciclo de Vida.&lt;br /&gt;
O modelo cascata é aquele em que se faz toda a análise no início, depois se faz toda a modelagem, toda a codificação e todos os testes. Quaisquer que sejam as fases do seu processo, se em uma fase (por exemplo, análise) você faz tudo o que tem pra fazer do projeto (por exemplo, fez análise do projeto inteiro) não retorna a ela depois que entrou em outra (por exemplo, codificação), então você está seguindo um modelo em cascata.&lt;br /&gt;
&lt;br /&gt;
O XP e o Scrum são metodologias que não adotam o modelo cascata pois depois de fazer codificação e testes, eles voltam para fazer análise e modelagem de funcionalidades que ainda não foram abordadas. O modelo que adotam é Iterativo e Incremental.&lt;br /&gt;
&lt;br /&gt;
Notem que o cliclo de vida trata única e exlusivamente da ordem das atividades e não quais atividades são feitas. Por exemplo, você pode ter um processo em Cascata que se inicia com o registro de uma visão, um backlog de user stories, os testes delas e por último seu desenvolvimento com uma integração no final, quando então são feitos uma revisão e uma retrospectiva. Pode até desenvolver em pair programming. Notem que não é Scrum, pois o Scrum fala especificamente de outro modelo de ciclo de vida. No entanto, também não são utilizados casos de uso nem nada que tenha ganho popularidade com Agile.&lt;br /&gt;
Ao mesmo tempo posso ter todas as atividades mais tradicionais e ainda ter um processo em várias iterações, onde em cada uma eu escolho alguns requisitos e passo por todas as fases até gerar um release intermediário.&lt;br /&gt;
&lt;br /&gt;
Vale lembrar que métodos ágeis não foram os primeiros a adotar o modelo iterativo e incremental. O RUP, um framework de processos, adota o mesmo modelo.&lt;br /&gt;
&lt;h4&gt;

RUP&lt;/h4&gt;
&lt;a href="http://en.wikipedia.org/wiki/RUP"&gt;RUP&lt;/a&gt; não é um processo em si. O RUP, o Rational Unified Process, criado pela Rational (empresa que criou o Rational Rose, famosa ferramenta de modelagem), adquirida pela IBM, é um framework de processos de software.&lt;br /&gt;
&lt;br /&gt;
Isto significa que o RUP apresenta vários artefatos, templates, atividades, fases, objetivando atender um grande escopo de necessidades.&lt;br /&gt;
&lt;br /&gt;
Assim como todo framework, é necessário que em cada situação, a pessoa encarregada de construir o processo analise as suas necessidades e faça um recorte, uma escolha do que deve ser utilizado dentro do que o RUP apresenta.&lt;br /&gt;
&lt;br /&gt;
Ou seja, o RUP pode dar origem a um processo extremamente burocrático ou até um processo leve e fácil de ser seguido. Como qualquer coisa na nossa área, depende de como é usado, por quem é usado e em que cenário foi usado.&lt;br /&gt;
&lt;br /&gt;
Nota-se já que o RUP não é UM processo e que RUP e Cascata são coisas completamente distintas, embora o RUP possa ser mapeado para um processo em Cascata. Afinal, ninguém irá impedir ninguém de fazer adaptações, sejam boas ou ruins. Se você seguiu um processo baseado no RUP e não gostou, a culpa pode não ser do RUP.&lt;br /&gt;
&lt;h4&gt;

PMBOK&lt;/h4&gt;
O &lt;a href="http://en.wikipedia.org/wiki/PMBOK"&gt;Project Management Body Of Knowledge&lt;/a&gt; (corpo de conhecimento em gerência de projetos) apenas organiza o conhecimento na área de gerência de projetos. Aborda temas como gerência de riscos, modelos de ciclo de vida, etc. Porque o Project Management Institute (PMI) resolveu organizar o conhecimento na área não quer dizer que você deve utilizar tudo o que se conhece na área em um projeto. Além disso, não há definição de seqüência de atividades, entradas e saídas. Não é um processo. É apenas o que o nome diz: um corpo de conhecimento.&lt;br /&gt;
&lt;br /&gt;
Portanto, chamar PMBOK de processo é um erro. Assim como é um erro atrelá-lo ao modelo Cascata ou ao RUP.&lt;br /&gt;
&lt;br /&gt;
Claro que como um projeto requer gerência, um framework de processos como o RUP irá incluir atividades de gerência que podem ser associadas a alguns conhecimentos presentes num corpo de conhecimento de gerência, pois se não estiverem associadas, significa que o corpo de conhecimento de gerência deixou de incluir alguma coisa.&lt;br /&gt;
&lt;br /&gt;
Da mesma forma, é apresentado o modelo Cascata assim como o iterativo e incremental. É um corpo de conhecimento, como um catálogo.&lt;br /&gt;
&lt;h4&gt;

CMMI e MPS.BR&lt;/h4&gt;
&lt;a href="http://en.wikipedia.org/wiki/CMMI"&gt;CMMI&lt;/a&gt; e &lt;a href="http://pt.wikipedia.org/wiki/Melhoria_de_Processos_do_Software_Brasileiro"&gt;MPS.BR&lt;/a&gt; não são processos, não são métodos, não são metodologias, são modelos de maturidade.&lt;br /&gt;
Um modelo de maturidade apresenta um guia do que uma organização pode fazer para melhorar sua maturidade e sua capacidade.&lt;br /&gt;
&lt;br /&gt;
Este guia apresenta "o que" fazer e não "como". Por exemplo, ele diz que você deve desenvolver seus requisitos. Se seus requisitos são casos de uso ou user stories, quem decide é você. Ele diz que você deve testar. Se você fará testes automatizados ou manuais, se utilizará TDD ou não, quem decide é você. Se o seu processo é cascata ou iterativo e incremental, quem decide é você. Se você faz sprint review e sprint retrospective ou não, quem decide é você.&lt;br /&gt;
&lt;br /&gt;
O interessante destes modelos é que eles apresentam, a cada nível, novas áreas e novos requisitos para áreas introduzidas anteriormente, servindo como guias para aumentar a maturidade e a capacidade de se fazer software, reduzindo custos, prazos e aumentando a qualidade.&lt;br /&gt;
&lt;br /&gt;
É cada vez mais comum atualmente encontrar organizações que utilizam métodos ágeis e são avaliadas seguindo modelos de maturidade, pois há um grande nível de compatibilidade.&lt;br /&gt;
&lt;h4&gt;

Metodologias Ágeis&lt;/h4&gt;
&lt;a href="http://en.wikipedia.org/wiki/Agile_software_development"&gt;Metodologias ou&amp;nbsp;métodos&amp;nbsp;Ágeis&lt;/a&gt; são aqueles que estão alinhados com o &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;sqi=2&amp;amp;ved=0CBwQFjAA&amp;amp;url=http%3A%2F%2Fagilemanifesto.org%2F&amp;amp;ei=Z5PoTOC-AYL6lwe3kan6Cw&amp;amp;usg=AFQjCNHwXRVf_KP8rGFX8ts0m0mI78Wc5Q&amp;amp;sig2=NgG_ddN-KquVdc8zf94N8g"&gt;Manifesto Ágil&lt;/a&gt;, ou seja, qualquer processo de desenvolvimento que valorize:&lt;br /&gt;
"Indivíduos e interações mais que processos e ferramentas&lt;br /&gt;
Software em funcionamento mais que documentação abrangente&lt;br /&gt;
Colaboração com o cliente mais que negociação de contratos&lt;br /&gt;
Responder a mudanças mais que seguir um plano"&lt;br /&gt;
&lt;br /&gt;
Os mais populares são &lt;a href="http://en.wikipedia.org/wiki/Scrum_(development)"&gt;Scrum&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Extreme_Programming"&gt;Extreme Programming (XP)&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Feature_Driven_Development"&gt;FDD&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/OpenUP"&gt;OpenUP&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Crystal_Clear_(software_development)"&gt;Crystal&lt;/a&gt; e &lt;a href="http://en.wikipedia.org/wiki/Kanban"&gt;Kanban&lt;/a&gt;, mas além destes, qualquer processo que siga os valores acima pode ser considerado Ágil, independente das práticas e das atividades que são executadas. Logo, não há problema em ser Ágil e utilizar um processo baseado no RUP que atende um nível do MPS.BR num processo cuja gerência é orientada por práticas descritas no PMBOK.&lt;br /&gt;
&lt;br /&gt;
Uma parte da comunidade Ágil atualmente rechaça vários destes conceitos como se fossem incompatíveis com a filosofia e não são. Pior, falam deles como se fossem o contrário de Ágil. Já vi inúmeras comparações entre Cascata e Scrum dizendo que o último é melhor. Dizem que MPS.BR e PMBOK são Cascata e por isso são ruins e outras coisas do gênero.&lt;br /&gt;
&lt;br /&gt;
Escolhi estes tópicos em particular porque normalmente a comunidade Ágil faz referência a eles como "tradicional" numa alusão a uma forma tradicional de se fazer software. A questão é que eles não definem uma forma "tradicional" de se fazer software pois não há ruptura entre o movimento Ágil e estes conceitos, visto que não são antagônicos, não são incompatíveis. É como dizer que existe pizza antes e depois de existirem pizzarias, quando você antes podia comer uma pizza excelente em um restaurante que não seja especializado e pode até comer outras massas em uma pizzaria sem que os diferentes estabelecimentos se descaracterizem.&lt;br /&gt;
&lt;br /&gt;
Mas há, dentro do movimento Ágil, este sentimento de ruptura. É inegável. Como em muitas conversas é necessário fazer referência às formas de se desenvolver anteriores ao movimento Ágil, eu uso "não-Ágil".&lt;br /&gt;
&lt;br /&gt;
Espero ter contribuído para desfazer a confusão.&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-2206090345032389625?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/GUeg7RWJllY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/2206090345032389625/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/11/agile-e-tradicional-pingos-nos-is.html#comment-form" title="5 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/2206090345032389625?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/2206090345032389625?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/GUeg7RWJllY/agile-e-tradicional-pingos-nos-is.html" title="Agile e &quot;tradicional&quot;: pingos nos i's." /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/11/agile-e-tradicional-pingos-nos-is.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIEQX8-cSp7ImA9Wx5bFkg.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-6619805946133810400</id><published>2010-11-01T21:01:00.000-02:00</published><updated>2010-11-01T21:01:40.159-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-01T21:01:40.159-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gerência de projetos" /><category scheme="http://www.blogger.com/atom/ns#" term="mps.br" /><category scheme="http://www.blogger.com/atom/ns#" term="workshop" /><title>Workshop de Gerência de Projetos</title><content type="html">Amigos, eu sei que o workshop é no Rio de Janeiro mas como meu blog ainda está nos primeiros passos, a maioria dos leitores são amigos (ou amigos de amigos). Assim grande parte está no Rio de Janeiro e portanto acho que vale a pena avisá-los que haverá um Workshop bastante interessante sobre gerência de projetos, baratinho.&lt;br /&gt;
Este é o site oficial:&lt;br /&gt;
&lt;a href="http://sites.google.com/site/workshopsmps/home/workshop-19-10-2010---chamada"&gt;http://sites.google.com/site/workshopsmps/home/workshop-19-10-2010---chamada&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
A chamada está aqui:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_t0UCMhLP4m0/TM9GMCj1SNI/AAAAAAAAAQc/B74TIXDU68s/s1600/worshop_GPR.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://2.bp.blogspot.com/_t0UCMhLP4m0/TM9GMCj1SNI/AAAAAAAAAQc/B74TIXDU68s/s640/worshop_GPR.png" width="443" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-6619805946133810400?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/IiGqXAbpwKE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/6619805946133810400/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/11/workshop-de-gerencia-de-projetos.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/6619805946133810400?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/6619805946133810400?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/IiGqXAbpwKE/workshop-de-gerencia-de-projetos.html" title="Workshop de Gerência de Projetos" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_t0UCMhLP4m0/TM9GMCj1SNI/AAAAAAAAAQc/B74TIXDU68s/s72-c/worshop_GPR.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/11/workshop-de-gerencia-de-projetos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkICQHs5eCp7ImA9Wx5XFUQ.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-1348655274853607213</id><published>2010-09-15T19:40:00.001-03:00</published><updated>2010-09-15T19:42:41.520-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-15T19:42:41.520-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><category scheme="http://www.blogger.com/atom/ns#" term="modelos" /><category scheme="http://www.blogger.com/atom/ns#" term="xp" /><category scheme="http://www.blogger.com/atom/ns#" term="metodologias" /><category scheme="http://www.blogger.com/atom/ns#" term="mps.br" /><category scheme="http://www.blogger.com/atom/ns#" term="cmmi" /><category scheme="http://www.blogger.com/atom/ns#" term="processos" /><category scheme="http://www.blogger.com/atom/ns#" term="scrum" /><title>Manifesto Ágil para entender a Agilidade</title><content type="html">Uma vez eu estava assistindo a uma palestra do David Card ("&lt;a href="http://www.amazon.com/gp/product/0135685931?ie=UTF8&amp;amp;tag=craftnicely-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0135685931"&gt;Measuring Software Design Quality&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=craftnicely-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0135685931" style="border: none !important; margin: 0px !important;" width="1" /&gt;" (Prentice Hall, 1990) e "&lt;a href="http://www.amazon.com/gp/product/0201715163?ie=UTF8&amp;amp;tag=craftnicely-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0201715163"&gt;Practical Software Measurement&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=craftnicely-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201715163" style="border: none !important; margin: 0px !important;" width="1" /&gt;" (Addison Wesley, 2002)) e ele falou uma coisa bastante interessante, sobre a busca por um processo &lt;a href="http://en.wikipedia.org/wiki/Lean_software_development"&gt;Lean&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Ele disse que uma pessoa pode ficar magra de duas formas. Fazendo uma dieta ou treinando para correr uma maratona. E ele pergunta retoricamente, qual das formas se espera que seja mais saudável, com os melhores resultados no final.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;É um ponto de vista muito interessante que eu gostaria de aproveitar para explorar. Na apresentação dele, ele falava que muitas empresas querem ter um processo Lean e acham que vão conseguir isso fazendo cortes, cortando atividades e pulando etapas enquanto que o Lean que traz benefícios deveria vir através de um processo contínuo de melhoria.&lt;br /&gt;
&lt;br /&gt;
Estou falando disso por causa da moda Ágil. Muitas empresas hoje em dia gostam de dizer que são Ágeis porque usam XP ou que são Ágeis porque usam Scrum ou seja lá o que for. Ser Ágil não é seguir um script. Ser Ágil exige mudar o mindset.&lt;br /&gt;
&lt;br /&gt;
Não adianta deixar de gerar os artefatos que agregam valor para o cliente ou para a empresa. Também não adianta trocar artefatos que se gerava para gerar outros sem entendê-los ou sem extrair benefício suficiente deles, benefício que os justifique.&lt;br /&gt;
&lt;br /&gt;
Não existe receita de bolo correta. Nenhuma empresa faz &lt;a href="http://www.scrumalliance.org/"&gt;Scrum&lt;/a&gt; igual. Nenhuma empresa faz &lt;a href="http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_Extrema"&gt;XP&lt;/a&gt; igual. Cada empresa tem sua própria cultura organizacional, seu perfil, seus clientes, etc, e fazer modificações Ágeis significa entender o mindset.&lt;br /&gt;
&lt;br /&gt;
Acho que este é o principal valor do &lt;a href="http://agilemanifesto.org/"&gt;Manifesto Ágil&lt;/a&gt;. Entendê-lo é entender que não é necessário seguir a receita A ou B para ser Ágil (até porque na primeira necessidade de adaptação, correr-se-á o risco de perder a Agilidade.&lt;br /&gt;
&lt;br /&gt;
O que é necessário é melhorar o seu processo, seja qual for, seja um processo aderente a algum nível do &lt;a href="http://www.softex.br/mpsbr"&gt;MPS.BR&lt;/a&gt; ou do &lt;a href="http://www.sei.cmu.edu/cmmi"&gt;CMMI&lt;/a&gt;, seja algum processo baseado exclusivamente em um framework Ágil, de forma a atender os seus objetivos sem gastos desnecessários de recursos, sem perder o &lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;foco &lt;/span&gt;&lt;/b&gt;e melhorando sempre.&lt;br /&gt;
&lt;br /&gt;
Falando em foco, teve recentemente uma discussão bem interessante na lista da &lt;a href="http://groups.google.com/group/apln-brasil"&gt;APLN Brasil&lt;/a&gt; sobre melhoria contínua e métodos Ágeis. A pergunta original era sobre uma empresa que teria, hipoteticamente, estabilizado seus processos Ágeis de forma que era difícil enxergar uma melhoria.&lt;br /&gt;
&lt;br /&gt;
Acho curioso como algumas equipes vêem a melhoria como uma forma de se chegar a um modelo de desenvolvimento Ágil, lean. É muito fácil esquecer que as melhorias devem estar alinhadas com os objetivos estratégicos organizacionais e que estes nunca estão satisfeitos, logo, as melhorias devem ser buscadas de forma a se atingir estes objetivos. Se vc acha que não tem muito o que melhorar é porque está olhando para &lt;span class="Apple-style-span" style="font-family: inherit;"&gt;um cenário bem limitado, como suas atividades diárias. Com uma visão mais ampla do negócio e suas necessidades, as melhorias começam a aparecer com mais facilidade. Mas este é papo para outro post.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Links:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Agile Project Leadership Network (APLN):&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://www.apln.org/"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.apln.org/&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://groups.google.com/group/apln-brasil"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://groups.google.com/group/apln-brasil&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Lean:&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://en.wikipedia.org/wiki/Lean_software_development"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://en.wikipedia.org/wiki/Lean_software_development&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en)&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://cantinhodoagile.blogspot.com/2010/06/perspectiva-do-desenvolvimento-de.html"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://cantinhodoagile.blogspot.com/2010/06/perspectiva-do-desenvolvimento-de.html&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://www.infoq.com/br/news/2009/08/lean-30-segundos"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.infoq.com/br/news/2009/08/lean-30-segundos&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Agile Manifesto:&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://agilemanifesto.org/"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://agilemanifesto.org/&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en - oficial)&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://www.manifestoagil.com.br/"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.manifestoagil.com.br/&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(tradução do oficial)&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;a href="http://en.wikipedia.org/wiki/Agile_Manifesto"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://en.wikipedia.org/wiki/Agile_Manifesto&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en)&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;MPS.Br:&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;a href="http://www.softex.br/mpsbr" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.softex.br/mpsbr&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;(pt - Oficial)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;a href="http://pt.wikipedia.org/wiki/Mps.br" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://pt.wikipedia.org/wiki/Mps.br&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;CMMI:&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;a href="http://www.blogcmmi.com.br/" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.blogcmmi.com.br/&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;a href="http://pt.wikipedia.org/wiki/Cmmi" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://pt.wikipedia.org/wiki/Cmmi&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;a href="http://www.sei.cmu.edu/cmmi" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.sei.cmu.edu/cmmi&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;(en - Oficial)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;a href="http://en.wikipedia.org/wiki/CMMI" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://en.wikipedia.org/wiki/CMMI&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Scrum:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;a href="http://www.scrumalliance.org/" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.scrumalliance.org/&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en - Oficial)&lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29" style="color: #0066cc;"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;span class="Apple-style-span"&gt;&lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://en.wikipedia.org/wiki/Scrum_(development)&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;a href="http://pt.wikipedia.org/wiki/Scrum" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://pt.wikipedia.org/wiki/Scrum&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;br /&gt;&lt;br /&gt;eXtreme Programming:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;a href="http://www.improveit.com.br/xp" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.improveit.com.br/xp&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;a href="http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_Extrema" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://pt.wikipedia.org/wiki/Programação_Extrema&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(pt)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;a href="http://www.extremeprogramming.org/" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://www.extremeprogramming.org/&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Extreme_Programming" style="color: #0066cc;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;http://en.wikipedia.org/wiki/Extreme_Programming&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(en)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-1348655274853607213?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/XVrU0emBHE8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/1348655274853607213/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/09/manifesto-agil-para-entender-agilidade.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1348655274853607213?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1348655274853607213?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/XVrU0emBHE8/manifesto-agil-para-entender-agilidade.html" title="Manifesto Ágil para entender a Agilidade" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/09/manifesto-agil-para-entender-agilidade.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YMRHsyeSp7ImA9Wx5TGEo.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-8639651034823669567</id><published>2010-08-03T18:33:00.000-03:00</published><updated>2010-08-03T18:33:05.591-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-03T18:33:05.591-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><category scheme="http://www.blogger.com/atom/ns#" term="modelos" /><category scheme="http://www.blogger.com/atom/ns#" term="xp" /><category scheme="http://www.blogger.com/atom/ns#" term="metodologias" /><category scheme="http://www.blogger.com/atom/ns#" term="processos" /><category scheme="http://www.blogger.com/atom/ns#" term="scrum" /><title>Papéis e responsabilidades nos métodos ágeis</title><content type="html">Todo mundo conhece a brincadeira do telefone sem fio. Além de uma brincadeira de crianças, ela serve para ilustrar quanto de conhecimento se pode perder entre a captura de requisitos até as funcionalidades de fato implementadas, caso não haja o cuidado necessário.&lt;br /&gt;
&lt;br /&gt;
O interessante é que ao se buscar a solução para o problema, duas abordagens completamente diferentes podem ser tomadas.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
A primeira é a mais óbvia, detalhar o máximo possível. Junto com isto temos técnicas de levantamento de requisitos, técnicas para verificar/validar os requisitos e outros recursos.&amp;nbsp;Muitas informações interessantes ficam registradas e outras tantas podem ser extraídas de um &lt;a href="http://pt.wikipedia.org/wiki/Caso_de_uso"&gt;Caso de Uso&lt;/a&gt; bem feito. Informações que podem levar a melhores estimativas, redução de custos e até de prazos no futuro, informações valiosas para um processo de melhoria. Porém, é mais trabalhoso.&lt;br /&gt;
&lt;br /&gt;
A segunda, adotada pelos métodos &lt;a href="http://agilemanifesto.org/"&gt;Ágeis&lt;/a&gt; é a inversa. Detalhar o mínimo possível. E costuma funcionar dependendo do cenário.&lt;br /&gt;
&lt;br /&gt;
Ao escrever uma &lt;a href="http://en.wikipedia.org/wiki/User_story"&gt;User Story&lt;/a&gt;, a idéia é quase um lembrete do que deve ser desenvolvido e não a descrição exaustiva da funcionalidade. A abordagem se baseia no fato de que, se a perda de conhecimento acontece nos intermediários da comunicação entre o cliente ou usuário e o desenvolvedor, o melhor a se fazer é colocar os dois para conversar no momento em que aquela funcionalidade for implementada.&lt;br /&gt;
&lt;br /&gt;
Neste momento, o desenvolvedor se torna um pouco analista. A seguir, ele pode ser um pouco arquiteto, um pouco desenvolvedor, um pouco testador, etc. Claro, nada impede que se tenha gente experiente nestas áreas acompanhando o processo em cada fase, mas também não tem nada que exija isto.&amp;nbsp;Porém, quando o cliente ou usuário tem baixa disponibilidade para o projeto, as coisas podem sair um pouco diferentes do esperado.&lt;br /&gt;
&lt;br /&gt;
Não estou dizendo que uma abordagem é melhor ou pior que outra. Como eu estou tentando mostrar, há vantagens e desvantagens e a abordagem ideal deve levar em consideração a cultura organizacional e o alinhamento com os objetivos estratégicos da organização.&lt;br /&gt;
&lt;br /&gt;
A questão do mindset fica bem clara quando analisamos as abordagens. Um dos valores do &lt;a href="http://agilemanifesto.org/"&gt;Manifesto Ágil&lt;/a&gt; prega "Individuals and interactions over processes and tools". Isso significa que se deve preferir resolver um problema através da redefinição de papéis e responsabilidades ao invés de recorrer a mais ferramentas e alongar os processos &lt;i&gt;&lt;b&gt;desnecessariamente&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Se um problema pode ou não ser resolvido de formas mais alinhadas ao &lt;a href="http://agilemanifesto.org/"&gt;Manifesto Ágil&lt;/a&gt; é outra questão. Pode ser que possam, pode ser que naquela organização não possam ou ainda não se tenha encontrado uma forma de fazê-lo.&lt;br /&gt;
&lt;br /&gt;
Existe um limite para o que pode ser feito pois o necessário é aquilo que se precisa para se atingir um objetivo e não adianta abrir mão de informações que são importantes para manter outras partes do processo funcionando adequadamente ou até informações que poderiam comprometer os objetivos organizacionais caso faltassem.&lt;br /&gt;
&lt;br /&gt;
O limite do que é Ágil e o que não é, na verdade, é um limite móvel, que deve ser adaptado à capacidade e ao cenário de cada empresa.&amp;nbsp;Assim, eu diria que uma organização que tem como objetivo se tornar Ágil, deve começar mudando seu modo de enxergar os problemas.&lt;br /&gt;
&lt;br /&gt;
Tomando que uma empresa em busca da Agilidade julga como sendo melhor entre duas soluções aquela que está mais alinhada com os ideais do Manifesto Ágil, eu diria que, como sempre há uma forma de melhorar, nunca se é Ágil o suficiente.&lt;br /&gt;
&lt;br /&gt;
Logo, não importa muito se há muita coisa a ser melhorada ou se está difícil enxergar onde se pode melhorar.&amp;nbsp;O passo essencial para se tornar Ágil é mudar a perspectiva sobre os problemas, buscar soluções inovadoras e principalmente, mudar o mindset.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
Agile Manifesto:&lt;br /&gt;
&lt;a href="http://agilemanifesto.org/"&gt;http://agilemanifesto.org/&lt;/a&gt;&amp;nbsp;(en - oficial)&lt;br /&gt;
&lt;a href="http://www.manifestoagil.com.br/"&gt;http://www.manifestoagil.com.br/&lt;/a&gt;&amp;nbsp;(tradução do oficial)&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Agile_Manifesto"&gt;http://en.wikipedia.org/wiki/Agile_Manifesto&lt;/a&gt;&amp;nbsp;(en)&lt;br /&gt;
&lt;br /&gt;
User Stories:&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/User_story"&gt;http://en.wikipedia.org/wiki/User_story&lt;/a&gt;&amp;nbsp;(en)&lt;br /&gt;
&lt;br /&gt;
Casos de Uso&lt;br /&gt;
&lt;a href="http://pt.wikipedia.org/wiki/Caso_de_uso"&gt;http://pt.wikipedia.org/wiki/Caso_de_uso&lt;/a&gt;&amp;nbsp;(pt)&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Use_case"&gt;http://en.wikipedia.org/wiki/Use_case&lt;/a&gt;&amp;nbsp;(en)&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-8639651034823669567?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/YB6muOg4Quc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/8639651034823669567/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/08/papeis-e-responsabilidades-nos-metodos.html#comment-form" title="1 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8639651034823669567?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8639651034823669567?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/YB6muOg4Quc/papeis-e-responsabilidades-nos-metodos.html" title="Papéis e responsabilidades nos métodos ágeis" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/08/papeis-e-responsabilidades-nos-metodos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cAQHw5eCp7ImA9WxFbE0U.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-4323152639286485766</id><published>2010-06-27T22:17:00.002-03:00</published><updated>2010-07-06T01:04:01.220-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-06T01:04:01.220-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="código" /><title>SQL é para dados, lógica não!</title><content type="html">&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Engraçado como são montadas as grades de disciplinas nas universidades... cada professor quer ensinar o que sabe, obviamente. O problema é que isto não é, necessariamente, no melhor interesse do aluno quando se olha para o todo, para o corpo de conhecimento sendo passado. Algumas coisas ficam bem aprofundadas e outras nem são mencioadas.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Por exemplo, sempre achei engraçado como na graduação em Ciência da Computação do DCC/UFRJ temos linguagens de programação nos primeiros períodos sem vermos NADA de banco de dados. Que só é visto na segunda metade do curso, sem nenhuma linguagem de programação acompanhando.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Resultado: ninguém faz um programinha que conecte no banco e faça alguma coisa. Inclusive, toda a persistência de trabalhos de faculdade é feita em arquivos até banco de dados e muitas vezes depois também.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Claro, sempre vale o argumento de que é muito fácil aprender sozinho, etc. Mas isso quando se pensa na conexão em si. Ninguém fala de mecanismos no banco para lidar com concorrência (locks pessimistas/otimistas) nem mapeamento objeto-relacional nem particionamento horizontal/vertical nem nada assim. Pelo menos não nas obrigatórias.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Mas acho que o pior é quando o professor acha que todo mundo tem que saber fazer as coisas na mesma profundidade que ele (por mais específicos que sejam os casos de aplicação real). E passa metade da disciplina em SQL. E os alunos arrancando os cabelos para fazer SQLs de várias linhas para... hmm.. nada útil.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;O fato é que grande parte dos sistemas atualmente são orientados a objetos. A maior parte das queries é simples e as mais complicadas são geradas por algum framework de mapeamento objeto-relacional.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;O pior é que SQLs grandes costumam gerar código "write-once". Aqueles que as pessoas escrevem e torcem pra nunca terem que alterar pois não conseguirão mais entender como aquilo funciona (e por Murphy é justamente alí que vai ter mudança, nem que seja pra jogar aquele trabalhão todo fora).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Por exemplo, uma questão que me lembro quando fiz esta disciplina era gerar uma SQL que desse como resultado as posições de chegada de cavalos na ordem, com seus tempos de chegada após uma corrida. A tabela tinha os cavalos e seus tempos. O "x" da questão era justamente gerar as posições.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Pois bem, apreciem a resposta:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;select count(*) as posicao, c1.nome, c1.tempo from cavalos c1 join cavalos c2 on c1.tempo &amp;gt;= c2.tempo group by c1.nome, c1.tempo order by posicao;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Isto mesmo, um join da tabela com ela mesma onde qualquer um teria feito simplesmente um "&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;SELECT * FROM Cavalos ORDER BY posicao;"&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;e um for que imprime o índice do loop antes de cada linha, para produzir o seguinte efeito:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="color: #444444;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #444444; font-size: small;"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;1&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;FugindoDoJackBauer&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;00:00:01&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;2&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Veloz&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;00:00:25&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;3&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Rápido&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;00:00:35&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;4&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Corredor&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;00:00:40&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;5&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Ligeiro&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;00:00:45&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;6&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Pangaré&lt;/span&gt;&lt;/td&gt;&lt;td style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;00:01:00&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Agora, amigos, imaginem uma aplicação onde se coloca a lógica da aplicação em consultas de várias linhas. Pois é, nem tudo que dá para fazer é para ser feito, né? :-)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Abraço a todos!&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;P.S.: Caso alguém queira testar, be my guest.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;div style="border-collapse: collapse; color: #444444; font-family: verdana, sans-serif; font-size: small;"&gt;
CREATE TABLE cavalos (nome varchar(255), tempo time);&lt;/div&gt;
&lt;div style="border-collapse: collapse; color: #444444; font-family: verdana, sans-serif; font-size: small;"&gt;
INSERT INTO cavalos (nome, tempo) VALUES ('Pangaré', '00:01:00');&lt;/div&gt;
&lt;div style="border-collapse: collapse; color: #444444; font-family: verdana, sans-serif; font-size: small;"&gt;
INSERT INTO cavalos (nome, tempo) VALUES ('Ligeiro', '00:00:45');&lt;/div&gt;
&lt;div style="border-collapse: collapse; color: #444444; font-family: verdana, sans-serif; font-size: small;"&gt;
INSERT INTO cavalos (nome, tempo) VALUES ('Corredor', '00:00:40');&lt;/div&gt;
&lt;div style="border-collapse: collapse; color: #444444; font-family: verdana, sans-serif; font-size: small;"&gt;
INSERT INTO cavalos (nome, tempo) VALUES ('Rápido', '00:00:35');&lt;/div&gt;
&lt;div style="border-collapse: collapse; color: #444444; font-family: verdana, sans-serif; font-size: small;"&gt;
INSERT INTO cavalos (nome, tempo) VALUES ('Veloz', '00:00:25');&lt;/div&gt;
&lt;div style="border-collapse: collapse; color: #444444; font-family: verdana, sans-serif; font-size: small;"&gt;
INSERT INTO cavalos (nome, tempo) VALUES ('FugindoDoJackBauer', '00:00:01');&lt;/div&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-4323152639286485766?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/XzDmTRRe-Mw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/4323152639286485766/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/06/sql-e-para-dados-logica-nao.html#comment-form" title="5 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/4323152639286485766?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/4323152639286485766?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/XzDmTRRe-Mw/sql-e-para-dados-logica-nao.html" title="SQL é para dados, lógica não!" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/06/sql-e-para-dados-logica-nao.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIBQn89cCp7ImA9WxFQF0w.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-8777310664355165586</id><published>2010-05-12T23:09:00.000-03:00</published><updated>2010-05-12T23:09:13.168-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-12T23:09:13.168-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="modelos" /><category scheme="http://www.blogger.com/atom/ns#" term="mps.br" /><title>Workshop de Melhoria de Processos de Software</title><content type="html">Amigos,&lt;br /&gt;
&lt;br /&gt;
Vai acontecer no Rio (ok, é no Fundão, mas vale a pena) um Workshop de Melhoria de Processos de Software.&lt;br /&gt;
Esta é uma iniciativa conjunta da COPPE/UFRJ, RioSoft, Promove e Prime Up.&lt;br /&gt;
Baratinho (Profissionais 50,00 / Estudantes 30,00), vai abordar temas importantes como conceitos, normas e modelos de maturidade de processos de software, indicadores de desempenho sobre o &lt;a href="http://www.softex.br/mpsbr"&gt;MPS.BR&lt;/a&gt;, implementações em empresas, etc.&lt;br /&gt;
Serão 4 palestras proferidas por alguns dos maiores nomes da engenharia de software no país como a professora Ana Regina e o professor Guilherme H. Travassos além de um painél onde representantes de empresas falarão sobre suas experiências em projetos de melhoria de processos que atendem a mais de um modelo/norma simultaneamente.&lt;br /&gt;
&lt;br /&gt;
Acho que vai ser interessantíssimo. Será dia 28 e acho que vale muito a pena para quem tem interesse no tema. Uma ótima oportunidade de aprendizado, troca de idéias e experiências e contatos profissionais.&lt;br /&gt;
&lt;br /&gt;
Este é o site:&amp;nbsp;&lt;a href="http://sites.google.com/site/workshopsmps/"&gt;&lt;b&gt;http://sites.google.com/site/workshopsmps/&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
Tem informações mais detalhadas. Lá vocês também podem se inscrever para receber (via e-mail ou feed) futuras notificações sobre workshops como este.&lt;br /&gt;
Claro, sabendo de algum, eu vou avisar a vocês por aqui também. ;-)&lt;br /&gt;
&lt;br /&gt;
Espero vocês lá!&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-8777310664355165586?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/kOQ4UbEGqMY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/8777310664355165586/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/05/workshop-de-melhoria-de-processos-de.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8777310664355165586?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8777310664355165586?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/kOQ4UbEGqMY/workshop-de-melhoria-de-processos-de.html" title="Workshop de Melhoria de Processos de Software" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/05/workshop-de-melhoria-de-processos-de.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQERXg4fyp7ImA9WxFREEk.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-1218348819852430131</id><published>2010-04-23T12:04:00.002-03:00</published><updated>2010-04-23T13:31:44.637-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-23T13:31:44.637-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="código" /><title>"Testar ou não" não é a questão.</title><content type="html">É até engraçado ouvir de um desenvolvedor iniciante que "está pronto, só falta testar".&lt;br /&gt;
&lt;br /&gt;
As chances de um código não funcionar de primeira para todos os casos previstos é tão grande que ninguém diz uma coisa destas. Se não testou, não está pronto.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Bom, para os que estão pensando em comentar sobre a declaração do Knuth dizendo que só precisa de testes automatizados quando não está desenvolvendo num ambiente familiar, onde ele já sabe o que vai e o que não vai funcionar. E eu repito o que reverberou por aí depois da declaração dele: "-Se você for o Knuth, escreva certo de primeira. Se não for, teste!".&lt;br /&gt;
&lt;br /&gt;
Bom, nem era exatamente sobre isso que eu ia falar, mas antes de começar eu gostaria de dizer que só agora estou percebendo que o título fez uma rima besta. Me desculpem. Agora vai ficar assim mesmo. :-P&lt;br /&gt;
&lt;br /&gt;
Como eu dizia, a questão não é sobre testar ou não. É sobre o que ou como testar.&lt;br /&gt;
&lt;br /&gt;
Vou contar um caso interessante. Imaginem um projeto de alguns anos de desenvolvimento. Bom, no início tem pouco código, pouca funcionalidade e no fim de uma iteração já se põe o analista a testar manualmente. Em 2 dias está tudo testado, os bugs foram reportados, os desenvolvedores corrigiram, tudo foi revisado e o sistema está ok.&lt;br /&gt;
&lt;br /&gt;
Passam-se mais alguns meses (e algumas iterações) e então são 2 dias pra testar, mais alguns pra corrigir, outros para retestar e facilmente já se foi mais de uma semana. E não dá para ser assim. Então o que o gerente esperto diz?&lt;br /&gt;
&lt;br /&gt;
"-Corrijam mais rápido!"&lt;br /&gt;
"-Façam hora extra!"&lt;br /&gt;
&lt;br /&gt;
E alguns meses depois já são duas semanas de testes. As correções se limitam aos bugs impeditivos (se tem outra forma de conseguir a mesma funcionalidade, não se perde tempo corrigindo o bug). A equipe está exausta. E o que o gerente esperto diz?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
"-Corrijam mais rápido!"&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
"-Façam hora extra!"&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
"-COMO ASSIM APARECEU BUG NOVO AO CORRIGIR UM? ASSIM NÃO DÁ, PRESTEM ATENÇÃO!"&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Bom, a situação foi ficando insustentável. Pessoas boas deixaram a equipe, etc...&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
A questão de como testar é simples. &lt;a href="http://pt.wikipedia.org/wiki/Automa%C3%A7%C3%A3o_de_teste"&gt;Testes automatizados&lt;/a&gt;. Há ótimos frameworks de testes automatizados em várias linguagens para facilitar a construção destes. Em segundos ou minutos é possível testar módulos ou sistemas inteiros. Também há testes de carga/performance que sem automatização são impossíveis.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Sugiro escrever testes automatizados em qualquer sistema minimamente sério ou complicado. A &lt;a href="http://pt.wikipedia.org/wiki/Teste_de_software"&gt;área de testes&lt;/a&gt; é muito vasta e há várias classificações e formas de testar. Sugiro ler &lt;a href="http://pt.wikipedia.org/wiki/Teste_de_software"&gt;Teste de Software&lt;/a&gt;&amp;nbsp;como um ponto de partida para se saber o que aprender sobre testes. Um bom profissional na área de desenvolvimento de software deve ter uma boa noção de como ter uma segurança mínima no que foi desenvolvido. E testar é uma ferramenta poderosa para isto.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
É claro que se você faz um teste para ver se o que você fez funciona, o teste não vai dizer se você desenvolveu o produto certo (&lt;a href="http://pt.wikipedia.org/wiki/ISO/IEC_15504#SUP.5_.E2.80.93_Valida.C3.A7.C3.A3o"&gt;validação&lt;/a&gt;), apenas se você desenvolveu certo o produto (&lt;a href="http://pt.wikipedia.org/wiki/ISO/IEC_15504#SUP.4._Verifica.C3.A7.C3.A3o"&gt;verificação&lt;/a&gt;).&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
No entanto, se você já escreve seus testes tendo em vista os requisitos que precisam ser atendidos e depois escreve código que passa nestes testes, como no &lt;a href="http://pt.wikipedia.org/wiki/Test_Driven_Development"&gt;Test Driven Development&lt;/a&gt; (e talvez este seja o link mais importante de todo o post - se você só for ler um e não conhecer este, é este que deve ser lido), você já está num caminho mais maduro de desenvolvimento de código, focado nas necessidades e não na predição de possíveis problemas que mina a qualidade do código e do sistema em geral.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
O que testar já varia em função do sistema que está sendo desenvolvido e do ambiente utilizado para testá-lo. Por exemplo, não faz sentido rodar teste de carga com múltiplos usuários numa administração de sistema web feito para apenas um usuário/administrador.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Da mesma forma, testar código criado automaticamente apenas para dizer que seus testes tem 100% de cobertura diz muito pouco ou nada sobre quão bem seu software está bem testado. Em geral, testar código criado automaticamente é esforço jogado fora. Esforço que o seu cliente está pagando.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Sempre é muito importante ter em mente o custo/benefício de se escrever teste para determinado trecho de código.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Mais para a frente pretendo escrever mais detalhes e dar alguns exemplos, por hoje fica aqui este artigo introdutório apontando apenas alguns links para os inciantes nesta prática se orientarem.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Quem estiver interessado em aprender mais sobre Test Driven Development (TDD) pode se aprofundar um pouco aqui:&amp;nbsp;&lt;a href="http://improveit.com.br/xp/praticas/tdd"&gt;http://improveit.com.br/xp/praticas/tdd&lt;/a&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-1218348819852430131?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/hgw0MVZOPO4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/1218348819852430131/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/04/testar-ou-nao-nao-e-questao.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1218348819852430131?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1218348819852430131?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/hgw0MVZOPO4/testar-ou-nao-nao-e-questao.html" title="&quot;Testar ou não&quot; não é a questão." /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/04/testar-ou-nao-nao-e-questao.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YBR3k5fyp7ImA9WxBWGUw.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-1608804300965612993</id><published>2010-02-11T15:59:00.000-02:00</published><updated>2010-02-11T15:59:16.727-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-11T15:59:16.727-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="OObjetos" /><title>Isto é jeito de tratar seus objetos? -Domain Driven Design</title><content type="html">Engraçado como às vezes é mais fácil fazer o que é mais complicado do que o mais simples. Pelo menos esta é a única razão que eu encontro quando ouço alguém chamar "vidro" de "vrido". Deve ser mais fácil pronunciar "vrido", já que é mais complicado.&lt;br /&gt;
&lt;br /&gt;
Posso não estar fazendo muito sentido pra vocês agora, mas já vão entender o que eu quero dizer.&lt;br /&gt;
&lt;br /&gt;
Contemplem, por um minuto, esta modelagem "esquisitinha". Mais ou menos como um "r" fora do seu devido lugar:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_t0UCMhLP4m0/S1L-HuJZzlI/AAAAAAAAANI/aoURYj0Ksgw/s1600-h/Class+Diagram0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_t0UCMhLP4m0/S1L-HuJZzlI/AAAAAAAAANI/aoURYj0Ksgw/s400/Class+Diagram0.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Não é nada que interfira no funcionamento do sistema ou no entendimento de uma frase. Mas que diabos, estamos fazendo um sistema ou remendando uma colcha?&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;O que é aquele AlunoCurso ali no canto? E se você se depara com uma referência para DisciplinaSalaProfessorAluno depois de encontrar uma referência para DisciplinaSalaProfessor? Porque não tem um DisciplinaSala? ;-)&lt;br /&gt;
&lt;br /&gt;
Um software é feito para resolver um problema de alguém. Este problema, em primeiro lugar, deve ser caracterizado. Parte desta caracterização envolve reconhecer as pessoas envolvidas e as entidades que executam suas ações em uma atividade problemática.&lt;br /&gt;
&lt;br /&gt;
Quando se faz uma análise do problema, é importante analisar aquele problema e não perder tempo renomeando coisas que já existem, que já tem nomes. Muitas vezes as entidades envolvidas carecem de uma definição melhor delimitada ou de um consenso sobre sua responsabilidade e seu comportamento. Neste caso, um glossário ou até uma ontologia pode ajudar a resolver o problema. Pode ser que durante a análise até se descubra que é melhor retirar algumas responsabilidades de algumas entidades para criar uma nova, melhorando a coesão. No entanto, isto é uma questão totalmente de negócio, uma decisão sobre o domínio da aplicação, e quem entende do domínio é quem tem o problema e não quem pegou o bonde andando e ainda quer sentar na janela. ;-)&lt;br /&gt;
&lt;br /&gt;
Vamos dar nomes existentes para aqueles caras do diagrama ali em cima e algumas coisas vão ficar mais claras:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_t0UCMhLP4m0/S1MBXeUqVqI/AAAAAAAAANQ/Y2ooV8svr4s/s1600-h/Class+Diagram1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_t0UCMhLP4m0/S1MBXeUqVqI/AAAAAAAAANQ/Y2ooV8svr4s/s400/Class+Diagram1.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Essa mania de substituir os nomes do domínio por nomes inventados em função dos relacionamentos das entidades, infelizmente, é muito comum. É péssima. Disruptiva. Uma pessoa nova que chega ao sistema demora a entender o que se passa no código. Uma mudança de requisitos, ainda que faça uso de uma matriz de rastreabilidade, apenas vai identificar quais classes serão alteradas. Qual alteração vai em cada uma é um custo. Tem-se que lembrar qual é a responsabilidade daquela classe em função de um nome artificial dado pelo relacionamento dela com as outras que não enfatiza o seu comportamento e a necessidade da sua existência. Não informa o problema que ela resolve. O que ela pode fazer.&lt;br /&gt;
Pior ainda, uma alteração que exija a inclusão de uma classe nova, criando novos relacionamentos, poderá fazer com que nomes deixem de fazer sentido.&lt;br /&gt;
&lt;br /&gt;
Ah, para os que ainda estão com problemas de ver que os diagramas são equivalentes, aqui vai a mesma organização do primeiro no segundo:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_t0UCMhLP4m0/S1MDUHRbc3I/AAAAAAAAANY/CEjim_caJFI/s1600-h/Class+Diagram2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_t0UCMhLP4m0/S1MDUHRbc3I/AAAAAAAAANY/CEjim_caJFI/s400/Class+Diagram2.png" /&gt;&lt;/a&gt;&lt;/div&gt;
OK, parece que eu trapaceei rearrumando o diagrama, mas eu explico. O processo que segui foi listar as classes com os nomes corretos (do segundo diagrama), criar os nomes esquisitos (do primeiro), construir o primeiro diagrama e depois construir o segundo.&lt;br /&gt;
&lt;br /&gt;
A questão é que quando se faz as coisas mais complicadas do que se deveria, muitas vezes o nosso entendimento do problema fica prejudicado e a organização do diagrama acaba podendo refletir isso. Quais são as classes com mais relacionamentos, que parecem ser mais "centrais" no primeiro diagrama? Quais são as classes mais "periféricas", que tem cara de "atributos"? E no segundo? O que você acha que você colocaria no topo do diagrama, para facilitar o entendimento?&lt;br /&gt;
&lt;br /&gt;
Quando se prejudica o entendimento do modelo de domínio, sobre o qual todo o seu software se baseará, se prejudica o entendimento de todo o software.&lt;br /&gt;
&lt;br /&gt;
"O vrido, coloquei encima da táuba pra potreger da agua."&lt;br /&gt;
"Coloquei o vidro em cima da tábua para proteger da água."&lt;br /&gt;
&lt;br /&gt;
Perceberam?&lt;br /&gt;
&lt;br /&gt;
E aí, alguém quer comentar nomes "esquisitos"?&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-1608804300965612993?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/1_lF7iXMDcU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/1608804300965612993/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/02/isto-e-jeito-de-tratar-seus-objetos.html#comment-form" title="1 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1608804300965612993?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/1608804300965612993?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/1_lF7iXMDcU/isto-e-jeito-de-tratar-seus-objetos.html" title="Isto é jeito de tratar seus objetos? -Domain Driven Design" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_t0UCMhLP4m0/S1L-HuJZzlI/AAAAAAAAANI/aoURYj0Ksgw/s72-c/Class+Diagram0.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/02/isto-e-jeito-de-tratar-seus-objetos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4FSXo7eCp7ImA9WxBQF0k.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-889781436346875946</id><published>2010-01-17T13:08:00.000-02:00</published><updated>2010-01-17T13:08:38.400-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-17T13:08:38.400-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="OObjetos" /><title>O mapeamento é objeto-relacional, não é relacional-objeto.</title><content type="html">&lt;br /&gt;
É isso aí, deveria ter uma seta no lugar deste hífen:&lt;br /&gt;
objeto&lt;span style="font-size: large;"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/span&gt;relacional&lt;br /&gt;
&lt;br /&gt;
Infelizmente, as pessoas insistem em chamar certo, mas fazer assim:&lt;br /&gt;
&lt;br /&gt;
relacional&lt;span style="font-size: large;"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/span&gt;objeto&lt;br /&gt;
&lt;br /&gt;
Eu entendo que algumas pessoas trabalharam usando &lt;a href="http://pt.wikipedia.org/wiki/Modelo_de_Entidades_e_Relacionamentos"&gt;MER&lt;/a&gt; e &lt;a href="http://pt.wikipedia.org/wiki/Dfd"&gt;DFD&lt;/a&gt; e &lt;a href="http://pt.wikipedia.org/wiki/Matriz_CRUD"&gt;matriz de interações (matriz CRUD)&lt;/a&gt; durante muitos anos e acham que deviam continuar usando primariamente estas ferramentas no desenvolvimento de sistemas orientados a objetos, muitas vezes em detrimento de outras mais ricas como modelos UML.&lt;br /&gt;
&amp;lt;&lt;i&gt;Este post é longo, mas o final surpreende.&lt;/i&gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt; Não estou defendendo que se use modelos UML, o que estou querendo discutir aqui é a implicação de se usar uma ferramenta na hora errada.&lt;br /&gt;
&lt;br /&gt;
Antes eu gostaria de discutir a questão da diferença entre o modelo orientado a objetos e o modelo relacional.&lt;br /&gt;
&lt;br /&gt;
O modelo relacional se presta a armazenar dados em tabelas, gerando relações. O modelo relacional não trata de comportamento, não trata de entidades do mundo real, não trata de relacionamentos entre estas entidades. Trata de dados em tabelas e relações matemáticas. Daí a necessidade de se fazer um &lt;a href="http://pt.wikipedia.org/wiki/Mapeamento_objeto-relacional"&gt;mapeamento&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Apesar de se falar em entidades e relacionamento num modelo relacional ("Modelo de Entidades e Relacionamentos"), ele trata de tabelas e as relações entre elas. Estas tabelas são tabelas com linhas, chamadas de registros e colunas que contém dados com extremas limitações.&lt;br /&gt;
&lt;br /&gt;
Por exemplo, não se pode associar um registro a vários outros utilizando uma única coluna pois numa coluna só se coloca UM valor.&lt;br /&gt;
&lt;br /&gt;
Logo, se queremos fazer uma associação 1:N ("um para n" ou "um para muitos"):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_t0UCMhLP4m0/S1MNMdwzJ9I/AAAAAAAAANg/sqLlVsJl5f8/s1600-h/1-N.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_t0UCMhLP4m0/S1MNMdwzJ9I/AAAAAAAAANg/sqLlVsJl5f8/s320/1-N.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Para associar um registro Aluno (com um identificador) a outros de outra tabela, por exemplo, Matrícula (supondo que um aluno possa ter uma matrícula para cada curso na mesma instituição), eis a solução:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_t0UCMhLP4m0/S1MOFLo2V8I/AAAAAAAAANw/M2xqnRTtfPk/s1600-h/1-N_exemplo.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_t0UCMhLP4m0/S1MOFLo2V8I/AAAAAAAAANw/M2xqnRTtfPk/s400/1-N_exemplo.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;Neste caso, cada matrícula só pode se relacionar com um aluno. Se fosse possível relacionar uma matrícula com mais de um aluno, ou teríamos vários registros com IDs diferentes e o mesmo número de matrícula, para ter diferentes valores na coluna id_aluno (o que poderia causar várias inconsistências ao alterar uma e esquecer de alterar as outras) ou teríamos que adotar outra solução. Como isto é exatamente o caso de Aluno e Turma, o pior ainda está por vir, o relacionamento n:m ("n para m" ou "muitos para muitos"):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_t0UCMhLP4m0/S1MQhMIVqeI/AAAAAAAAAN4/62YJIkP00bY/s1600-h/n-m.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_t0UCMhLP4m0/S1MQhMIVqeI/AAAAAAAAAN4/62YJIkP00bY/s400/n-m.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Digo "pior" porque esta solução cria uma entidade de relacionamento, uma entidade fraca, que possivelmente não existe no mundo real, mas existe no modelo relacional por uma restrição tecnológica. Os dados ficariam assim armazenados:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_t0UCMhLP4m0/S1MRR2abhhI/AAAAAAAAAOI/hVNVOvaSK4c/s1600-h/n-m_exemplo.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_t0UCMhLP4m0/S1MRR2abhhI/AAAAAAAAAOI/hVNVOvaSK4c/s400/n-m_exemplo.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
 O problema da modelagem relacional é que estas restrições são impostas pela maneira matemática de armazenar e trabalhar com estas informações, através do uso de álgebra relacional.&lt;br /&gt;
&lt;br /&gt;
Como os &lt;a href="http://pt.wikipedia.org/wiki/Sistema_gerenciador_de_banco_de_dados"&gt;sistemas gerenciadores de bancos relacionais&lt;/a&gt; são muito estáveis, bem estabelecidos no mercado, extremamente confiáveis e extremamente rápidos graças ao desenvolvimento da álgebra relacional e anos de otimizações nas implementações, eles se mantém no mercado mesmo quando o sistema é desenvolvido utilizando orientação a objetos.&lt;br /&gt;
&lt;br /&gt;
Acontece que como os objetos não têm estas restrições, o modelo OO é mais simples, mais próximo do real e isto exige que seja feito um mapeamento dos atributos do objeto para as colunas das tabelas.&lt;br /&gt;
Isto seria simples se:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;não houvesse herança, que não tem correspondente no modelo relacional. Existem 3 estratégias principais para se mapear heranças (single table, table per class e joined subclasses). Como o foco aqui não é explicar o &lt;a href="http://pt.wikipedia.org/wiki/Mapeamento_objeto-relacional"&gt;mapeamento O-R&lt;/a&gt;, com estratégias já bem conhecidas, vão ao Google procurar páginas como&amp;nbsp;&lt;a href="http://gustavomaiaaguiar.spaces.live.com/Blog/cns%21F4F5C630410B9865%21794.entry"&gt;esta&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;se não houvesse encapsulamento e níveis de visibilidade diferentes para atributos e classes, pois não há correspondência no modelo relacional.&lt;/li&gt;
&lt;li&gt;se relacionamentos não tivessem "navegabilidade".Ou seja, se Aluno tem um atributo Matrícula mas Matrícula não tem atributo para Aluno, o relacionamento é unidirecional e não tem correspondência no modelo relacional.&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;se não houvesse atributos que na verdade são coleções de outros objetos, pois uma coluna (para aquele atributo) não pode guardar uma quantidade indeterminada de valores. Apenas um. E se for assim nas duas pontas do relacionamento, teremos uma tabela de relacionamento que não representa classe alguma.&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
Felizmente, hoje em dia, é possível fornecer metadados (muitas vezes em XML ou Anotações em Java) para as nossas classes de forma que ferramentas automáticas se encarreguem de construir o banco conforme as nossas instruções nos metadados de forma adequada.&lt;br /&gt;
&lt;br /&gt;
Outra alternativa é construir o banco de forma a comportar as nossas classes manualmente. Como este trabalho é muito custoso, normalmente se faz uso de uma ferramenta.&lt;br /&gt;
&lt;br /&gt;
Quando se faz uso do MER antes de se ter o diagram de classes, o que acontece é que o banco é criado e as classes passam a espelhar o banco. Ou cria-se as classes manualmente, copiando-as do banco, uma classe para cada tabela ou se faz uso de ferramentas automáticas para isto.&lt;br /&gt;
&lt;br /&gt;
Neste momento, perde-se todas as heranças (joined subclasses viram associações simples, table per class aglutina classes abstratas na próxima superclasse concreta e single table junta todas as classes a uma classe só), surgem tabelas que não existem como classes com nomes esquisitos, perde-se a navegabilidade dos relacionamentos (muitas vezes impactando no desempenho geral do sistema e aumentando o acoplamento, criando dependências circulares) e perde-se informação de visibilidade dos atributos que muitas vezes acabam trazendo nomes estranhos e fora do &lt;a href="http://craftnicely.blogspot.com/2009/12/convencoes-de-codificacao.html"&gt;padrão de codificação da linguagem&lt;/a&gt; adotada.&lt;br /&gt;
&lt;br /&gt;
Tem-se um modelo totalmente deformado. A manutenção fica prejudicada, a compreensão do código fica prejudicada, o desempenho fica prejudicado e a própria codificação fica prejudicada, gerando muitas vezes código extra, com verificações, comparações e loops desnecessários.&lt;br /&gt;
&lt;br /&gt;
Claro que já peguei código assim. Mas vou lhes contar a vez mais estarrecedora:&lt;br /&gt;
&lt;br /&gt;
Imaginem a minha surpresa quando encontrei um banco onde todos os relacionamentos 1:n foram promovidos a n:m sob a desculpa de que um dia o relacionamento poderia ter que ser modificado, então já se modificou todos antes, indiscriminadamente. Mais ou menos como se você fosse para a frente de uma garagem de hospital se jogar na frente de uma ambulância em baixa velocidade toda vez que você fosse atravessar uma rua para minimizar o tamanho do possível acidente.&lt;br /&gt;
&lt;br /&gt;
A questão a ambulância não estava em baixa velocidade. Vinha em alta velocidade, com a sirene ligada e um paciente em estado crítico sendo transportado. Não só o modelo tinha cerca de 770 classes como cerca de 425 (mais da metade) eram de relacionamento já que todos os relacionamentos que não eram 1:1 eram n:m. Pra piorar, todo registro de uma tabela de relacionamento entre A e B tinha um número que significava a posição do objeto B no atributo (coleção) em A, para que ficassem na ordem, mesmo que a ordem não importasse para absolutamente nada para a aplicação e para o usuário e sua supressão não fizesse a menor diferença.&lt;br /&gt;
&lt;br /&gt;
Depois de meses de conversa e persuasão, a ordem foi abolida onde não era importante e o mapeamento foi construído de forma a deixar as tabelas de relacionamento transparentes onde fosse possível. Aproximadamente 410 classes de relacionamento foram retiradas do sistema, sobrando algo em torno de 15. Infelizmente esta era só uma das idiossincrasias da modelagem daquele banco.&lt;br /&gt;
&lt;br /&gt;
E você? Tem alguma história semelhante para contar?&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-889781436346875946?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/M5pkgbh1urk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/889781436346875946/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2010/01/o-mapeamento-e-objeto-relacional-nao-e.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/889781436346875946?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/889781436346875946?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/M5pkgbh1urk/o-mapeamento-e-objeto-relacional-nao-e.html" title="O mapeamento é objeto-relacional, não é relacional-objeto." /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_t0UCMhLP4m0/S1MNMdwzJ9I/AAAAAAAAANg/sqLlVsJl5f8/s72-c/1-N.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2010/01/o-mapeamento-e-objeto-relacional-nao-e.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEHRXw4eSp7ImA9WxBSFUU.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-2734434997978124373</id><published>2009-12-23T13:53:00.000-02:00</published><updated>2009-12-23T13:53:54.231-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-23T13:53:54.231-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="código" /><title>Convenções de codificação</title><content type="html">Estudos revelam que apenas 20% a 40% do custo de um software está relacionado com a construção. 60% a 80% com manutenção (Livro "Facts and fallacies of software engineering", Robert L. Glass).&lt;br /&gt;
Isso não significa dizer que manutenção é o mais importante no ciclo de desenvolvimento de software, mas certamente requer uma atenção especial.&lt;br /&gt;
Levando em consideração que também é bastante comum fazer manutenção em código de outra pessoa é importante que a outra pessoa nos deixe um código limpo, claro, fácil de entender e sem armadilhas escondidas.&lt;br /&gt;
&lt;br /&gt;
Assim é muito importante que bons padrões de codificação sejam seguidos. Bons padrões melhoram a legibilidade, deixam claras as intenções do autor do código e expõem erros, facilitando não só para quem faz a manutenção mas para quem escreve o código.&lt;br /&gt;
&lt;br /&gt;
Infelizmente muita gente não dá a devida importância ao tópico porque é bastante comum que outra pessoa dê manutenção no código no final das contas. O grande problema é que alguns de vocês leitores precisam escrever um código bom para que outros de vocês sejam capazes de entender, corrigir e mudar. Além disso, você se pergunta em que condições você está entregando o produto do seu trabalho? Você se pergunta o qual o valor do que você está entregando para o seu empregador?&lt;br /&gt;
&lt;br /&gt;
Agora estou escrevendo este post no Blog. E simplesmente não dá para diferenciar os que estão dando manutenção no código de outra pessoa dos que estão escrevendo código para outra manter. E isso se dá pelo simples fato de que todos nós trocamos os chapéus vez ou outra. Então melhor do que torcer para que o seu próximo código a ser mantido tenha sido bem escrito é escrever o seu código atual bem. Se o seu amigo estiver fazendo o mesmo, você terá um bom código para manter e ele também.&lt;br /&gt;
&lt;br /&gt;
Eu já escrevi &lt;a href="http://craftnicely.blogspot.com/2009/09/voce-comenta-seu-codigo.html"&gt;anteriormente&lt;/a&gt; sobre qualidade de código mas desta vez me refiro a padrões. Padrões como http://java.sun.com/docs/codeconv/ e outros podem ser encontrados pelo Google. O padrão definido na linguagem Java tem sido largamente aceito inclusive por comunidades de outras linguagens de programação por ser bastante geral, simples e manter o código limpo.&lt;br /&gt;
&lt;br /&gt;
Para quem acha que estou exagerando na importância do tópico vale lembrar que o padrão ajuda outros desenvolvedores a entenderem o código por já estarem familiarizados com o padrão. Um padrão ajuda em tarefas de automação como contagem de linhas de código (não estou defendendo esta medida, apenas citando) e revisões por pares frequentemente envolvem leitura de código.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Veja o trecho de código abaixo com uma identação adequada e sem uma identação adequada:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //RUIM&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((condition1 &amp;amp;&amp;amp; condition2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; || (condition3 &amp;amp;&amp;amp; condition4)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ||!(condition5 &amp;amp;&amp;amp; condition6)) { //QUEBRA RUIM&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; doSomethingAboutIt();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //FÁCIL DE PERDER ESTA LINHA&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //BEM MELHOR&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((condition1 &amp;amp;&amp;amp; condition2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; || (condition3 &amp;amp;&amp;amp; condition4)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ||!(condition5 &amp;amp;&amp;amp; condition6)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; doSomethingAboutIt();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //TAMBÉM SERVE&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((condition1 &amp;amp;&amp;amp; condition2) || (condition3 &amp;amp;&amp;amp; condition4)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ||!(condition5 &amp;amp;&amp;amp; condition6)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; doSomethingAboutIt();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/code&gt; &lt;br /&gt;
&lt;br /&gt;
Exemplo retirado do padrão Java, onde se lê "Line wrapping for if statements should generally use the 8-space rule,
since conventional (4 space) indentation makes seeing the body
difficult."&lt;br /&gt;
&lt;br /&gt;
E o principal é &lt;b&gt;fazer com que o que esteja errado pareça estar errado.&lt;/b&gt; Às vezes encontramos um bug num trecho inocente:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (condicao)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fazerAlgo();&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
E descobrimos que o autor esqueceu de fazerAlgoAntes();. Assim, vamos corrigir:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (condicao)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fazerAlgoAntes(); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fazerAlgo();&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
E pronto, lá está o fazerAlgo(); fora do if simplesmente porque o desenvolvedor não abriu um bloco no if:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (condicao) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fazerAlgo();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
E não é importante? Quem quer criar um bug novo ao consertar outro? Ou pior, quando você achou que era só "fazerAlgoAntes();" e não percebeu que quebrou o "fazerAlgo();" vai ficar se perguntando porque não funcionou, se não era só isso, como uma coisa fez a outra quebrar, etc...&lt;br /&gt;
&lt;br /&gt;
Viu a diferença que um bloco no if pode fazer?&lt;br /&gt;
&lt;br /&gt;
Não fique parado! Aprenda o padrão da sua linguagem mais utilizada/preferida! :-)&lt;br /&gt;
&lt;br /&gt;
E se você tem algum caso de bug causado por código mal formatado, comente!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-2734434997978124373?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/EXgECaMKzC4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/2734434997978124373/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/12/convencoes-de-codificacao.html#comment-form" title="1 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/2734434997978124373?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/2734434997978124373?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/EXgECaMKzC4/convencoes-de-codificacao.html" title="Convenções de codificação" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/12/convencoes-de-codificacao.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMGSX0-fSp7ImA9WxBTEk0.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-8633115713947765787</id><published>2009-12-07T15:37:00.000-02:00</published><updated>2009-12-07T15:37:08.355-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-07T15:37:08.355-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DPatterns" /><category scheme="http://www.blogger.com/atom/ns#" term="OObjetos" /><title>Interfaces e comportamento aumentando a coesão e reduzindo o acoplamento</title><content type="html">Você já encontrou uma pessoa famosa na rua executando tarefas cotidianas? Eu já. Encontrei, há muitos anos, o &lt;a href="http://pt.wikipedia.org/wiki/Francisco_Cuoco"&gt;Francisco Cuoco&lt;/a&gt; alugando um filme numa &lt;a href="http://www.blockbusteronline.com.br/"&gt;Blockbuster&lt;/a&gt; em Ipanema. Também numa ida ao &lt;a href="http://www.guiadasemana.com.br/Rio_de_Janeiro/Gastronomia/Estabelecimento/Tanaka_San.aspx?id=5000"&gt;Tanaka San da Lagoa&lt;/a&gt; encontrei, jantando, &lt;a href="http://pt.wikipedia.org/wiki/Helena_Ranaldi"&gt;Helena Ranaldi&lt;/a&gt;, &lt;a href="http://pt.wikipedia.org/wiki/Malu_Mader"&gt;Malu Mader&lt;/a&gt; e outros.&lt;br /&gt;
&lt;br /&gt;
Como todas as outras pessoas, estas também implementam interfaces. E estas implementam interfaces públicas! ;-)&lt;br /&gt;
&lt;br /&gt;
Elas comem como todo mundo, assistem filmes, fazem tudo o que nós fazemos. E atuam. Quando estão atuando, estão no ambiente de trabalho. Lá, diferente da vida pessoal, eles são obrigados a obedecer certas regras, assim como o resto de nós.&lt;br /&gt;
&lt;br /&gt;
Ninguém vai trabalhar de pijamas, apesar de ser compreensível que, no mesmo horário, no conforto do seu lar, alguém pudesse estar de pijamas.&lt;br /&gt;
&lt;br /&gt;
Isto porque no trabalho precisamos apresentar uma outra interface, com outro comportamento. Este comportamento é definido por um conjunto coeso de tarefas que podemos executar. Estas tarefas são executadas de uma determinada forma, seguindo determinados passos que compõem nosso método de executá-las.&lt;br /&gt;
&lt;br /&gt;
Assim é com as classes. Ao definir métodos públicos para uma classe, estamos definindo uma interface para ela. Esta interface exibe um comportamento que poderá ser exigido dela através da execução destes métodos.&lt;br /&gt;
&lt;br /&gt;
Se a sua classe implementa mais de uma interface, ela exibe mais de um comportamento. O mecanismo de interfaces presente em muitas linguagens é geralmente usado para simular uma herança múltipla, muitas vezes ausente, pois as interfaces podem ser usados como tipos quando o comportamento que será exigido de um objeto está inteiramente contido nela (e é o mais recomendável pois deixa o código mais flexível e reutilizável).&lt;br /&gt;
&lt;br /&gt;
No entanto, o significado de implementar uma interface é dizer que um determinado comportamento é atendido e criar uma interface não só mostra isso com mais clareza mas também agrupa os métodos de forma mais coesa e dá uma flexibilidade maior ao sistema permitindo que classes em outra hierarquia também possam implementar o mesmo comportamento.&lt;br /&gt;
&lt;br /&gt;
Este é o ponto de vista interno, do desenho da classe.&lt;br /&gt;
 &lt;br /&gt;
Do ponto de vista das classes clientes, ou seja, das classes que irão exigir o comportamento chamando os métodos, utilizar através de uma interface significa não estar preso a uma implementação específica, que pode inclusive ser trocada em tempo de compilação ou de execução, reduzindo drasticamente o acoplamento.&lt;br /&gt;
&lt;br /&gt;
Em tempo de compilação esta flexibilidade permite que os métodos possam ser chamados de classes diferentes e cada classe poderá realizar diferentes ações. Esta flexibilidade é usada em muitos frameworks para isolar a implementação real da funcionalidade sendo disponibilizada, permitindo que os desenvolvedores possam evoluir o framework sem impactar na API externa.&lt;br /&gt;
&lt;br /&gt;
Em tempo de execução esta flexibilidade permite que um método seja chamado de instâncias de diferentes classes, por exemplo, para notificar o acontecimento de um evento. A partir daí, cada instância fará o que foi programada para fazer no acontecimento daquele evento. Assim, uma coleção de instâncias de diferentes classes observadoras pode ser notificada quando um evento observável ocorrer em uma instância de outra.&lt;br /&gt;
Este é o padrão de projetos &lt;a href="http://www.universia.com.br/MIT/6/6.170/pdf/6.170_lecture-13.pdf"&gt;Observer&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Ainda não sei se vou explicar padrões de projeto aqui. Tem muita informação disponível a respeito já, basta googlar. O que acham?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bom, vão as dicas:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Depois de identificadas as entidades do sistema, verifique comportamentos em comum que serão exigidos pelas funcionalidades já requisitadas e os defina em termos de interfaces. Isto permitirá a reutilização de funcionalidades já construídas para diferentes hierarquias, reduzindo tempo e custo de desenvolvimento e manutenção.&lt;br /&gt;
&lt;br /&gt;
- Procure identificar funcionalidades que tratam classes de hierarquias
diferentes de forma semelhante no seu sistema e verifique se uma
interface não poderia eliminar a redundância. &lt;br /&gt;
&lt;br /&gt;
Você cria interfaces no seu sistema?&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-8633115713947765787?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/zMaxq9Dh4wI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/8633115713947765787/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/12/interfaces-e-comportamento-aumentando.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8633115713947765787?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8633115713947765787?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/zMaxq9Dh4wI/interfaces-e-comportamento-aumentando.html" title="Interfaces e comportamento aumentando a coesão e reduzindo o acoplamento" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/12/interfaces-e-comportamento-aumentando.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08FQXc-eCp7ImA9WxNaEUQ.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-6078092474034524929</id><published>2009-11-25T23:43:00.000-02:00</published><updated>2009-11-25T23:43:30.950-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-25T23:43:30.950-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="modelos" /><category scheme="http://www.blogger.com/atom/ns#" term="metodologias" /><category scheme="http://www.blogger.com/atom/ns#" term="cmmi" /><category scheme="http://www.blogger.com/atom/ns#" term="processos" /><title>O CMMI e os processos de software</title><content type="html">O &lt;a href="http://www.sei.cmu.edu/cmmi"&gt;CMMI&lt;/a&gt; (Capability Maturity Model Integration) é, como o nome diz, um modelo de capacidade e maturidade. É um modelo de referência para a melhoria dos processos relacionados ao ciclo de desenvolvimento de software em organizações que desempenham esta atividade.&lt;br /&gt;
&lt;br /&gt;
A melhor explicação que já ouvi até agora sobre capacidade e maturidade me foi contada pela professora &lt;a href="http://buscatextual.cnpq.br/buscatextual/visualizacv.jsp?id=K4783126J8"&gt;Ana Regina C. da Rocha&lt;/a&gt;, verdadeira autoridade na área. Ela diz que uma criança adquire a capacidade de escrever ainda cedo, mas escreve de uma forma quando aprende, outra quando é adolescente, outra quando é adulta e outra no fim de uma carreira literária. O que muda é a sua maturidade.&lt;br /&gt;
&lt;br /&gt;
Assim também, organizações adquirem a capacidade de fazer software de acordo com determinados processos e a cada ciclo de melhoria, deveria melhorar também a maturidade do que já era feito.&lt;br /&gt;
&lt;br /&gt;
O CMMI organiza os processos de software em 5 níveis. Cada nível introduz novos processos e aumenta a exigência sobre os que já haviam sido introduzidos, obrigando a organização a aumentar sua maturidade.&lt;br /&gt;
&lt;br /&gt;
A cada nível é possível fazer uma avaliação, onde pessoas credenciadas ao Software Engineering Institute, da Carnegie Mellon University atestam que a organização implementa os processos daquele nível de forma suficiente para as exigências do modelo.&lt;br /&gt;
&lt;br /&gt;
Estes processos não foram tirados do bolso, obviamente. Foi muita pesquisa até se chegar na norma internacional &lt;a href="http://www.iso.org/iso/catalogue_detail.htm?csnumber=43447"&gt;ISO/IEC 12207&lt;/a&gt; na qual o CMMI se baseou. Também se baseou na &lt;a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=38932"&gt;ISO/IEC 15504&lt;/a&gt; para seu processo de avaliação.&lt;br /&gt;
&lt;br /&gt;
Este modelo é considerado de difícil implantação nas pequenas empresas brasileiras, com avaliações caras. Mas temos o &lt;a href="http://www.softex.br/mpsbr"&gt;MPS.BR&lt;/a&gt;, totalmente compatível, com implementação facilitada para pequenas empresas e custos muito mais baixos. Falo dele num próximo post.&lt;br /&gt;
&lt;br /&gt;
Os processos de cada nível são:&lt;br /&gt;
Nível 1: Ad hoc - Não há processos e atividades definidas. As pessoas trabalham de forma reativa, sem muito planejamento na maior parte das vezes.&lt;br /&gt;
&lt;br /&gt;
Nível 2: Gerenciado - Processos de gerência, requisitos, medição e análise e outros necessários para um funcionamento controlado.&lt;br /&gt;
CM – Gerência de configuração&lt;br /&gt;
MA – Medição e análise&lt;br /&gt;
PP – Planejamento de projetos&lt;br /&gt;
PMC – &lt;span id="goog_1255141087521"&gt;&lt;/span&gt;Acompanhamento de projetos&lt;span id="goog_1255141087522"&gt;&lt;/span&gt;&lt;br /&gt;
PPQA – Garantia de qualidade do processo e produto&lt;br /&gt;
REQM – Gerência de requisitos&lt;br /&gt;
SAM – Gerência de acordos com fornecedores&lt;br /&gt;
&lt;br /&gt;
Nível 3: Definido - Os processos, ferramentas e métodos são definidos a nível organizacional e padronizados em todos os projetos.&lt;br /&gt;
PI – Integração do produto&lt;br /&gt;
RD – Desenvolvimento de requisitos&lt;br /&gt;
TS – Solução técnica&lt;br /&gt;
VAL - Validação&lt;br /&gt;
VER – Verificação&lt;br /&gt;
OPD – Definição do processo organizacional&lt;br /&gt;
OPF – Foco no processo organizacional&lt;br /&gt;
OT – Treinamento organizacional&lt;br /&gt;
IPM – Gerência integrada de projetos&lt;br /&gt;
DAR – Análise de decisão e resolução&lt;br /&gt;
RSKM – Gerência de riscos&lt;br /&gt;
&lt;br /&gt;
Nível 4: Gerenciado quantitativamente - Os processos são medidos e gerenciados através de ferramentas estatísticas. Considerado como de alta maturidade. Em geral, após um grande esforço de implementação do nível 3, este nível dificilmente é avaliado. Por só ter dois processos, as empresas costumam implementar este junto com o 5 e fazer uma avaliação só.&lt;br /&gt;
QPM – Gerência quantitativa de projetos&lt;br /&gt;
OPP – Desempenho do processo organizacional&lt;br /&gt;
&lt;br /&gt;
Nível 5: Em otimização - Melhoria contínua implementada com uso do ferramental estatístico e dados coletados a partir de processos estabilizados graças a maturidade obtida pela implantação dos processos dos níveis anteriores.&lt;br /&gt;
CAR - Análise de causa e resolução&lt;br /&gt;
OID - Inovação organizacional e implantação&lt;br /&gt;
&lt;br /&gt;
O CMMI também permite que uma empresa escolha quais processos quer avaliar por achar mais relevantes na sua situação e quais níveis de cada processo serão avaliados (como expliquei, os processos do nível 2 devem ser mais maduros no 3 do que eram no 2). Este tipo de avaliação é chamada de "contínua" em oposição à avaliação "em estágios". Como a avaliação contínua não dá um nível que a empresa possa estampar no seu material de divulgação, acaba sendo preterida à outra.&lt;br /&gt;
&lt;br /&gt;
No futuro, pretendo falar a respeito de cada um destes processos ou até pedir a especialistas na área que escrevam algo para eu postar aqui. Tenho certeza que será bastante interessante.&lt;br /&gt;
&lt;br /&gt;
Só a título de curiosidade, o MPS.Br facilita as coisas tendo mais níveis com menos processos em cada um, trazendo um retorno de investimento mais cedo. Os níveis G e F do MPS.Br correspondem ao 2 do CMMI. Os níveis C, D e E ao nível 3. O nível B ao 4 e o A ao 5. Outra facilidade também é a presença de avaliadores e implementadores em quase todos os estados e nas principais cidades brasileiras, tornando a implementação e a avaliação mais baratas, além de fontes de subsídio para que as organizações implementem suas melhorias. Mas o MPS.Br fica pra outro post. Merece um só para ele.&lt;br /&gt;
&lt;br /&gt;
Links do CMMI:&lt;br /&gt;
&lt;a href="http://www.blogcmmi.com.br/"&gt;http://www.blogcmmi.com.br/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://pt.wikipedia.org/wiki/Cmmi"&gt;http://pt.wikipedia.org/wiki/Cmmi&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.sei.cmu.edu/cmmi"&gt;http://www.sei.cmu.edu/cmmi&lt;/a&gt; (Oficial)&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/CMMI"&gt;http://en.wikipedia.org/wiki/CMMI&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-6078092474034524929?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/9VYCJ4UG3nU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/6078092474034524929/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/11/o-cmmi-e-os-processos-de-software.html#comment-form" title="1 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/6078092474034524929?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/6078092474034524929?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/9VYCJ4UG3nU/o-cmmi-e-os-processos-de-software.html" title="O CMMI e os processos de software" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/11/o-cmmi-e-os-processos-de-software.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QBQH09eSp7ImA9WxNVGEk.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-5719406819036305085</id><published>2009-10-29T18:49:00.000-02:00</published><updated>2009-10-29T18:49:11.361-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-29T18:49:11.361-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="código" /><title>Otimização e desempenho</title><content type="html">Como eu já disse anteriormente, sou monitor da disciplina "Computação 2" (Orientação a Objetos com Java) na graduação em Ciência da Computação da UFRJ.&lt;br /&gt;
&lt;br /&gt;
Uma pergunta bastante recorrente ao longo dos períodos tem sido "Como é mais rápido?" geralmente acompanhada de "O que consome mais memória?".&lt;br /&gt;
&lt;br /&gt;
Estas perguntas podem ser facilmente respondidas em Java com &lt;code&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/System.html#nanoTime%28%29"&gt;System.nanoTime()&lt;/a&gt;&lt;/code&gt; e &lt;code&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/System.html#currentTimeMillis%28%29"&gt;System.currentTimeMillis()&lt;/a&gt;&lt;/code&gt; para a velocidade e &lt;a href="http://java-source.net/open-source/profilers"&gt;ferramentas de profiling&lt;/a&gt; para a memória e outras informações. Embora isto responda a pergunta, ataca um sintoma e não a raiz do problema:&lt;br /&gt;
&lt;br /&gt;
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." - &lt;a href="http://pt.wikipedia.org/wiki/Knuth"&gt;Donald Knuth&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
O mal ("evil") a que ele se refere é consequência de algo bem explicado por outro grande autor:&lt;br /&gt;
&lt;br /&gt;
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - &lt;a href="http://pt.wikipedia.org/wiki/C.A.R._Hoare"&gt;C. A. R. Hoare&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Quem já percebeu a relação entre estas duas frases, já sabe onde eu vou chegar. A questão é que muitos tendem a se preocupar primariamente com otimização e deixam a legibilidade do código em segundo plano.&lt;br /&gt;
Ao fazer isso, o código pode ficar otimizado onde não precisa, prejudicando a legibilidade sem trazer ganho real.&lt;br /&gt;
&lt;br /&gt;
Em via de regra, seu foco deve ser fazer um código legível. O máximo
possível. SE vc tiver problema de desempenho (o que você só sabe depois
que rodar com a carga esperada de usuários e objetos criados
simultaneamente) é que você deve alterar o código de forma a ganhar
desempenho prejudicando a legibilidade o mínimo possível, até atingir o
desempenho desejado.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”-&lt;a href="http://pt.wikipedia.org/wiki/Martin_Fowler"&gt;Martin Fowler&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
Já falei de legibilidade aqui antes: &lt;a href="http://craftnicely.blogspot.com/2009/09/voce-comenta-seu-codigo.html"&gt;"Você comenta seu código?"&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
A grande questão é que você não trabalha sozinho. Cedo ou tarde alguém vai por a mão no seu código, assim como você vai mudar algo que alguém fez. E ainda que você esteja começando a desenvolver agora e esteja só fazendo pequenos exercícios, é de cedo que se deve treinar bons hábitos.&lt;br /&gt;
É importante que você deixe tudo muito bem claro para o seu colega, assim como ele deve deixar tudo claro para você. É mais um fator que pode contribuir para que você tenha no seu currículo um projeto de sucesso, um reconhecimento no ambiente de trabalho e consequentemente uma boa carreira profissional.&lt;br /&gt;
Mesmo que seja um projeto seu, particular, você mesmo pode querer mudá-lo alguns meses depois de começado.&lt;br /&gt;
Clareza é fundamental e deve vir em primeiro lugar, principalmente porque quando se escreve código, não se sabe, a priori, o que será suficientemente rápido ou precisará de otimização.&lt;br /&gt;
&lt;br /&gt;
Isto só se descobre quando a funcionalidade foi implementada, para que possa passar por &lt;a href="http://en.wikipedia.org/wiki/Load_test"&gt;teste de carga (também conhecido como teste de estresse ou de performance)&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Testes de carga são aqueles em que o sistema é forçado a executar em condições acima do projetado, para ver como se comporta. Por exemplo, se a sua previsão é para 50 usuários simultâneos, teste com 200, para ver como o sistema reagiria num caso de pico de utilização. &lt;br /&gt;
&lt;br /&gt;
Estes testes são feitos geralmente através de ferramentas automatizadas que simulam execuções por usuários virtuais extremamente leves (para que uma máquina sozinha possa simular muitos). Uma ferramenta para Java free e muito popular é o &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt; e há outras para outras linguagens, inclusive algumas independentes de linguagem, já que basta simular um "agente" (termo que usam para um usuário ou sistema externo).&lt;br /&gt;
&lt;br /&gt;
Estes testes, associados a ferramentas de profiling já mencionadas anteriormente fornecem informações sobre quais são os métodos mais lentos, que consomem mais memória, que executam maior quantidade de vezes, etc.&lt;br /&gt;
&lt;br /&gt;
É só a partir destas informações que se pode detectar onde as otimizações devem ser feitas CASO precisem ser feitas. E mesmo assim, o código deve ser modificado para a otimização que menos prejudica a legibilidade e a portabilidade. Depois de um novo teste é que se decide se foi suficiente ou se mais alguma ação deve ser tomada.&lt;br /&gt;
&lt;br /&gt;
Um ótimo exemplo de otimização sem perda de legibilidade está no &lt;a href="http://www.zimbrao.com/"&gt;Blog C++ do Zimbrão&lt;/a&gt;. &lt;a href="http://www.zimbrao.com/cpp/?p=262"&gt;Este é sobre Java&lt;/a&gt; e este sobre &lt;a href="http://www.zimbrao.com/cpp/?p=191"&gt;C++&lt;/a&gt;, lembrando que otimizações que realmente funcionam variam de linguagem para linguagem e de compilador para compilador em uma mesma linguagem. O post de &lt;a href="http://www.zimbrao.com/cpp/?p=191"&gt;otimizações em C++&lt;/a&gt; é muito elucidativo a este respeito.&lt;br /&gt;
&lt;br /&gt;
Além disso, deve-se lembrar neste momento que há diversos mecanismos para melhorar a performance como clusters de aplicações (felizmente para quem trabalha com JEE, isto vem &lt;a href="http://www.jboss.org/community/wiki/JBossFarmDeployment"&gt;de graça&lt;/a&gt;), configurações de datasource, pool de conexões com banco, cache de banco que não mudam a aplicação em si, caso tenha sido desenvolvida corretamente, isolada de acoplamentos com outros sistemas, como o sistema gerenciador de banco de dados ou o servidor onde será executada.&lt;br /&gt;
&lt;br /&gt;
Vou só lembrar ainda que é importante também seguir as &lt;a href="http://java.sun.com/docs/codeconv/"&gt;convenções de codificação&lt;/a&gt; da sua organização. Mas este é assunto para outro post. ;-)&lt;br /&gt;
&lt;br /&gt;
P.S.: Pra quem gostou dos quotes, aqui tem mais: http://en.wikipedia.org/wiki/Program_optimization#Quotes&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-5719406819036305085?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/21_P_j4TPpM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/5719406819036305085/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/10/otimizacao-e-desempenho.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/5719406819036305085?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/5719406819036305085?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/21_P_j4TPpM/otimizacao-e-desempenho.html" title="Otimização e desempenho" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/10/otimizacao-e-desempenho.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IDRn07fyp7ImA9WxNaFEU.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-4742161016002790163</id><published>2009-10-10T00:59:00.007-03:00</published><updated>2009-11-29T08:12:57.307-02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-29T08:12:57.307-02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="código" /><category scheme="http://www.blogger.com/atom/ns#" term="OObjetos" /><title>Exceções são como são</title><content type="html">O mecanismo de exceções comum em linguagens OO modernas como Java, C# e outras é talvez um dos mais incompreendidos.&lt;br /&gt;
Tamanho é o incômodo que traz aos desenvolvedores que em C# nenhuma exceção precisa obrigatoriamente ser tratada e frameworks são escritos para lidar com exceções de forma mais "transparente" possível.&lt;br /&gt;
Por transparente entende-se muitas vezes "não tratá-las" ou jogá-las a um limbo onde todas são "tratadas" da mesma forma (que geralmente é o mesmo que não tratar).&lt;br /&gt;
Mas se o desenvolvedor já ia ignorá-la de qualquer forma (deixando o bloco de captura em branco ou simplesmente imprimindo o trace na console onde nunca será lido), que diferença faz?&lt;br /&gt;
&lt;br /&gt;
Exceções são como são para que possamos tratá-las onde soubermos como fazê-lo. É por isso que nos é dada a opção de relançar ou tratar.&lt;br /&gt;
&lt;br /&gt;
É comum, entre as pessoas que estão aprendendo sobre este mecanismo a dúvida sobre o que fazer em que situação ou "onde tratar".&lt;br /&gt;
&lt;br /&gt;
Tipicamente em um sistema OO, o usuário realiza uma ação que dispara um método &lt;code&gt;buttonSaveAction()&lt;/code&gt; que chama um &lt;code&gt;saveUserData()&lt;/code&gt;, depois um &lt;code&gt;writeFormattedContentFile()&lt;/code&gt; e assim por diante, até que chegamos naquele método &lt;code&gt;saveFile()&lt;/code&gt; que grava o conteúdo que o usuário forneceu a um determinado arquivo que o usuário indicou.&lt;br /&gt;
&lt;br /&gt;
E aí entra o problema: o arquivo não existe no local indicado.&lt;br /&gt;
&lt;br /&gt;
Há então algumas opções:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Tratamento em branco / imprimir um erro na console:&lt;/li&gt;
Embora seja muito fácil e muito comum, o usuário nunca saberá o que aconteceu. Claro, um erro na console é bom, se estamos olhando para a console. No caso de uma aplicação com interface gráfica ou rodando em um servidor, este erro passará despercebido. Em uma aplicação de linha de comando os desenvolvedores saberão o que aconteceu, mas o usuário nunca saberá o que o atingiu. Bastante desagradável.
&lt;li&gt;Registrar o ocorrido:&lt;br /&gt;
Registre se precisar corrigi-lo posteriormente, mas o faça em um arquivo ao menos, para que as informações fiquem a salvo. E com informação que você julgue suficiente para corrigir. Infelizmente esta opção não ajuda nosso usuário, mas pelo menos ele não recebeu um golpe certeiro de um desenvolvedor descuidado, como um stack trace. Stack Trace real (4.40Mb, quase 46 MIL linhas - 45750 suprimidas - quem quiser ver tudo, me mande um e-mail):&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;textarea cols="80" rows="5"&gt;01:20:48,359 INFO  [Server] Starting JBoss (MX MicroKernel)...
01:20:48,359 INFO  [Server] Release ID: JBoss [Trinity] 4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)
01:20:48,359 INFO  [Server] Home Dir: C:\jboss-4.2.2.GA
01:20:48,359 INFO  [Server] Home URL: file:/C:/jboss-4.2.2.GA/
01:20:48,359 INFO  [Server] Patch URL: null
01:20:48,359 INFO  [Server] Server Name: default
01:20:48,359 INFO  [Server] Server Home Dir: C:\jboss-4.2.2.GA\server\default
01:20:48,359 INFO  [Server] Server Home URL: file:/C:/jboss-4.2.2.GA/server/default/
01:20:48,359 INFO  [Server] Server Log Dir: C:\jboss-4.2.2.GA\server\default\log
01:20:48,359 INFO  [Server] Server Temp Dir: C:\jboss-4.2.2.GA\server\default\tmp
01:20:48,359 INFO  [Server] Root Deployment Filename: jboss-service.xml
01:20:48,953 INFO  [ServerInfo] Java version: 1.5.0_14,Sun Microsystems Inc.
01:20:48,953 INFO  [ServerInfo] Java VM: Java HotSpot(TM) Client VM 1.5.0_14-b03,Sun Microsystems Inc.
01:20:48,953 INFO  [ServerInfo] OS-System: Windows XP 5.1,x86
01:20:52,671 INFO  [Server] Core system initialized
01:20:56,546 INFO  [WebService] Using RMI server codebase: http://127.0.0.1:8083/
01:20:56,546 INFO  [Log4jService$URLWatchTimerTask] Configuring from URL: resource:jboss-log4j.xml
01:21:26,296 WARN  [TransactionManagerService] XAExceptionFormatters are not supported by the JBossTS Transaction Service - this warning can safely be ignored
01:21:40,875 WARN  [ConfigurationFactory] No configuration found. Configuring ehcache from ehcache-failsafe.xml  found in the classpath: jar:file:/C:/jboss-4.2.2.GA/server/default/tmp/deploy/tmp55870XXX.ear-contents/SS_2007_048_XXXEJB.jar-contents/lib/ehcache-1.4.1.jar!/ehcache-failsafe.xml
01:21:42,078 ERROR [STDERR] javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.LocalOnlyContextFactory [Root exception is java.lang.ClassNotFoundException: No ClassLoaders found for: org.jnp.interfaces.LocalOnlyContextFactory]
01:21:42,078 ERROR [STDERR]  at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
01:21:42,078 ERROR [STDERR]  at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
01:21:42,078 ERROR [STDERR]  at javax.naming.InitialContext.init(Unknown Source)
01:21:42,078 ERROR [STDERR]  at javax.naming.InitialContext.&amp;lt;init&amp;gt;
(Unknown Source)
(01:21:42,078) ERROR [STDERR]  at SUPRIMIDO - ESPECÍFICO DA APLICAÇÃO
(01:21:42,078) ERROR [STDERR]  at SUPRIMIDO - ESPECÍFICO DA APLICAÇÃO
(01:21:42,078) ERROR [STDERR]  at SUPRIMIDO - ESPECÍFICO DA APLICAÇÃO
(01:21:42,078) ERROR [STDERR]  at SUPRIMIDO - ESPECÍFICO DA APLICAÇÃO
(01:21:42,078) ERROR [STDERR]  at SUPRIMIDO - ESPECÍFICO DA APLICAÇÃO
01:21:42,093 ERROR [STDERR]  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
01:21:42,093 ERROR [STDERR]  at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
01:21:42,093 ERROR [STDERR]  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
01:21:42,093 ERROR [STDERR]  at java.lang.reflect.Constructor.newInstance(Unknown Source)
01:21:42,093 ERROR [STDERR]  at org.hibernate.engine.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:22)
01:21:42,093 ERROR [STDERR]  at org.hibernate.engine.UnsavedValueFactory.getUnsavedIdentifierValue(UnsavedValueFactory.java:44)
01:21:42,093 ERROR [STDERR]  at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:44)
01:21:42,093 ERROR [STDERR]  at org.hibernate.tuple.entity.EntityMetamodel.&amp;lt;init&amp;gt;
(EntityMetamodel.java:123)
01:21:42,093 ERROR [STDERR]  at org.hibernate.persister.entity.AbstractEntityPersister.&amp;lt;init&amp;gt;
(AbstractEntityPersister.java:434)
01:21:42,093 ERROR [STDERR]  at org.hibernate.persister.entity.JoinedSubclassEntityPersister.&amp;lt;init&amp;gt;
(JoinedSubclassEntityPersister.java:91)
01:21:42,093 ERROR [STDERR]  at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:58)
01:21:42,093 ERROR [STDERR]  at org.hibernate.impl.SessionFactoryImpl.&amp;lt;init&amp;gt;
(SessionFactoryImpl.java:226)
01:21:42,093 ERROR [STDERR]  at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
01:21:42,093 ERROR [STDERR]  at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
01:21:42,093 ERROR [STDERR]  at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:730)
01:21:42,093 ERROR [STDERR]  at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:127)
01:21:42,093 ERROR [STDERR]  at org.jboss.ejb3.entity.PersistenceUnitDeployment.start(PersistenceUnitDeployment.java:246)
01:21:42,093 ERROR [STDERR]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
01:21:42,093 ERROR [STDERR]  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
01:21:42,093 ERROR [STDERR]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
01:21:42,093 ERROR [STDERR]  at java.lang.reflect.Method.invoke(Unknown Source)
&amp;lt;b&amp;gt;(Suprimidas 45750 linhas - quem quiser ver tudo, me mande um e-mail)&amp;lt;/b&amp;gt;
01:22:52,562 ERROR [STDERR]  at java.lang.reflect.Method.invoke(Unknown Source)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
01:22:52,562 ERROR [STDERR]  at $Proxy4.start(Unknown Source)
01:22:52,562 ERROR [STDERR]  at org.jboss.deployment.SARDeployer.start(SARDeployer.java:302)
01:22:52,562 ERROR [STDERR]  at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1025)
01:22:52,562 ERROR [STDERR]  at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:819)
01:22:52,562 ERROR [STDERR]  at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:782)
01:22:52,562 ERROR [STDERR]  at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:766)
01:22:52,562 ERROR [STDERR]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
01:22:52,562 ERROR [STDERR]  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
01:22:52,562 ERROR [STDERR]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
01:22:52,562 ERROR [STDERR]  at java.lang.reflect.Method.invoke(Unknown Source)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
01:22:52,562 ERROR [STDERR]  at $Proxy5.deploy(Unknown Source)
01:22:52,562 ERROR [STDERR]  at org.jboss.system.server.ServerImpl.doStart(ServerImpl.java:482)
01:22:52,562 ERROR [STDERR]  at org.jboss.system.server.ServerImpl.start(ServerImpl.java:362)
01:22:52,562 ERROR [STDERR]  at org.jboss.Main.boot(Main.java:200)
01:22:52,562 ERROR [STDERR]  at org.jboss.Main$1.run(Main.java:508)
01:22:52,562 ERROR [STDERR]  at java.lang.Thread.run(Unknown Source)
01:22:52,562 ERROR [STDERR] Caused by: java.lang.ClassNotFoundException: No ClassLoaders found for: org.jnp.interfaces.LocalOnlyContextFactory
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:306)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:521)
01:22:52,562 ERROR [STDERR]  at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:415)
01:22:52,562 ERROR [STDERR]  at java.lang.ClassLoader.loadClass(Unknown Source)
01:22:52,562 ERROR [STDERR]  at java.lang.ClassLoader.loadClassInternal(Unknown Source)
01:22:52,562 ERROR [STDERR]  at java.lang.Class.forName0(Native Method)
01:22:52,562 ERROR [STDERR]  at java.lang.Class.forName(Unknown Source)
01:22:52,562 ERROR [STDERR]  at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)
01:22:52,562 ERROR [STDERR]  ... 167 more
01:22:54,578 WARN  [SessionFactoryObjectFactory] InitialContext did not implement EventContext&lt;/textarea&gt;&lt;br /&gt;
&lt;/center&gt;&lt;br /&gt;

&lt;/li&gt;
&lt;li&gt;Avisar o usuário:&lt;br /&gt;
Avisar o usuário parece ser uma boa idéia nesta situação. Se o arquivo não está no local indicado, pode ser que ele tenha informado o caminho errado, por exemplo. Uma forma de resolver o problema seria pedir o caminho novamente, informando o erro e ver se ele corrige. Claro, dependendo da situação, pode ser que sua aplicação resolva criar o arquivo ou salve em um arquivo padrão ou simplesmente não realize o salvamento. De qualquer forma, é sempre bom informar o usuário de que o que ele pediu não foi feito ou foi feito de forma diferente.&lt;br /&gt;
Uma vez tomada a decisão de informar o usuário, que método você espera que fique responsável por isso?&lt;br /&gt;
&lt;code&gt;writeBytes()&lt;/code&gt;, o método onde o erro se originou é um método genérico demais. Pode ser usado para qualquer situação em qualquer aplicação. Resolver o que fazer com um erro irá acoplá-lo a uma regra daquela aplicação especificamente, impedindo seu reuso.&lt;br /&gt;
&lt;code&gt;writeFormattedContentFile()&lt;/code&gt;, o método que chamou &lt;code&gt;writeBytes()&lt;/code&gt; não parece ser responsável por lidar com o usuário, assim como &lt;code&gt;saveUserData()&lt;/code&gt;. Ainda que fossem, estando fora da camada de apresentação, como fazê-lo? É uma aplicação desktop em linha de comando, com interface gráfica ou Web? E mesmo que fosse, este era o caso de uso em que o usuário opta por um arquivo existente necessariamente ou é o caso de uso em que o arquivo pode ser criado caso não exista? Em outras palavras, qual era a ação presente no método &lt;code&gt;buttonSaveAction()&lt;/code&gt;?&lt;br /&gt;

Como se pode notar, conforme os métodos se aproximam do usuário, se tornam mais específicos da aplicação, com mais informação sobre o contexto de sua utilização. Conforme se afastam, se tornam mais genéricos e mais reutilizáveis.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
Então, finalmente respondendo a pergunta:&lt;br /&gt;
As informações técnicas sobre o erro devem ser escondidas do usuário comum, mas salvas para que possam ser utilizadas para corrigir. O tratamento pode envolver tentar de outra forma, tentar novamente ou perguntar ao usuário o que fazer, mas de qualquer forma, o usuário deve ser avisado de que seu pedido não foi realizado da forma que se desejava. E sempre que a solução envolver o usuário (avisar do erro e/ou fornecer alternativas), o tratamento deve ser feito no método que tiver informação de contexto suficiente para não só saber quais são as alternativas viáveis, mas como avisar ao usuário.&lt;br /&gt;
&lt;br /&gt;
Não raro, em aplicações com a camada de negócio e apresentação separadas, uma exceção técnica (como &lt;code&gt;ArquivoNaoEncontrado&lt;/code&gt;) pode ser capturada na camada de negócio unicamente para que seja lançada outra em seu lugar, determinando apenas o curso de ação (como &lt;code&gt;PerguntarCaminhoArquivo&lt;/code&gt; ou &lt;code&gt;AvisarErroArquivoNaoEncontrado&lt;/code&gt;). Na camada de apresentação, então, determina-se como avisar ao usuário, de acordo com a ação decidida pelo lançamento da exceção específica na camada de negócio.&lt;br /&gt;
&lt;br /&gt;
Se for bem utilizado, o mecanismo de exceções é seu amigo.&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-4742161016002790163?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/Tgm4g5AiEy0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/4742161016002790163/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/10/excecoes-sao-como-sao.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/4742161016002790163?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/4742161016002790163?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/Tgm4g5AiEy0/excecoes-sao-como-sao.html" title="Exceções são como são" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/10/excecoes-sao-como-sao.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAGRHk6eSp7ImA9WxNWE0g.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-3549372018340548784</id><published>2009-10-06T00:21:00.006-03:00</published><updated>2009-10-12T11:45:25.711-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-12T11:45:25.711-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><category scheme="http://www.blogger.com/atom/ns#" term="modelos" /><category scheme="http://www.blogger.com/atom/ns#" term="xp" /><category scheme="http://www.blogger.com/atom/ns#" term="metodologias" /><category scheme="http://www.blogger.com/atom/ns#" term="mps.br" /><category scheme="http://www.blogger.com/atom/ns#" term="cmmi" /><category scheme="http://www.blogger.com/atom/ns#" term="processos" /><category scheme="http://www.blogger.com/atom/ns#" term="scrum" /><title>Agile, "tradicional" ou ambos?</title><content type="html">Muitos não sabem mas antes de enveredar pelo MPS.BR*/CMMI* eu já estudava muito XP*. E antes do XP, muito RUP*. Agora, acabo de regressar de São Paulo onde fiz o curso oficial Certified ScrumMaster* com o &lt;a href="http://borisgloger.com/"&gt;Boris Gloger&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
O curso foi ótimo para aprofundar meu aprendizado no Scrum. A experiência do Boris com certeza foi um fator importante neste processo. Acabei acumulando ao conhecimento que tive durante o treinamento de coach de XP com o &lt;a href="http://www.improveit.com.br/xp"&gt;Vinícius Teles&lt;/a&gt; e relembrando muitas práticas Ágeis que há muito haviam ficado esquecidas.&lt;br /&gt;
&lt;br /&gt;
O curso também foi muito bom pela contribuição da &lt;a href="http://www.swquality.com.br/"&gt;Ana Rouiller&lt;/a&gt; com relação a integração do MPS.BR/CMMI e Scrum. É uma integração já com bastantes artigos publicados em congressos nacionais e internacionais e até onde eu pude perceber, bastante benéfica para as empresas. Espero que as comunidades de ambos os "flancos" ergam bandeiras brancas e percebam que há o que se aprender com a perspectiva do outro.&lt;br /&gt;
Esta integração, que eu sempre soube ser não só possível mas também benéfica, é um dos assuntos que mais desperta meu interesse desde que comecei a estudar Engenharia de Software.&lt;br /&gt;
&lt;br /&gt;
*Para quem não está familiarizado com a sopa de letrinhas do primeiro parágrafo, aqui vão alguns links.&lt;br /&gt;
Estes são exemplos típicos de assuntos que pretendo abordar neste blog. Na verdade, cada um destes temas merece um blog, mas pretendo abordar todos estes assuntos aqui mesmo em futuras postagens.&lt;br /&gt;
&lt;br /&gt;
Por enquanto, ficam as referências:&lt;br /&gt;
&lt;br /&gt;
MPS.Br:&lt;br /&gt;
&lt;a href="http://www.softex.br/mpsbr"&gt;http://www.softex.br/mpsbr&lt;/a&gt; (Oficial)&lt;br /&gt;
&lt;a href="http://pt.wikipedia.org/wiki/Mps.br"&gt;http://pt.wikipedia.org/wiki/Mps.br&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
CMMI:&lt;br /&gt;
&lt;a href="http://www.blogcmmi.com.br/"&gt;http://www.blogcmmi.com.br/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://pt.wikipedia.org/wiki/Cmmi"&gt;http://pt.wikipedia.org/wiki/Cmmi&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.sei.cmu.edu/cmmi"&gt;http://www.sei.cmu.edu/cmmi&lt;/a&gt; (Oficial)&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/CMMI"&gt;http://en.wikipedia.org/wiki/CMMI&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Scrum:&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29"&gt;http://en.wikipedia.org/wiki/Scrum_(development)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.scrumalliance.org/"&gt;http://www.scrumalliance.org/&lt;/a&gt; (Oficial)&lt;br /&gt;
&lt;a href="http://pt.wikipedia.org/wiki/Scrum"&gt;http://pt.wikipedia.org/wiki/Scrum&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
eXtreme Programming:&lt;br /&gt;
&lt;a href="http://www.improveit.com.br/xp"&gt;http://www.improveit.com.br/xp&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_Extrema"&gt;http://pt.wikipedia.org/wiki/Programação_Extrema&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.extremeprogramming.org/"&gt;http://www.extremeprogramming.org/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Extreme_Programming"&gt;http://en.wikipedia.org/wiki/Extreme_Programming&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Rational Unified Process:&lt;br /&gt;
&lt;a href="http://pt.wikipedia.org/wiki/Rup"&gt;http://pt.wikipedia.org/wiki/Rup&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www-306.ibm.com/software/awdtools/rup/?S_TACT=105AGY59&amp;amp;S_CMP=WIKI&amp;amp;ca=dtl-08rupsite"&gt;http://www-306.ibm.com/software/awdtools/rup/?S_TACT=105AGY59&amp;amp;S_CMP=WIKI&amp;amp;ca=dtl-08rupsite&lt;/a&gt; (Oficial)&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Rup"&gt;http://en.wikipedia.org/wiki/Rup&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-3549372018340548784?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/dMrsUobQacM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/3549372018340548784/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/10/agile-tradicional-ou-ambos.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/3549372018340548784?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/3549372018340548784?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/dMrsUobQacM/agile-tradicional-ou-ambos.html" title="Agile, &quot;tradicional&quot; ou ambos?" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/10/agile-tradicional-ou-ambos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEBQ3czcSp7ImA9WxNWE0g.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-7596359070223086064</id><published>2009-09-22T01:06:00.003-03:00</published><updated>2009-10-12T11:44:12.989-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-12T11:44:12.989-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="OObjetos" /><title>Conformidade de tipo</title><content type="html">Eu já falei sobre isso em algumas aulas mas sempre é válido ressaltar: herança é um acoplamento forte.&lt;br /&gt;
&lt;br /&gt;
Acoplamentos fortes são indesejáveis, pois criam dependências pelas quais o impacto de uma mudança se propaga.&lt;br /&gt;
Uma herança entre duas classes traz várias implicações. Uma delas é dizer que a subclasse se comporta como a superclasse (Princípio de Substituição de Liskov*).&lt;br /&gt;
&lt;br /&gt;
Assim, um pequeno polimorfismo de classe pode causar grandes transtornos se este relacionamento não for bem observado. Vou falar um pouco de covariância e contravariância.&lt;br /&gt;
&lt;br /&gt;
Imaginem uma &lt;code&gt;Superclasse&lt;/code&gt; e uma &lt;code&gt;Subclasse&lt;/code&gt;, ambas com um método &lt;code&gt;m&lt;/code&gt; declarado, sendo redefinido na subclasse. Este método tem um retorno e uma lista de parâmetros.&lt;br /&gt;
&lt;br /&gt;
A covariância é a determinação de que o retorno da subclasse deve ser do mesmo tipo do retorno da superclasse ou de um tipo mais específico (subtipo) que este.&lt;br /&gt;
&lt;br /&gt;
Então suponha a classe &lt;code&gt;Object&lt;/code&gt; e a classe &lt;code&gt;String&lt;/code&gt; herdando de &lt;code&gt;Object&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
O método &lt;code&gt;m&lt;/code&gt; na &lt;code&gt;Superclasse&lt;/code&gt; pode retornar &lt;code&gt;Object&lt;/code&gt;. O método &lt;code&gt;m&lt;/code&gt; redefinido na &lt;code&gt;Subclasse&lt;/code&gt; pode retornar &lt;code&gt;Object&lt;/code&gt; ou &lt;code&gt;String&lt;/code&gt; (ou qualquer outro subtipo de &lt;code&gt;Object&lt;/code&gt;).&lt;br /&gt;
&lt;br /&gt;
Isto porque um código como&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;Object objeto = instancia.m();&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
deveria funcionar com&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;Superclasse instancia = new Superclasse();&lt;/code&gt;&lt;br /&gt;
ou&lt;br /&gt;
&lt;code&gt;&lt;b&gt;Super&lt;/b&gt;classe instancia = new &lt;b&gt;Sub&lt;/b&gt;classe();&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Reparem que o código cliente (que usa as classes) assume que os retornos serão pelo menos do tipo declarado na Superclasse (ou mais específico) e, mais ainda, a variação deste retorno deve ser igual ou menor. Por exemplo, fosse o retorno um inteiro entre 0 e 10, a subclasse poderia retornar quaisquer números entre 0 e 10 (não necessariamente todos) mas nunca um número fora destes limites, pois o código cliente não pode estar preparado para lidar com situações que não estão previstas para a execução daquele método através de uma referência para a Superclasse.&lt;br /&gt;
&lt;br /&gt;
Notem que para os objetos retornados, o ideal é que o espaço-estado* também seja igual ou menor.&lt;br /&gt;
&lt;br /&gt;
Assim, conforme o tipo vai ficando mais específico (descendo na hierarquia), o retorno também vai ficando mais específico, configurando-se a covariância.&lt;br /&gt;
&lt;br /&gt;
A contravariância é o mesmo conceito aplicado aos parâmetros. Ela é "contra" pois conforme se desce na hierarquia (ficando mais específico), os parâmetros vão aumentando os limites.&lt;br /&gt;
&lt;br /&gt;
Se passo para o método &lt;code&gt;m&lt;/code&gt; na superclasse um valor entre 0 e 5 e ele funciona, na subclasse, ele deve funcionar, no mínimo, com valores entre 0 e 5. Nenhum problema se ele funcionar também com 314.1592. O problema é se ele só funcionar com valores entre 0 e 3 ou não funcionar com 4 ou qualquer outra restrição. Devemos lembrar que a declaração&lt;br /&gt;
&lt;code&gt;&lt;b&gt;Super&lt;/b&gt;classe instancia = new &lt;b&gt;Sub&lt;/b&gt;classe();&lt;/code&gt;&lt;br /&gt;
é sempre válida e quem determina se uma classe funciona como deveria é o código cliente (novamente Princípio de Substituição de Liskov).&lt;br /&gt;
&lt;br /&gt;
Vocês se preocupam com o funcionamento correto das heranças nas aplicações que fazem?&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;br /&gt;
&lt;br /&gt;
*Prometo que no futuro falo um pouco do Princípio de Substituição de Liskov e de espaço-estado.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-7596359070223086064?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/8GwE-UWAeEU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/7596359070223086064/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/09/conformidade-de-tipo.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/7596359070223086064?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/7596359070223086064?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/8GwE-UWAeEU/conformidade-de-tipo.html" title="Conformidade de tipo" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/09/conformidade-de-tipo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIFSX8-eyp7ImA9WxNWFUo.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-6236630551338777110</id><published>2009-09-07T14:09:00.009-03:00</published><updated>2009-10-14T22:35:18.153-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T22:35:18.153-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="código" /><title>Você comenta seu código?</title><content type="html">Para quem não sabe, sou monitor honorário da disciplina "Computação II" no Departamento de Ciência da Computação da UFRJ (&lt;a href="http://www.dcc.ufrj.br/%7Ecomp2/professor.html"&gt;http://www.dcc.ufrj.br/~comp2/professor.html&lt;/a&gt;).&lt;br /&gt;
Como monitor honorário eu ajudo os outros monitores nas tarefas que me agradam. ;-) Isso significa dar aulas de apoio e tirar dúvidas, principalmente.&lt;br /&gt;
Na última semana um aluno perguntou sobre a importância de comentar o código dos exercícios a serem corrigidos. Adaptei a resposta para a pergunta "É importante comentar?".&lt;br /&gt;
É MUITO importante que seu código seja compreensível, não só por você mesmo (agora ou no futuro), por pessoas que trabalham com você ou trabalharão num projeto em que você desenvolveu um dia.&lt;br /&gt;
Como regra, eu adoto a política de tentar fazer um código tão claro que dispense comentários. Só quando isto não é possível por uma idiossincrasia da vida que eu comento e tento ser o mais explicativo possível.&lt;br /&gt;
&lt;br /&gt;
“There are two ways of constructing a software design; one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” Sir Charles Antony Richard Hoare&lt;br /&gt;
&lt;br /&gt;
Reparem, por exemplo, neste trecho fictício:&lt;br /&gt;
&lt;pre&gt;if ((e1.comparaMaior(e2) || e1.vazio()) &amp;amp;&amp;amp; (e2 != null)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fazerAlgo();
}
&lt;/pre&gt;
&lt;br /&gt;
em contraste com:&lt;br /&gt;
&lt;pre&gt;if (elemento1AtendeRestricaoComparandoElemento2(elemento1, elemento2)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fazerAlgo();
}

boolean elemento1AtendeRestricaoComparandoElemento2(Elemento elemento1, Elemento elemento2) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return (elemento1.comparaMaior(elemento2) || elemento1.vazio()) &amp;amp;&amp;amp; (elemento2 != null);
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Notem que fica claro o que está sendo testado no if e fica clara também a intenção daquela comparação enorme graças ao nome método implementado em seguida. Não é necessário o comentário. Assim, evita-se, entre outras coisas, que o código seja atualizado, e o comentário esquecido, ficando desatualizado e informando uma condição diferente da que acontece, causando muitos transtornos.&lt;br /&gt;
Além disso, se a intenção é entender a finalidade do código, muitas vezes entender a comparação é desncessário.&lt;br /&gt;
&lt;br /&gt;
Usar nomes de variáveis que signifiquem alguma coisa também é outra boa prática. Todas as boas IDEs completam os nomes quando digitamos os primeiros caracteres e pressionamos ctrl+space.&lt;br /&gt;
Notem que não poupei letras no nome do método. O importante é deixar claro e organizado.&lt;br /&gt;
&lt;br /&gt;
Vale notar também que este código é agora mais testável, já que é possível testar apenas a comparação. ;-)&lt;br /&gt;
&lt;br /&gt;
Uma situação válida para a utilização de comentários é quando entendemos algum código um pouco complicado, que demanda algum raciocínio de como o código funciona para entendermos seu objetivo. Neste caso, vale comentar o objetivo se não for possível (por restrições quaisquer) refatorá-lo para torná-lo adequado ao entendimento.&lt;br /&gt;
&lt;br /&gt;
O Javadoc também é bem interessante, mas nele deve constar apenas "o que" o método faz (objetivo) e não "como" o método faz (lógica). Assim, a documentação se torna suscinta, simples e direta, atendendo aos objetivos de quem a lê. Quem quiser entender como irá ler o código e o deve encontrar devidamente organizado.&lt;br /&gt;
&lt;br /&gt;
E vocês? O que comentam? Como comentam?&lt;br /&gt;
&lt;br /&gt;
Abraço a todos!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-6236630551338777110?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/iP2V9MymXC8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/6236630551338777110/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/09/voce-comenta-seu-codigo.html#comment-form" title="4 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/6236630551338777110?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/6236630551338777110?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/iP2V9MymXC8/voce-comenta-seu-codigo.html" title="Você comenta seu código?" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/09/voce-comenta-seu-codigo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8GQXYzfSp7ImA9WxNRE0k.&quot;"><id>tag:blogger.com,1999:blog-1207075282956940856.post-8019599549526313918</id><published>2009-09-07T11:48:00.000-03:00</published><updated>2009-09-07T13:27:00.885-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-07T13:27:00.885-03:00</app:edited><title>Um blog!</title><content type="html">Então galera...&lt;br /&gt;Muita gente tem me perguntado porque eu não tenho um blog sobre coisas relacionadas a Java ou orientação a objetos ou desenvolvimento de software em geral. A resposta é simples. Porque eu não tenho tempo pra ficar postando, atualizando. E ainda acho que isso é verdade.&lt;br /&gt;De qualquer forma, vou fazer uma tentativa.&lt;br /&gt;A princípio, este blog não é sobre Java. É sobre desenvolvimento de software em geral. Sendo de um assunto mais amplo, pode ser que eu tenha mais o que dizer. ;-) Também aumentam as chances de um assunto interessante aparecer por acaso e me animar para postar.&lt;br /&gt;Enfim, pretendo abordar assuntos relacionados a qualidade de software em geral, de processos e metodologias a questões de design, boas práticas, padrões, etc.&lt;br /&gt;É claro que como trabalho com Java, vez ou outra haverá aqui dicas de aplicações, componentes, frameworks e trechos de código interessantes. E os exemplos, em geral, provavelmente serão em Java quando envolverem código.&lt;br /&gt;&lt;br /&gt;Vamos ver se esta empreitada segue em frente ou desisto depois de meia dúzia de posts.&lt;br /&gt;&lt;br /&gt;Abraço a todos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207075282956940856-8019599549526313918?l=craftnicely.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/craftnicely/~4/zail1PhiezQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://craftnicely.blogspot.com/feeds/8019599549526313918/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://craftnicely.blogspot.com/2009/09/um-blog.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8019599549526313918?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1207075282956940856/posts/default/8019599549526313918?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/craftnicely/~3/zail1PhiezQ/um-blog.html" title="Um blog!" /><author><name>Peter Lupo</name><uri>https://profiles.google.com/101158450141034105303</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-YTE_Qjzk0LE/AAAAAAAAAAI/AAAAAAAAAAA/X8c0seRXKrw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://craftnicely.blogspot.com/2009/09/um-blog.html</feedburner:origLink></entry></feed>

