domingo, 11 de novembro de 2012

Jdk 1.8 e projeto lambda

Vamos ao Java 8.

public class TestLambda {

    public interface Acceptor {
        public boolean accept(int num);
    }

    public static void main(String[] args){
        System.out.println("123");
        printNumbers( i -> i % 3 == 0);
    }

    public static void printNumbers(Acceptor acceptor){
        for(int i = 0; i < 10; i++)
            if (acceptor.accept(i))
                System.out.println("Accept " + i );
    }
}

Observe a linha 9.

printNumbers( i -> i % 3 == 0);

É a chamada expressão lambda. A leitura é funcional, na verdade é uma instancia da interface Acceptor sendo criada na hora da compilação. Costumo fazer a leitura desse tipo de código da seguinte forma: Para um i, de tal forma que i dividido por tres seja zero.

Para que esse código funcione será necessário que os parâmetros da expressão lambda sejam aderentes ao único método da interface Acceptor, que criamos para declarar a expectativa da função printNumbers.

O mais interessante desse código está no arquivo .class compilado. Os primeiros testes do projeto Lambda criava uma classe anonima para a expressão da linha nove mas as últimas verões já estão usando a nova instrução invokeDinamic, veja.

Compiled from "TestLambda.java"
public class TestLambda {
  public TestLambda();
    Code:
       0: aload_0       
       1: invokespecial #1                  
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  
       3: ldc           #3                  
       5: invokevirtual #4                  
       8: invokedynamic #5,  0              
      13: invokestatic  #6                  
      16: return        

  public static void printNumbers(TestLambda$Acceptor);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: bipush        10
       5: if_icmpge     49
       8: aload_0       
       9: iload_1       
      10: invokeinterface #7,  2 
      15: ifeq          43
      18: getstatic     #2            
      21: new           #8                  
      24: dup           
      25: invokespecial #9                  
      28: ldc           #10                  
      30: invokevirtual #11                 
      33: iload_1       
      34: invokevirtual #12                 
      37: invokevirtual #13                 
      40: invokevirtual #4                  
      43: iinc          1, 1
      46: goto          2
      49: return        
}

O código pode parecer que não muda muito, mas agora é possível alguma coisa funcional com java. Quando essa implementação estiver completa será possível fazer ordenação de lista de forma muito fácil, basta passar uma assinatura de método que implemente comparable com o exemplo de código a seguir.

listaDeClientes.sort( cliente -> cliente.getNome() );
// Ou uma passando a própria referencia 
// para o método que retorna um comparable.
listaDeClientes.sort( Cliente::getNome );
De uma olhada na página do JDK8 para baixar o preview ou na página do projeto lambda.

segunda-feira, 2 de julho de 2012

Pascal Estruturado

Encontrei um livro de Pascal Estruturado na casa dos meus pais dos tempos em que eu estava aprendendo a programar. Já estava a algum tempo com vontade de postar uma série de blogs do tipo "Desafio e Solução". Como dou aula de programação é uma oportunidade de testarmos os conhecimentos.

O livro supõe a solução em Pascal, uma linguagem procedural, mas os desafios são bem interessantes. Acredito que a solução pode ter várias "caras", mais orientadas a objeto ou mais procedural, vou tentar apresentar a solução de ambas as formas.

Segue o primeiro:

[ 1 Questão ]

Construir uma tabela de perda de carga em tubulações para vazões que variam de 0,1 a 10 litros/segundos, de 0,1 em 0,1, através da formula de Hanzen Williams dada a seguir:


J = Perda de Carga 
Q = Vazão(metros cúbicos/2)
D = Diâmetro do tubo( metros quadrados)
C = Coeficiente de rugosidade

Os valores de D e C devem ser lidos do teclado, deve terminar as contas quando for informado um D = 0.


quarta-feira, 26 de janeiro de 2011

Agile Archtecture

Acredito que todos concordamos que a arquitetura de um sistema é a principal responsável pela facilidade de manutenção corretiva e evolutiva, quanto melhor feito, mas fácil será para achar bugs, incrementar funcionalidades, etc. Por esse motivo é muito comum que seja gasto um tempo considerável na sua elaboração.

Já participei de desenvolvimento de sistemas em que as primeiras fazes do cronograma foram dedicados praticamente a arquitetura, mas como lidar com isso em ambientes de desenvolvimento ágil, entregando softwares funcionando logo nas primeiras iterações.

Alguns times falam do Sprint 0, nesse sprint a entrega serão praticamente poucos pontos, uma vez que a principal preocupação será na montagem das bases do sistema, escolha de frameworks e modelagem, e coisas de "infraestrutura". Acredito que essa abordagem seja muito interessante para times recém formados. Nesses times ainda é necessário formar o conhecimento comum base, ou seja, quais frameworks são normalmente utilizados nos projetos, como e onde são colocadas as classes e as camadas do sistema, etc. Para times que já estão a algum tempo juntos isso é mais natural, as coisas simplesmente fluem pela equipe.

Tenho experimentado uma abordagem Top-Down na arquitetura do sistema utilizando metodologias ágeis e acredito que está dando um bom resultado. Nessa abordagem, a arquitetura do sistema irá surgir conforme o sistema se desenvolve e não haverá a necessidade de um Sprint 0. Esse tipo de abordagem deve ser tomada com cuidado, integração continua e time fluente são alguns dos requisitos para dar certo.

Vamos explicar mais. Imagine a seguinte requisição:

  1. "Preciso listar o total das vendas por dia da semana em um determinado período."

 A primeira coisa que vem a cabeça é, pelo menos para mim: "vou precisar de um método que me traga todas as vendas em um determinado período". Apesar de correta a ideia, ela está errada. Quando a coisa é encarada por esse lado não estamos nos preocupando em realmente atender o que deve ser entregue, mas em como pegar os dados para atender o requisito.

Isso pode soar estranho, mas a primeira coisa a pensar é em como o dado deverá ser exibido porque isso pode mudar completamente a forma de recuperar as informações para apresenta-lo. O pensamento no momento do desenvolvimento deverá ocorrer de cima para baixo. Vamos supor que estamos construindo esse requisito para um sistema desktop swing, poderíamos começar assim:


public class JReport extends JPanel {
    public  JReport(Period period, Sales sales){
        for(PeriodEntry pEntry : period){
             JPeriodValue jpValue = new JReriodValue(sales.totalFor(pEntry));
             this.add(jpValue); 
        }
    }
}

Estamos nesse caso começando pela classe de apresentação. Note que nesse momento eu ainda não criei nenhuma classe das que declarei no modelo, a IDE irá adicionar um erro no lugar informando que ela ainda não existe. Mas imagine comigo, se quando você cria-las, fizer correto, esse código irá funcionar independente do que haja nas classes da qual ele depende. Já estamos modelando o sistema.

Com as IDEs modernas, basta um ou dois cliques que todas as dependências serão criadas, dai basta apenas preenche-las.

Iremos ver mais no próximo post.

sábado, 25 de setembro de 2010

A way to develop software

There are a sort of way to develop a computational system. Each one of then will let to a different place and it depends on the type of management are bean used. I'm particularly involved in some projects with a variety of development/management style.

There are a lot of companies doing outsourcing, this is good, it let you focus on your business and run a lot of things concurrently, but a project isn't just a delivery it's a live organism and you can't foreseen all you need in. It's very common to the outsider see the things in other ways, and you need to light all the way thought, but wen you find the good one, that who see as you see, you need to keep then.

Doing everything internally has it good and bad sides too, as outsourcing. The are the other things you must think, the system that is currently running, the bugs, the server crash, etc, but you can take advaced of the business knowledge you alread have.

To choose what way to go is sometimes difficult, you need to balance a lot of things to take that decision but a mix of the two is something very useful. 

sexta-feira, 10 de setembro de 2010

Metodologias ágeis

Estou a algum tempo coordemando alguns projetos e uma das minhas metas é executar um piloto de metodologias ágeis, alguns Sprints depois já conseguimos ver o horizonte.

Uma ponto muito importante na implantação de uma nova metodologia, principalmente a ágil, é preciso ter em mente que é um processo iterativo/evolutivo. Demora um pouco até entrar na rotina mas uma vez que entra é fácil se acostumar com a flexibilidade, agilidade e visibilidade na evolução do projeto.

Outra coisa ótima é o acompanhamento com os pontos das estórias e o gráfico de Burndown. Você consegue acompanhar dia a dia como está a sua previsão de entrega em relação ao que foi previsto, alem de criar um histórico de velocidade da equipe em relação ao tipo de projeto, plataforma, linguagem, etc, o que é um ótimo combustível para planejamentos de novos projetos. A pouco passamos por uma "estimativa" que utilizamos os dados históricos para prever o tempo de desenvolvimento.

Outra coisa que percebi, na prática, é que a équipe é um diferencial. Se você tiver a equipe engajada, o projeto chega lá. É preciso deixar claro os objetivos que se deseja alcançar na entrega e ter o cliente acessível para uma dúvida ou outra.

sexta-feira, 26 de fevereiro de 2010

Entropia de software


Esbarrei no termo esses dias lendo sobre "What Is Time? One Physicist Hunts for the Ultimate Theory", e achei muito interessante a definição. Nunca havia parado para realmente entender o termo, mas é incrível como está conectado sobre várias áreas do cotidiano, inclusive no trabalho de Analista de Sistemas.

Por definição entropia é uma função de não conservação de estado. Ou seja, pouca entropia define que o estado da coisa está pouco alterado, muida entropia define que o estado está bem alterado em relação ao estado inicial. Existe um ponto máximo de entropia, podemos defini-la como "pior que está não fica". Ou seja as coisas tendem para o caos e a desordem automaticamente, aumentam a entropia.

Um exemplo simples é quando deixamos um maço de folhas empilhados sobre a mesa e depois saimos, depois de uma semana, quando voltarmos, muito provavelmente o maço estará desorganizado.

Relacionando com desenvolvimento de softwares, quando começamos um projeto sabemos onde está tudo, o softwaer funciona e a coisa está organizada, dai então entra outro programador, outra equipe, os prazos apertam, etc, e a coisa começa a ficar um pouco mais confusa. Nesse momento estamos aumentando a entropia, as coisas começam a ficar mais desorganizadas ou não documentadas. Com a evolução do software e manutenções corretivas se atinge um estado de entropia máxima, e o sistema não suporta mais "novas funcionalidades" e sequer correções pequenas se tornam uma tortura. Esse é o ponto de reescrever o software ou o módulo.

sexta-feira, 5 de fevereiro de 2010

Seu grande inimigo




Li a frase "(...) and competing with no one but himself,(...) any issue that must be handled was solved first and foremost in a dialogue between him and himself(...)" e não consegui parar de pensar nela.

Parece uma coisas simples, mas perceber que você só tem um único inimigo e que esse inimigo é você mesmo lhe da um novo entendimento das coisas. Se lembra daquela promoção que não te deram mas a deram ao João, ou aquele carro que queria comprar mas acabou optando por um mais barato, ou aquele curso que queria fazer mas não tinha tempo. Quem lhe atrapalhou foi você mesmo, porque não se esforçou mais, porque não juntou dinheiro mais uns messes e porque não reservou um tempo.

Essa filisofia também é nova pra mim, estou aprendendo a encara-la.