Automatização utilizando Ant

Desenvolvedores que iniciaram seu aprendizado na linguagem Java utilizando alguma IDE, muitas vezes desconhecem como funcionam os processos responsáveis por transformar o código escrito, em software propriamente dito. Neste post irei mostrar um pouco sobre os conceitos por trás destes processos, como compilar e geração de arquivos .jar, e como automatizar estas tarefas utilizando o Ant.

Os arquivos .class

Quando desenvolvemos um software escrito em Java, não é nosso código em si que é utilizado para executar o programa. Antes de rodarmos o código que escrevemos, o mesmo deve ser compilado, etapa esta que a maioria das IDEs faz automaticamente. A compilação consiste em transformar o código fonte, legível para nós, em código de máquina ou bytecode, que é a forma que a JVM (Java Virtual Machine) compreende e sabe executar. Enquanto os arquivos que escrevemos possuem a extensão .java, este arquivos gerados, escritos em bytecode, são arquivos .class.

Os arquivos .jar e .war

A não ser que você esteja escrevendo seu primeiro Hello World, dificilmente seu programa em Java terá somente uma classe. O arquivo .jar é o executável do Java, nele se encontram os pacotes com todas as classes e arquivos do seu software. Os arquivos .war funcionam de forma semelhante, mas são criados para aplicações web, nele também se encontram todas as classes e arquivos do projeto. O arquivo .war é utilizado para instalar a aplicação no servidor web como Jboss ou TomCat.

Apache Ant

Apache Ant, ou somente Ant como é mais conhecido, é uma ferramenta que automatiza além dos processos mostrados anteriormente muitos outros. Você pode por exemplo criar e remover diretórios, mover arquivos entre eles, rodar seus testes unitários e gerar relatórios.

Instalação

Baixe o instalador do Ant aqui. Descompacte o arquivo no local de sua preferência. É necessário inserir o caminho da pasta “bin” do Ant às variáveis de ambiente do Windows. Copie o endereço da pasta bin que vai ser algo como “C:\Program Files\apache-ant-1.9.2\bin”. Vá nas propriedades do computador e acesse a opção variáveis de ambiente. Procure a variável Path e adicione no final de seu valor o caminho para o diretório copiado anteriormente. Isso é tudo que precisa ser feito, para conferir se a instalação ocorreu corretamente, apartir do prompt de comando digite: ant –version. Se tudo estiver certo, uma mensagem com a versão de seu Ant será exibida.

O arquivo build.xml

As operações do Ant, mais conhecidas como tasks, funcionam através de configurações escritas em um arquivo XML. Através de comandos simples as tarefas que vimos anteriormente podem ser automatizadas facilmente. Vou demonstrar isso através de um exemplo bem simples com o objetivo de demonstrar na prática como se monta um arquivo de build. Crie os arquivos build.xml e TesteAnt.java, e copie os trecho abaixo, ou baixe o exemplo pronto no meu GitHub.

public class TesteAnt {
public static void main(String[] args) {
System.out.println(“Hello Ant!”);
}
}

<project name=”teste” basedir=”.” default=”executar”>

<property name=”classes” location=”classes”/>
<property name=”arquivo” value=”TesteAnt” />

<target name=”diretorios”>
<mkdir dir=”classes” />
</target>

<target name=”apagar”>
<delete dir=”classes”/>
</target>

<target name=”compilar” depends=”diretorios”>
<javac srcdir=”${basedir}” classpath=”${classes}” destdir=”${classes}”/>
</target>

<target name=”empacotar” depends=”compilar”>
<mkdir dir=”build/jar”/>
<jar destfile=”build/jar/TestAnt.jar” basedir=”${basedir}/classes”>
<manifest>
<attribute name=”Main-Class” value=”main.TesteAnt”/>
</manifest>
</jar>
</target>

<target name=”executar” depends=”empacotar, apagar”>
<java jar=”build/jar/TestAnt.jar” fork=”true”/>
</target>

</project>

Por trás do exemplo

<project name=”teste” basedir=”.” default=”executar”>

Esta linha é o início do arquivo de build, onde é declarado o nome do projeto, o diretório base, e a task padrão que será executada pelo Ant.

<property name=”classes” location=”classes”/>
<property name=”arquivo” value=”TesteAnt” />

A tag property serve para declarar variáveis que podem ser utilizadas dentro do arquivo de build.

<target name=”diretorios”>
<mkdir dir=”classes” />
</target>

A tag target serve para definir um alvo para o Ant. Uma vez definido, você pode chamar o alvo dentro do arquivo, ou até de fora através do comando “ant nomeDoAlvo”. Mkdir cria um diretório com o nome recebido por parâmetro.

<target name=”apagar”>
<delete dir=”classes”/>
</target>

Delete apaga o diretório com o nome recebido. Não se preocupe não estamos criando e apagando em seguida o diretório, você já irá entender.

<target name=”compilar” depends=”diretorios”>
<javac srcdir=”${basedir}” classpath=”${classes}” destdir=”${classes}”/>
</target>

A tag javac, assim como o comando de mesmo nome, compila os arquivos .java gerando como saída os .class escritos em bytecode

<target name=”empacotar” depends=”compilar”>
<mkdir dir=”build/jar”/>
<jar destfile=”build/jar/TestAnt.jar” basedir=”${basedir}/classes”>
<manifest>
<attribute name=”Main-Class” value=”main.TesteAnt”/>
</manifest>
</jar>
</target>

A tag jar empacota os arquivos indicados gerando como saída um arquivo jar. Já a tag manifest cria o arquivo manifest necessário para criação do pacote jar.

<target name=”executar” depends=”empacotar, apagar”>
<java jar=”build/jar/TestAnt.jar” fork=”true”/>
</target>

E a tag java  executa um arquivo .jar. A tag depends indica que a iniciação do target depende da finalização de outro, por isso no exemplo anterior o alvo “apagar” não será executado após o “diretorios”, e sim antes do alvo “executar”. Cuidado ao montar seu arquivo, se um target não for dependência de outro, ele só será executado caso seja declarado como default na tag project.

Executando

Para executar o arquivo é simples, basta abrir o prompt de comando, navegar até a pasta onde se encontra o arquivo “build.xml”, e digitar o comando ant, se tudo ocorrer bem, você terá uma pasta com o arquivo .jar e a mensagem “Hello Ant!” será exibida no console. Também é possível executar um target específico executando o comando ant nomeTarget.

Como disse anteriormente, este foi apenas um exemplo didático, o Ant possibilita automatizar muitas outras tarefas de seu projeto. Abaixo seguem alguns links interessantes para se aprofundar no assunto.

Links

Ant: http://ant.apache.org/

Documentação: http://ant.apache.org/manual/index.html

Lista de tasks: http://ant.apache.org/manual/Tasks/ 

Publicidade

Qual a sua causa?

O relógio chama. Hora de acordar. Vale a pena? Você tem um motivo para acordar. Algo para fazer? Algo para realizar?

Como conseguir manter este foco. Como manter um propósito vivo? Nesta apresentação de pouco mais de 2mins, apresento alguns conceitos de caras famosos, como Daniel Pink e Chip Conley. Podemos ainda falar na famosa pirâmide de Maslow, que acabei pulando nesta apresentação (a pirâmide aparece quase como uma mensagem subliminar).

O dinheiro não é suficiente. Ser reconhecido pode não ser suficiente. Fazer parte de uma causa, que nos ajuda a manter o foco e aceitar as realizações que conseguimos alcançar, pode ser uma opção.

Esta palestra foi realizada em um uMov.me Labs Summit, evento de palestras usado para compartilhar e criar conhecimento.

Link para o vídeo no youtube. Ou mande um play aí na apresentação:

Análise de Código utilizando SonarQube

No meu último post falei sobre métricas de código e os benefícios que eles podem trazer para a boa saúde do código. Hoje irei apresentar uma ótima ferramenta para gerar automaticamente estas métricas, SonarQube.

SonarQube é um software open-source que se propõe a ser a central de qualidade do seu código-fonte, lhe possibilitando o controle sobre um grande número de métricas de software, e ainda apontando uma série de possíveis bugs. Tudo isso é gerado através de uma análise completa do código, e após isso os resultados obtidos são mostrados através de uma interface web, em forma de dashboards, e gráficos. Um exemplo do resultado disto pode ser visualizado nesta página.

Iniciando o SonarQube

Vejamos então como configurar o SonarQube. Para este exemplo irei utilizar um projeto Java do jogo FizzBuzz. Além de Java, mais de 25 linguagens são suportadas como C# e Python por exemplo. Uma lista completa pode ser conferida aqui.

Baixe o SonarQube 3.6.3. Descompacte o arquivo em uma pasta de sua escolha. Abra a pasta “sonar-3.6/bin” e entre na versão relativa ao seu sistema operacional. Execute o arquivo StartSonar.bat (no caso do Windows). Um console irá aparecer e executar o serviço do Sonar. Para verificar se tudo ocorreu corretamente acesse o seguinte endereço em seu navegador: http://localhost:9000/. A tela abaixo deve aparecer.

exemplo

Tela de apresentação do SonarQube

Configurando o projeto

O próximo passo será criar o arquivo de configuração. Crie um arquivo com o nome “sonar-project.properties” na raiz de seu projeto. Abaixo segue o arquivo com a configuração para o projeto exemplo, copie para o seu arquivo e faça as adaptações necessárias para o seu projeto.

# metadados requeridos

sonar.projectKey=FizzBuzzSonarExample

sonar.projectName=FizzBuzzSonarExample

sonar.projectVersion=0.1

# caminhos para os códigos fontes

# caminhos podem ser separados por vírgula

sonar.sources=src/main/java

sonar.tests=src/main/test

# A linguagem do projeto

sonar.language=java

# Formato

sonar.sourceEncoding=UTF-8

Analisando o código

Para fazer a análise do código iremos utilizar o SonarQube Runner. Baixe o arquivo SonarRunner 2.2.2, e extraia o conteúdo em uma pasta de sua escolha. Agora é necessário adicionar o caminho onde se encontra o arquivo “sonar-runner.bat” às variáveis de ambiente (no caso do Windows). Clique com o botão direito em Computador e escolha propriedades. Vá em Configurações avançadas do sistema e entre em variáveis de ambiente. Edite a variável Path, adicionando no final o caminho para o SonarQube Runner, que irá ser algo como: “suaPasta\sonar-runner-2.2.2\bin”

variaveis

Adicionando o SonarQube Runner às variáveis de ambiente

Feita a configuração, é hora de análisar o projeto. Se certifique que o SonarQube foi iniciado e que seu projeto tenha o arquivo “sonar-project.properties”. Através do Prompt de Comando, navegue até a pasta raiz de seu projeto e digite o comando: “sonar-runner”. Se tudo ocorrer bem a análise deve iniciar e o resto do trabalho é feito automaticamente. O tempo de duração irá variar de acordo com o tamanho de seu código, e no final uma mensagem de sucesso é exibida.

prompt

Mensagem de sucesso na execução do Sonar Runner

Agora você pode acessar novamente o endereço http://localhost:9000/ para conferir o resultado. Os dashboards com as métricas padrões serão exibidos. Você pode configurar os dashboards, efetuando login com usuário: admin, e senha: admin. 

Por fim acesse a documentação oficial para conhecer as diversas opções de métricas disponíveis, e escolha as que atenderem o seu projeto.

Clean code good! Spaghetti code bad!

Desculpem pelo título em inglês, era para poder fazer a piada. O ponto é que ler um código espaguete é diferente de comer espaguete. O código neste “formato” provoca dores de cabeça e muitas vezes gera sentimentos como ódio, fúria, principalmente se você é chamado para corrigir algo em um código assim perto das 18h da sexta-feira.

O ideal é poder iniciar novos sistemas com boas práticas, de padrões de projetos e facilidade de leitura. Mas nem sempre é assim. E aí vem a importância do estudo contínuo de orientação a objetos, padrões de projetos, e tópicos de engenharia de software em geral.

excelencia-tecnica.032

Uma das referências neste aspecto é Bob Martin, o Uncle Bob.

Usei o Uncle Bob como motivação em alguns time que trabalhei, usando a regra da banda verde.  Selecionava pessoas que acreditava que tinham potencial de disseminar a cultura de TDD e Clean Code pela equipe, e doava uma banda verde para que aquele desenvolvedor sempre que fosse tocar no código se lembrasse de manter o código limpo e desenvolver como um desenvolvedor profissional.

Praticar código limpo. Se eu posso dar um conselho para você, esse é o meu conselho. E dentro da prática, está em transformar código. E transformar com paciência. Baby steps. Saber que débito técnico é uma realidade em qualquer código de produção. Mesmo times ágeis focados em refactoring, testes e qualidade no código sempre, encontrarão oportunidades de melhoria, para ganhar mais desempenho e estabilidade em algum pedaço de código fonte.

Pensando nisto trouxe um dojo diferente para a equipe. Coloquei um código Java ruim, com vários pequenos problemas que passam desapercebidos pelos desenvolvedores muitas vezes, para que durante o espaço do dojo o time fosse trabalhando criando testes básicos para garantir o comportamento do fonte e a partir daí focassem na refatoração da estrutura. Dá para ver o resultado depois de 40mins programando em um repositório do github. Lá tem o código original para quem quiser brincar.

Os Coding Dojos são excelentes oportunidades para a prática do código limpo. Seja de um problema do zero como de um problema “pronto” para ser transformado, como é o caso deste “bad code dojo”. Estudar ferramentas de apoio no processo do TDD, como ferramentas de auditoria de código fonte e cobertura de testes, também são ótimas possibilidades. No meu post sobre TDD tem algumas dicas.

E essa prática dever ser igual a do seu esporte favorito. Deve fazer parte da sua rotina praticar código e resolver problemas. Escolha um kata, e pratique código limpo! Comecei o post em inglês e vou terminar com uma tagline para vocês sobre qualidade de código e testes. Só quem faz teste automatizado vai entender:

Keep the bar green to keep the code clean!

Android & Lua

Neste post, vou apresentar um pequeno projeto de exemplo que mostra uma integração de Lua com uma aplicação Android.


O que é Lua?

Lua é uma “embed language”, ou seja, tem como objetivo ser usada dentro de uma aplicação escrita com outra linguagem (para estender a app, configurar, etc.). Quando foi criada na PUC-Rio, por exemplo, era usada por engenheiros da Petrobras (que nem mesmo eram programadores) para configurar o funcionamento de alguns softwares usados nas plataformas de petróleo.

Mais detalhes na página oficial: http://www.lua.org


Como um programa escrito em Lua roda dentro de uma aplicação?

Lua nada mais é que uma biblioteca escrita em C. É multiplataforma, pois usa apenas as funções e tipos da biblioteca padrão do C. É possível executar programas escritos em Lua (scripts) através da linha de comando, mas isso nada mais é que um pequeno executável que tem a biblioteca Lua dentro.

Então, para incluir Lua na sua aplicação, basta incluir essa biblioteca no seu programa e usar suas funções. É possível carregar arquivos com os scripts, executá-los e integrar funções e dados; por exemplo, funções escritas em C que podem ser chamadas pelo script Lua, e funções do script podem ser chamadas pelo código em C.


Lua e Android

No link https://github.com/marciodrosa/LuaAndAndroidSample há um sample que mostra como integrar Lua em uma aplicação mobile. No caso, Android. Teoricamente, deve ser possível também em outras plataformas, como iOS e Windows Phone 8 (o Windows Phone 7 não tem suporte a programação com C, logo, só é possível executar Lua caso exista alguma implementação não oficial da biblioteca em C#).

O objetivo é mostrar como uma aplicação poderia ser estendida com um plug-in escrito pelo usuário.

Ao executar a app, são exibidos três caixas de texto. Ao alterar valores das duas primeiras, a soma destes valores aparece na terceira. Essa lógica e manipulação do terceiro campo é feita por um script Lua.

postimg1 - screenshot


Mas as aplicações Android são escritas em Java, não em C!

Java permite integração com código escrito em C, a chamada Java Native Interface (JNI). O código escrito em C precisa ser compilado em uma lib, e por isso existem as ferramentas do Android para isso: o Android NDK (http://developer.android.com/tools/sdk/ndk/index.html). Além do compilador, há algumas bibliotecas disponíveis no NDK.

Assim, no Android, ocorre uma conversa entre três linguagens: Java <—> C <—> Lua.


Como funciona a app de exemplo LuaAndAndroidSample

Dentro do projeto há um arquivo “myscript.lua”, que é empacotado junto com a aplicação. Essa foi a maneira utilizada por este projeto de exemplo, mas é claro que poderia ser feito de outras maneiras, afinal, o script é apenas um texto; poderia ser recebido pela rede, lido de um arquivo, ou até mesmo criado dentro da app, em uma caixa de texto. O conteúdo do script é o seguinte:

 return {
   onfieldvaluechangedbyuser = function(context)
     local op1 = tonumber(context.fields["Field one"].value) or 0
     local op2 = tonumber(context.fields["Field two"].value) or 0
     return {
       newfieldvalue = {
         field = "Field three",
         value = op1 + op2,
       }
     }
   end
 }

Este script é como um plugin, ele altera o comportamento da aplicação para mostrar uma nova informação na terceira caixa de texto. Quando a app é iniciada, ela carrega e executa o script, que apenas retorna uma tabela (objeto) com as funções de callback para serem chamadas em determinados eventos. No exemplo, esta tabela tem uma função chamada “onfieldvaluechangedbyuser”, que é chamada pela app quando uma caixa de texto tem o valor alterado pelo usuário.

A função onfieldvaluechangedbyuser recebe um objeto de contexto, que possui os dados da aplicação (como os valores das três caixas de texto). Na implementação, ela retorna um outro objeto (result), que é então processado pela app. Este outro objeto pode possuir um novo valor para algum campo. No myscript.lua, o script retorna um novo valor para ser setado na terceira caixa de texto.

Resumidamente, este é o fluxo do que ocorre:

Usuário altera um valor na caixa de texto –> app chama o callback do script, passando o contexto –> script retorna um resultado –> app processa o resultado.

A idéia dessa arquitetura é isolar a execução do script em uma sandbox: não há interação entre a app e o script (por exemplo, o script não altera o valor da terceira caixa de texto; ao invés disso, ele retorna um objeto solicitando que a app faça isso). Esse isolamento é feito para deixar a execução do script mais unitária, facilitar os testes e simplificar o fluxo.

Além disso, usei um pouco da idéia dos plugins do Blender (blender.org), que também são executados assim que a aplicação é iniciada, e que possui funções de callback para serem chamadas mais tarde, quando ocorrem eventos (também recebendo um objeto de contexto como parâmetro).

postimg2 - flow


Como foi feita a integração na app (a “engine” de plug-ins)

A arquitetura básica da “engine” é exemplificada na seguinte imagem:

postimg3 - languageflow

  • A biblioteca em C foi nomeada de “Bridge”, já que é uma ponte entre a app e os scripts.
  • A aplicação Java e o “Bridge” em C conversam entre si (Java solicita para a Bridge que o plugin execute; a Bridge retorna resultados para a aplicação Java).
  • A Bridge e uma engine Lua conversam entre si. Essa engine não é o plugin em si. Ela é usada para fazer a lógica de chamada do plugin, processar erros, resultados, etc. Isso mostra como Lua pode ser usado não apenas para estender a aplicação: neste caso, foi usada para implementar uma lógica que pertence nativamente à aplicação. Isso pode ser muito útil para aplicações multiplataforma. Por exemplo, se a mesma app for implementada para outro sistema, como iOS, o código dessa engine em Lua pode ser reaproveitado.
  • Por fim, a engine em Lua faz o plugin executar. O plugin não se comunica com ninguém, ele executa em uma sandbox isolada, evitando que a lógica implementada por um usuário possa agir de maneira inesperada na aplicação. Toda a comunicação é feita entre a engine Lua e a Brigde C.

Algumas informações adicionais

  • Embora Lua utilize ANSI C (apenas as bibliotecas padrão), nem tudo são flores: o NDK, por exemplo, não possui a API de internacionalização do C (utilizada pelo Lua para saber se um número decimal usa ponto ou vírgula). Então, pequenos ajustes são necessários. O código fonte do Lua 5.2 pronto para ser compilado para Android pode ser pego no meu repositório do Github: https://github.com/marciodrosa/LuaAndroid. Além dos ajustes necessários, ele também direciona as mensagens de erro e log para o logcat.
  • Para fazer o build de uma lib para Android usando código-fonte C, os arquivos de código devem ser colocados dentro de uma pasta chamada “jni” e o comando “ndk-build” deve ser executado. Dentro da pasta “jni” também há alguns arquivos de configuração, como “Android.mk” e “Application.mk”, e outras libs pré-compiladas, caso sejam usadas pelo projeto. O NDK automaticamente move os binários gerados para dentro da pasta “lib”. No projeto Java do Android, as libs que serão usadas devem ser carregadas usando System.loadLibrary (ver a classe StartActivity do projeto LuaAndAndroidSample). O build pode parecer um pouco difícil de entender no começo. Para mais detalhes, é necessário ler a documentação do NDK. A maior parte da documentação não está disponível online; ao invés disso, vem junto com o projeto do Android NDK, quando ele é baixado.
  • No projeto AndroidAndLuaSample, há um método que gera o objeto “context”, que é passado para o callback do script. Ele gera o context concatenando scripts. Obviamente, isso não é uma boa prática, não estamos lidando com linguagens orientadas a string! Que fique claro que isso foi feito apenas para demonstração. O correto seria criar o objeto de contexto usando a API C do Lua.
  • Este sample funciona apenas em dispositivos com processador ARM. É necessário fazer outro build das bibliotecas C para que elas funcionem com outros processadores, como Intel.

Links

Página oficial do Lua:
http://www.lua.org/

Documentação do Lua (manual, referência da API e referência da API C):
http://www.lua.org/manual/5.2/

Livro online gratuito sobre Lua (mas é de uma versão antiga do Lua, com algumas features desatualizadas):
http://www.lua.org/pil/contents.html

Android NDK:
http://developer.android.com/tools/sdk/ndk/index.html

Lua 5.2 para Android:
https://github.com/marciodrosa/LuaAndroid

Código-fonte do projeto de exemplo “LuaAndAndroid”:
https://github.com/marciodrosa/LuaAndAndroidSample

Métricas de Software X Saúde do Código

Você já deve ter ouvido falar sobre a importância da qualidade de um produto ou serviço certo?

Diversas áreas se preocupam com isso, da construção civil e seus prédios, à um médico ao realizar uma cirurgia. Mas e na área de desenvolvimento de software, quais ferramentas temos a disposição para garantir a qualidade e excelência de nosso produto, o software? Temos diversas respostas para estas pergunta: metodologias e processos, testes de aceitação, testes funcionais, testes de stress. Estas ferramentas tem por objetivo garantir a qualidade a nível de cliente, fazendo com que o produto atenda as demandas corretamente para as quais foi projetado.

Mas e para nós desenvolvedores, o que pode ser considerado como um software de qualidade? O estudo da engenharia de software nos remete a diversos problemas que o desenvolvedor deve procurar evitar para obter código fonte de qualidade. Duplicidade de código, métodos e classes com muitas responsabilidades, alta complexidade ciclomática, ausência de testes unitários, entre outros.

Partindo da premissa de que o desenvolvedor conhece as boas práticas de programação, controlar a propagação destes fatores indesejáveis, em um projeto pequeno pode ser fácil. Mas atualmente a realidade é outra, projetos tendem a serem escaláveis e crescerem ao longo do tempo. Além disso dificilmente o desenvolvedor irá trabalhar sozinho, o desenvolvimento distribuído já é realidade na maioria da empresas. Nesses casos é muito fácil a equipe perder o controle da dimensão do software e de seus problemas.

E é neste cenário que entram as métricas de software. Existem diversas métricas, cada uma medindo um aspecto do software. Abaixo seguem alguns exemplos:

Número de linhas de código (LOC, KLOC): Mostra a quantidade de linhas do código fonte. Deve-se ter cuidado com está métrica quando utilizada para fazer comparações. Um maior número de linhas de código não significa necessariamente que um software é maior que outro. Por exemplo diferentes linguagens de programação necessitam de número de instruções diferentes para executarem as mesmas coisas.

Complexidade Ciclomática (CC): Fornece uma medida sobre a complexidade do software. O cálculo de complexidade ciclomática leva em conta quantos desvios uma função possui. Cada comando if, switch, for, while, é considerado um desvio do fluxo principal do código. Toda função possui como valor padrão 1, já que pelo menos um caminho é possível para o código. Conforme são inseridos os desvios este número aumenta. Como dito por Robert C. Martin em seu livro Código Limpo, cada método deve ter uma única responsabilidade, portanto devemos sempre buscar manter este indicador baixo, garantindo a manutenibilidade de nosso código.

Falta de coesão em métodos (LCOM): Esta métrica mede o nível de coesão de uma classe através da verificação do número de acessos a atributos em comum pelos métodos. Se a classe possui um método A que acessa os atributos B e C, e um método D que acessa os atributos E e F, a métrica considera que essa classe tem duas responsabilidades. Quanto maior o LCOM, mais responsabilidades a classe possui, tornando-a pouco coesa. Assim como outras métricas, este valor não pode ser considerado totalmente verdadeiro. Em algumas ocasiões, em virtude das regras de negócio, dois conceitos que parecem ser responsabilidades distintas, na verdade fazem parte do mesmo escopo. Portanto sempre deve-se analisar minuciosamente o código com LCOM alto, para tomar as ações corretas.

Estas métricas são apenas um exemplo, existem outras diversas. Mas a pergunta que fica é como calcular de forma efetiva estas métricas? Existem diversas ferramentas utilizadas para medição de software, algumas servem para métricas específicas, mas existem soluções como Sonarqube que oferecem um pacote de métricas que podem ser utilizadas pelos desenvolvedores para monitorar o estado do código de maneira simples e rápida. Algumas destas ferramentas também auxiliam a comparação do código em um período de tempo, assim possibilitando a criação de gráficos que mostrem a evolução de nosso software.

Um bom exemplo disso seria um gráfico do tipo Cobertura de testes X Complexidade ciclomática. Quando evoluímos o software inserindo novas features, devemos ter o cuidado de não inserir complexidade desnecessária, visando a boa evolução do código. Abaixo segue um exemplo de como esse tipo de gráfico nos fornece um rápido feedback sobre o código:

Gráfico de complexidade do framework Struts

Este gráfico mostra claramente que o framework Struts inseriu alguma funcionalidade que aumentou a complexidade do código drasticamente, e que a cobertura de código caiu quase na mesma proporção.

Como vimos o monitoramento das métricas de software pode ser essencial para a manutenção da saúde de nosso código. Cabe a nós desenvolvedores, ou aos times que resolverem adotar esta prática, utilizarem com parcimônia. De nada adianta possuirmos um dashboard com diversas métricas se a maioria não faz sentido para o nosso caso. Também vale ressaltar que as medições devem servir como base para planos de ação, caso contrário se tornam apenas números. Para começar, escolha de 3 a 5 métricas e ataque os pontos críticos, com o tempo você pode adotar outras, mas sempre visando a melhoria continua e consequentemente a qualidade de seu código.

Anatomia de uma Mensagem de Erro (ou de Alerta)

Thiago Esser, Designer

Elas são necessárias, mas nem sempre tão espertas ou simpáticas quando a gente gostaria. São aquelas mensagenzinhas que volta e meia aparecem quando estamos preenchendo um formulário na web, ou quando estamos usando um aplicativo no smartphone.

Guia pro designer ou desenvolvedor

Abaixo, compartilho um pequeno guia pra escrever esse tipo de mensagem, o que, pela minha experiência, não é uma tarefa que se faz com as mãos nas costas.

  1. Informe o que aconteceu?
    Tip: Você não está tratando com idiotas e, muito provavelmente, não está falando com especialistas.
  2. Diga o que pode serfeito?
    Tip: A sua meta é sempre resolver o problema ali na hora.
  3. Ese, mesmo assim, o problema continuar?
    Tip: Vá até o fim, afinal de contas, o problema também é seu.

20130701-125314.jpg

[Update de 03/07/2013] Para revisar, além dessa estrutura básica, você pode pedir pra alguém olhar e avaliar esses quesitos:

  • O português está…

Ver o post original 133 mais palavras

Design Thinking Dojo na uMov.me

Num Dojo com mais conversa do que qualquer outra coisa, discutimos a abordagem do design thinking e de como podemos usá-la no nosso dia-a-dia. Em qualquer profissão, mas especialmente no desenvolvimento de software, para:

  • Validarmos pensamentos/idéias, transformando-as em algo visual
  • Gerando um entendimento compartilhado do que estamos discutindo
  • Fazendo perguntas que tragam à tona o sentido daquilo que produzimos
  • Repetindo esse processo sempre que necessário, levando-o na nossa “caixa de ferramentas” (toolbox)

Abaixo, a apresentação que guiou o nosso papo sobre o tema.

Escalando Horizontalmente – AWS Auto Scaling – Parte#1

Finalmente depois de alguns aprendizados e experiências chegou a hora de compartilharmos um pouco sobre Amazon Web Services. Vamos então falar sobre  escalar de forma horizontal utilizando o serviço Auto Scaling da AWS. Para aqueles que não conhecem o AWS Auto Scaling indico fortemente dar uma boa leitura na vasta documentação do serviço que aborda desde conceitos básicos de utilização até mesmo referencias da API.

Outra dica também é assistir a palestra realizada no uMov.Me Labs Summit realizado em Abril 🙂

Para interagirmos com os serviços web services da Amazon relacionados a política de Auto Scaling podemos escolher basicamente entre:

  • SDK – Utilizando a API de desenvolvimento da AWS disponível hoje para as principais linguagens de programação como Java, .Net, Ruby, PHP, Node.JS e também plataformas móveis como Android, iOS. Através da API de desenvolvimento é possível interagir diretamente com os web services da Amazon, manipulando grande parte dos serviços oferecidos via console de gerenciamento.
  • Command Line Tools – Grande amigo dos SysAdmins, o Command Line Tools, veio para facilitar a interação com os principais serviços disponíveis pela AWS, onde sem precisar desenvolver nenhuma linha de código ou instanciar nem objeto é possível gerenciar sua infraestrutura usando apenas o terminal.

Neste primeiro exemplo iremos adotar o Command Line Tools como ferramenta para criarmos uma política de auto scaling. Nesta abordagem iremos fazer com que nossa infraestrutura esteja preparada para escalar de forma horizontal. É possível utilizando o serviço Auto Scaling prever períodos de grande utilização de uma determinada aplicação ou serviço, mas também simplesmente reduzir o número de instancias durante os períodos de inatividade das mesmas, impactando diretamente assim nos custos com infraestrutura.

Através de alguns poucos passos utilizando o Command Line Tools você poderá obter significativa redução no seu bolso ao final do mês. Então chega de bla bla bla e vamos ao que interessa: Setup:

  1. Para iniciar realize o download da ferramenta Command Line Tools de Auto Scaling;
  2. Uma vez descompactado o arquivo, será criada a pasta ‘AutoScaling-xxx’. Iremos seguir os passos descritos na seção “Installation” do arquivo README.TXT situado dentro da pasta descompactada, setando assim todas as variáveis de ambiente necessárias para rodarmos os scripts;
  3. Agora é a vez de obter suas chaves de segurança da AWS para conseguirmos interagir com a API da AWS. Para obter as suas credenciais basta acessar as configurações da sua conta e obter as duas chaves(Chave de acesso, Chave de acesso secreta).
  4. Com as chaves em mãos, basta seguir a seção “Using AWS Keys” do arquivo README.TXT situado dentro da pasta descompactada.
  5. Para ter certeza de que tudo está funcionando corretamente digite no terminal o comando “as-cmd”. Se todos os passos foram seguidos corretamente você verá uma lista com os comando disponíveis da ferramente de auto scaling via Command Line Tools.
  6. Dúvidas?

Escalando:

  1. O primeiro passo a ser realizado basicamente irá identificar qual AMI(Amazon Machine Images) servirá de base para criar novas VMs quando necessário. Para isso basta executar o comando abaixo:  
    as-create-launch-config my_config --image-id ami-xxxxxxxx --instance-type m1.micro
  2. Uma vez criada a configuração de inicialização de novas VMs, precisamos informar agora através da criação de um novo grupo de auto scaling em quais zonas estas VMs devem ser criadas. Algumas outras informações importantes são número mínimo e máximo de VMs bem como para qual ELB(Elastic Load Balancer) estas VMs devem ser atribuídas. Crie um novo grupo executando:
    as-create-auto-scaling-group my_as_group --launch-configuration my_config --availability-zones us-east-1a us-east-1b --min-size 2 --max-size 20 --load-balancers MyLB
  3. Para que possamos iniciar uma nova VM e desta forma escalar horizontalmente é necessário a criação de políticas de auto scaling. Desta forma criaremos uma política para adicionar novas VMs respondendo ao load balancer associado. Para isso precisamos executar o comando:
    as-put-scaling-policy scale_up --auto-scaling-group my_as_group --adjustment=1 --type ChangeInCapacity --cooldown 300
  4. Uma vez incrementado o número de VMs e satisfeito o aumento na demanda das aplicações, você também pode ter uma política de auto scaling para desligar VMs uma vez identificado baixo tráfego de requisições através do ELB em questão. Semelhantemente ao passo 3 iremos criar uma nova política, porém agora estaremos subtraindo uma VM de modo a economizar recursos não utilizadas executando o comando:
    as-put-scaling-policy scale_down --auto-scaling-group my_as_group --adjustment=-1 --type ChangeInCapacity  --cooldown 300

    Você ainda pode resolver diminuir o número de VMs após o horário comercial onde o volume de acessos diminui consideravelmente e através do monitoramento de memória ou CPU indicam inatividade de algumas VMs. Mas este é um assunto para o próximo post, AWS Auto Scaling – Parte#2 🙂

  5. Vamos testar? Uma vez que não atrelamos nenhuma rotina de monitoramento onde poderíamos criar e remover instancias automáticamente, podemos criar e remover instancias manualmente através do comando “as-execute-policy“.
  • Baseado na política para criar VMs podemos executa-la assim:
    as-execute-policy --name scale_up --auto-scaling-group my_as_group
  • Baseado na política para remover VMs podemos executa-la assim:
    as-execute-policy --name scale_down --auto-scaling-group my_as_group

Desta forma temos uma primeira política de auto scaling! Em um próximo post estaremos explicando como automatizar a criação e remoção de VMs utilizando o serviço AWS CloudWatch. #ficadica

Boot2Gecko (FirefoxOS) o novo sistema operacional para smartphones

Seguindo a tendência do uso de dispositivos móveis, a Mozilla também pretende ocupar uma fatia deste mercado com o lançamento de seu sistema operacional para dispositivos móveis.

Utilizando inicialmente um codinome boot2gecko, o FirefoxOS está trazendo mais uma opção para bater de frente com os gigantes atuais Android, iOS e Windows Phone, para ser vendido junto aos atuais smartphones.

Um ponto muito interessante que está embalando a comunidade é o fato que seus aplicativos serão desenvolvidos todos utilizando puramente HTML, CSS e JavaScript. Potencializando assim a comunidade de desenvolvedores e agregando profissionais que hoje trabalham para o desenvolvimento web e não precisarão aprender uma nova tecnologia em relação a seus concorrentes.

Você pode saber mais sobre o projeto aqui: http://www.mozilla.org/en-US/b2g/

É possível também acompanhar a evolução do projeto por sua conta no github: https://github.com/mozilla-b2g

E este é o projeto que contém sua parte de interface com todos os seus aplicativos iniciais: https://github.com/mozilla-b2g/gaia

A Mozilla anunciou que pretende lançar este sistema primeiro “pasmem” no Brasil. Se por motivos de mercado ou estratégia da empresa não sabemos, mas podemos ficar felizes brasileiros por sermos os primeiros a colocar as mãos nele.

Enquanto não temos suporte oficial em nenhum aparelho, podemos ver como ele está ficando rodando ele emulado em seu sistema operacional. Algumas dicas de como fazer isso aqui: https://wiki.mozilla.org/Gaia/Hacking

Abaixo alguns screenshots que tirei realizando uma breve exploração do sistema.

Screen_shot_2012-08-16_at_12Screen_shot_2012-08-16_at_12Screen_shot_2012-08-16_at_12Screen_shot_2012-08-16_at_12Screen_shot_2012-08-16_at_12Screen_shot_2012-08-16_at_12

 

E você, acredita que ele vem para fazer frente ?