Início > programação > Você é realmente um bom desenvolvedor Java?

Você é realmente um bom desenvolvedor Java?

Para ser um bom desenvolvedor Java é preciso, acima de tudo, ter experiência. Em geral, os anos de mercado levam a boas práticas que fazem com que o código seja mais limpo, fácil de dar manutenção e mais simples de entender. No entanto, nem sempre isso é verdade. Estou acostumado a ver código de pessoas com muito tempo de programação que não possui uma boa estruturação e com erros básicos como, por exemplo, a criação de classes com baixa coesão.

Nesse post mostro algumas técnicas que você deve aprender (e algumas falhas que precisa evitar) para que suas aplicações sigam bons princípios e aproveitem ao máximo os recursos nativos que o Java pode te oferecer (não abordo recursos de frameworks ou bibliotecas). Todas as dicas estão relacionados a aspectos técnicos da linguagem, portanto não me prendi a outros fatores, como uso de recursos de IDE’s ou metodologias de desenvolvimento. Vamos a elas:

  1. Strings

O erro mais comum cometido por programadores que estão começando é a criação desenfreada de Strings. Em Java o objeto String é imutável, o que significa que uma vez criado, não pode ser modificado. Portanto, não cometa erros como o de abaixo, em que vários objetos são criados para gerar uma grande String com letras de ‘a’ a ‘j’, consumindo recursos de memória que poderiam estar livres. Observação: a partir do Java 1.6, a concatenação de Strings passou a ser feita através de StringBuilder de forma automática pelo Java, porém um novo objeto StringBuilder é criado e o método append() é chamado a cada concatenação, levando também a um grande desperdício de memória. Assim, use sempre StringBuffer ou StringBuilder quando for efetuar concatenações de Strings.

String todasAsLetras = "a";

// a cada iteração, um novo objeto String é criado
for(char letraAtual='b'; letraAtual<='j'; letraAtual++) {
   todasAsLetras = todasAsLetras + "-" + letraAtual;
}

System.out.println(todasAsLetras); // imprime a-b-c-d-e-f-g-h-i-j

Solução: use a classe StringBuffer ou StringBuilder.

  1. Operadores

A utilização de operador ternário deixa seu código menor e mais legível. Exemplo:

int numeroDePosts = 3;

String status = (numeroDePost<4) ? "número baixo de posts" : "bom número de posts";

System.out.println("O status de publicações desse blog é: " + status);

Sempre que puder, use os operadores pré e pós fixados, pois garantem uma melhor legibilidade e, em algumas situações, podem apresentar um ganho de desempenho. Exemplo:

int valorInicial = 1;
valorInicial = valorInicial + 1; // podemos melhorar essa instrução
valorInicial += 1; // ficou melhor, mas pode ser mais eficiente
valorInicial++; // código mais limpo
  1. Interfaces e Classes Abstratas

Saiba distinguir uma da outra e quando usar a opção correta (ou as duas, se for o caso). Interfaces estão ligadas a comportamento, enquanto classes abstratas à implementação. Java não possui herança múltipla, mas permite que mais de uma interface seja implementada por uma classe. As duas, entretanto, têm um papel fundamental no polimorfismo, assunto importante e comentado a seguir.

  1. Herança e Polimorfismo

Mais do que saber usar herança, você precisa compreender a visibilidade de atributos e métodos entre classes, de acordo com os modificadores de acesso (publicprivatedefault ou protected). Entenda também a diferença entre sobrecarga e sobrescrita e como fazer bom uso do polimorfismo. O exemplo abaixo ilustra o uso de polimorfismo, de interface e de classe abstrata:

public abstract class Pessoa {
   public abstract void anda();
}
public interface Jogador {
   public void joga();
}
class JogadorDeFutebol extends Pessoa implements Jogador {
   public void anda() {
      System.out.println("andando");
   }
   public void joga() {
      System.out.println("jogando");
   }
   public static void main(String[] args) {
      JogadorDeFutebol jogadorDeFutebol = new JogadorDeFutebol();
      Object objeto = jogadorDeFutebol; // Sem problemas. JogadorDeFutebol é um Object.
      Jogador jogador = jogadorDeFutebol; // Sem problemas. JogadorDeFutebol implementa Jogador.
      Pessoa pessoa = jogadorDeFutebol; // Sem problemas. JogadorDeFutebol é uma Pessoa.
   }
}
  1. Encapsulamento, Baixo Acoplamento e Alta Coesão

Como um bom desenvolvedor Java, você sabe que precisa criar um código enxuto, fácil de manter e fácil de estender, correto? Então, tenha especial atenção com três conceitos básicos: encapsulamento, acoplamento e coesão.

  • encapsulamento é a técnica de esconder os atributos internos de uma classe através de modificadores de acesso (normalmente private). O acesso aos valores desses atributos é geralmente feito mediante o uso de métodos set e get. O objetivo é proteger os atributos de um acesso indevido, escondendo os detalhes internos para o usuário. O blog da Caelum tem um bom post falando sobre o assunto;
  • Um código com baixo acoplamento é aquele em uma classe A não sabe e não depende da forma como a classe B implementa uma certa solução. Ela é muito importante, pois uma mudança no código da classe B pode ter um enorme impacto no da classe A;
  • coesão é um conceito que indica que uma classe possui um único e bem definido propósito. Quanto mais alta for a coesão de uma classe, mais fácil será para dar manutenção nela.
  1. Generics

Você sabe usar Generics? Este é um conceito muito importante em Java, pois deixa o código mais robusto, organizado e evita os erros comuns encontrados em tempo de compilação que aconteciam antes. Veja se você entende o código abaixo:

abstract class Animal {
   String nome;
}
class Cachorro extends Animal {
   public Cachorro(String nome) {
      super.nome = nome;
   }

   public void late() {
      System.out.println("late");
   }
}

public class TesteGenerics {

   private List<? super Cachorro> animais = new ArrayList();

   public void adicionaAnimal(Animal animal) {
      animais.add((Cachorro) animal);
   }

   public <T extends Animal> Animal retornaAnimal(int posicao) {
      return (Animal) animais.get(posicao);
   }
}

E tipos parametrizados, você sabe usar? Eles podem ser bastante úteis, principalmente quando se usa frameworks ORM, como o Hibernate. Observe o código abaixo:

public class TesteGenerics<T, X> {
   private T primeiro;
   private X segundo;

   public TesteGenerics(T primeiro, X segundo) {
      this.primeiro = primeiro;
      this.segundo = segundo;
   }

   public T getT() {
      return primeiro;
   }

   public X getX() {
      return segundo;
   }

   public static void main(String[] args) {
      TesteGenerics<String, Integer> teste = new TesteGenerics<String, Integer>("string 1", 10);
      String primeiroValor = teste.getT(); // retorna String
      int segundoValor = teste.getX(); // retorna Integer e faz o unboxing para int
   }
}
  1. Reflexão

Imagine que você implementou um framework genérico que se comunicará com classes desconhecidas implementas em vários projetos. Como chamar métodos dessas classes, sem conhecê-las? Para esses casos existe reflexão. Você sabe usá-la? Veja o exemplo abaixo:

public class Calculadora {
   private String versao = "1.0";

   public double pi(){
      return Math.PI;
   }

   public static String nomeClasse(){
      return "Calculadora";
   }

   public int soma(int a, int b){
      return a+b;
   }
}

public class TesteReflexao {

   public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
      String stringNomeClasse = "Calculadora";
      String stringNomeMetodo = "pi";
      String stringNomeSoma = "soma";

      // carrega a classe
      Class<?> classeGenerica = Class.forName(stringNomeClasse);
      // instancia um objeto Calculadora
      Object objeto = classeGenerica.newInstance();

      // retorna o método pi da classe Calculadora
      Method metodoPI = classeGenerica.getMethod(stringNomeMetodo);
      // invoca o método pi do objeto instanciado
      System.out.println(metodoPI.invoke(objeto).toString());

      // retorna o método soma da classe Calculadora, informando que possui dois parâmetros int
      Method soma = classeGenerica.getMethod(stringNomeSoma, int.class, int.class);
      // chama o método soma passando parâmetros
      System.out.println(soma.invoke(objeto,5,10));

   }
}

Agora imagine que você quer setar um certo valor em um atributo de instância privado que não possui um método set. Tem saída para essa situação? Sim. Veja o exemplo abaixo:

public class TesteReflexao2 {
   public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {

      // invocar um método de uma classe a partir da String do seu nome
      String stringNomeClasse = "Calculadora";

      // carrega a classe
      Class<?> classeGenerica = Class.forName(stringNomeClasse);
      // instancia um objeto Calculadora
      Object objeto = classeGenerica.newInstance();

      // pega o atributo privado de instância "versão"
      Field campoPrivado = objeto.getClass().getDeclaredField("versao");
      // torna o atributo acessível, pois é privado
      campoPrivado.setAccessible(true);
      // seta o valor 1.1 (antes era 1.0)
      campoPrivado.set(objeto, "1.1");
      // exibe o novo valor 1.1
      System.out.println(campoPrivado.get(objeto).toString());
   }
}
  1. Classes Internas

Embora sejam odiadas por alguns, as classes internas (inner classes) podem ser bastante úteis em determinados casos. Elas são largamente utilizadas  para tratamento de eventos em Java e existem quatro tipos: classes internas regulares, classes internas locais de método, classes internas anônimas e classes aninhadas estáticas (embora essas últimas não sejam conceitualmente classes internas).

Vamos ao exemplo de uma classe interna regular:


class MinhaClasseExterna {
   private int x = 7;

   public void criarClasseInternaAPartirDaClasseExterna() {
      MinhaClasseInterna interna = new MinhaClasseInterna(); // instancia classe interna a partir de um método da externa
      interna.mostraValorVariavelClasseExterna();
   }

   // definindo classe interna regular
   class MinhaClasseInterna {
      public void mostraValorVariavelClasseExterna() {
         System.out.println("Valor de x na classe externa é: " + x);
      }

      public void exibeFormasDeReferenciarClasses() {
         System.out.println("Referência para a classe interna: " + this);
         System.out.println("Referência para a classe externa: " + MinhaClasseExterna.this);
      }
   }

   public static void main(String[] args) {
      MinhaClasseExterna externa = new MinhaClasseExterna();
      // instanciando classe interna a partir de um método da classe externa
      externa.criarClasseInternaAPartirDaClasseExterna();

      // instanciando classe interna a partir de uma instância da classe externa
      MinhaClasseInterna interna = externa.new MinhaClasseInterna();
      interna.mostraValorVariavelClasseExterna();

      interna.exibeFormasDeReferenciarClasses();
   }
}

Agora o exemplo de uma classe interna de método:


class MinhaClasseExterna {
   private int x = 15;

   void testaClasseInternaDeMetodo() {
      final String z = "variável local de método";

      // definindo classe interna de método
      class MinhaClasseInternaDeMetodo {
         public void mostraDadosExternos() {
            System.out.println("Valor de x da classe externa é: " + x);
            System.out.println("Valor de z do método é: " + z); // se z não for final não compila
         }
      }

      MinhaClasseInternaDeMetodo internaMetodo = new MinhaClasseInternaDeMetodo();
      internaMetodo.mostraDadosExternos();
   }

   public static void main(String[] args) {
      MinhaClasseExterna externa = new MinhaClasseExterna();
      externa.testaClasseInternaDeMetodo();
   }
}

Vamos agora ao exemplo de uma classe interna anônima:


class Animal {
   public void anda() {
      System.out.println("anda");
   }
}

class Cachorro {
   // definindo classe interna anônima
   Animal a = new Animal() {
      public void late() {
         System.out.println("cachorro latindo");
      }

      public void anda() {
         System.out.println("anda");
      }
   };

   public void realiza() {
      a.anda(); // OK, Animal tem um método anda()
     // não posso chamar a.late() pois Animal não tem esse método
   }
}

Classe interna anônima também pode ser argumento de um método. A classe File tem um método que facilita bastante isso e é bastante útil para listar os arquivos de um diretório que obedeçam um determinado pattern. Veja o exemplo abaixo onde são listados os arquivos do diretório C:\imagens que terminem com a extensão jpg:


public File[] listaArquivos() {
   File[] imagensJpegDoDiretorio = new File("C:\\imagens").listFiles(
      new FileFilter() { // definindo classe interna anônima como argumento de método
         public boolean accept(File b){
            return b.getName().endsWith(".jpg");
         }
      }
   );

   return imagensJpegDoDiretorio;
}

Por fim, vamos ver o exemplo de uma classe aninhada estática:

class Externa1 {
   static class Aninhada1 {
      void escreve() {
         System.out.println("olá aninhada 1");
      }
   }
}
class Externa2 {
   static class Aninhada2 {
      void escreve2() {
         System.out.println("olá aninhada 2");
      }
   }

   public static void main(String[] args) {
      // pego instância da classe aninhada estática
      Externa1.Aninhada1 a = new Externa1.Aninhada1();
      a.escreve();

      // pego instância da classe aninhada estática
      Aninhada2 a2 = new Aninhada2();
      a2.escreve2();
   }
}
  1. Equals e Hashcode

O método equals() é extremamente importante na maioria das aplicações. Caso deixe de ser implementado, não poderemos usar o objeto como chave em um HashTable e, muito provavelmente, os Sets com esse objeto não funcionarão de forma correta. É imprescindível implementá-lo de forma correta. O equals() deve ter as seguintes características  (consulte aqui o javadoc):

  • Reflexivo: para qualquer referência não nula de x, x.equals(x) deve retornar verdadeiro;
  • Simétrico: para quaisquer referências não nulas de x e y, x.equals(y) deve retornar verdadeiro, se, e somente se, y.equals(x) retorna verdadeiro;
  • Transitivo: para quaisquer referências não nulas de x, y e z, se x.equals(y) retorna verdadeiro e y.equals(z) retorna verdadeiro, então x.equals(z) também deve retornar verdadeiro;
  • Consistente: para quaisquer referências não nulas de x e y, invocações múltiplas x.equals(y) devem retornar consistentemente verdadeiro ou falso;
  • x.equals(null) deve sempre retornar falso.

Veja o exemplo abaixo (coloquei alguns comentários para ficar mais fácil de entender):


public class Carro {

   private Integer id;
   private String placa;
   private String chassi;
   private String modelo;
   private String cor;

   // gets e sets omitidos

   @Override
   public boolean equals(Object obj) {
      if (this == obj) { // se apontam para o mesmo objeto, retorna true
         return true;
      }
      if (obj == null) { // se o objeto passado está nulo, retorna false
         return false;
      }
      if (getClass() != obj.getClass()) { // se são de classes diferentes, retorna false
          return false;
      }
      Carro other = (Carro) obj;
      if (id != other.id) { // se os id's são diferentes, retorna false
         return false;
      }

      return true; // retorna true quando os id's são iguais
   }
}

Da mesma forma, o método hashCode() é muito importante quando usamos coleções. As classes HashMap e HashSet, por exemplo, utilizam-no para definir como o objeto será armazenado internamente. Além disso, ele é essencial para a localização do objeto na coleção. Veja o contrato do método hashCode() (consulte aqui o JavaDoc):

  • Deve retornar sempre o mesmo valor para um mesmo objeto durante a execução de uma aplicação;
  • Se dois objetos são iguais de acordo com o método equals(), então eles devem retornar o mesmo valor para o método hashCode();
  • Não é obrigatório que, se dois objetos são diferentes de acordo com o método equals(), então eles podem retornar valores diferentes no hashCode(). Se isso for feito, as coleções que armazenam esses objetos serão mais eficientes.

Veja o exemplo abaixo de implementação do hashCode():


public class Carro {
   private Integer id;
   private String placa;
   private String chassi;
   private String modelo;
   private String cor;

   // gets e sets omitidos

   @Override
   public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + id;

      return result;
   }
}
  1. Padrões de Projeto

Como um bom desenvolvedor, é imprescindível que você conheça padrões de projeto. Alguns são bastante conhecidos, como o Singleton, o Facade e o Observer, mas existem muitos outros que podem ser bastante úteis. Se você quer desenvolver bem em Java, aprenda boa parte deles. O livro Design Patterns com Java: Projeto orientado a objetos guiado por padrões é um bom começo.

Livro Design Patterns

Livro Design Patterns

Use a Cabeça! Padrões de Projetos também é uma boa pedida. A série Use a Cabeça é bastante didática, o que facilita o entendimento.

Livro Use a Cabeça! Padrões de Projetos

Livro Use a Cabeça! Padrões de Projetos

  1. Tratamento de exceções

Você sabe quando deve criar suas próprias exceções? Conhece a diferença entre uma Checked Exception e uma Unchecked Exception? Sabe definir corretamente o trecho do try e do catch e, principalmente, quando usar o finally? No Java 7, tivemos ainda uma novidade bastante relevante nesse assunto: o tratamento simultâneo de várias exceções. Veja o código abaixo em que duas unchecked exceptions são tratadas em um único catch:


public void processaNumeros() {
   int[] valores = {3,1,4,1,5,9,2};
   try {
      int posicao = Integer.parseInt("3");
      int valorPosicao3 = valores[posicao];

      System.out.println("Valor na posição 3 = " + valorPosicao3);
   } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
      e.printStackTrace();
   }
 }

  1. Ordenação em Arrays e Collections

Para saber como ordenar Arrays e Collections, estude sobre as interfaces Comparable, Comparator e os métodos sort das classes Collections e Arrays. Os exemplos abaixo mostram como ordenar um array e um ArrayList.


public void ordenaArray() {
   String[] cidadesDoInterior = {"Quixadá", "Amontada", "Baturité", "Beberibe", "Tauá"};

   // ordenando array
   Arrays.sort(cidadesDoInterior);
   System.out.print("após ordenação = ");
   for (String cidade : cidadesDoInterior) {
      System.out.print(cidade + " ");
   }
}

public void ordenaArrayList() {
   ArrayList listaDeInteiros = new ArrayList();
   listaDeInteiros.add(10);
   listaDeInteiros.add(51);
   listaDeInteiros.add(4);
   listaDeInteiros.add(12);
   listaDeInteiros.add(25);

   System.out.println("não ordenado " + listaDeInteiros);
   // ordenando arraylist
   Collections.sort(listaDeInteiros);
   System.out.println("após ordenação " + listaDeInteiros);
}
  1. Coleções

Um bom desenvolvedor Java deve conhecer bem as classes que envolvem coleções. Você sabe a diferença, por exemplo, entre um HashMap e um LinkedHashMap? E as consequências de se mudar a forma de armazenar a lista de objetos no seu projeto de ArrayList para HashSet, saberia dizer quais seriam? A figura a seguir mostra a hierarquia de classes para coleções no Java.

Hierarquia de Classes de Collections

Hierarquia de Classes de Collections. Fonte: Sierra, K.; Bates, B. (2008)

  1. Thread e Runnable

Em Java, thread tem dois significados:

  • Uma instância da classe java.lang.Thread;
  • Uma thread de execução.

Se você deseja executar tarefas em paralelo no Java, é às classes Thread e Runnable que vai recorrer. Para isso existem duas opções: implementar a interface Runnable ou estender a classe Thread. O código abaixo mostra um exemplo de criação de 2 threads utilizando uma classe que estende Thread.

class MinhaThread extends Thread {
   int id;

   public MinhaThread(int id) {
      this.id = id;
   }

   public void run() {
      for (int x = 1; x < 6; x++) {
         System.out.println("rodando thread com o id = " + id);
      }
   }
}

public class TestThreads {
   public static void main(String[] args) {
      MinhaThread t1 = new MinhaThread(1);
      MinhaThread t2 = new MinhaThread(2);
      t1.start();
      t2.start();
   }
}
  1. Expressões Regulares

Por fim, aprenda o uso de expressão regulares. O uso delas pode facilitar – e muito – o seu trabalho na validação/conversão de dados digitados pelo usuário, ajudar na pesquisa de certos valores em arquivos, entre outras funções bastante úteis. O exemplo abaixo mostra como validar um e-mail:


public static void main(String[] args) {
   String email = "teste@teste.com";
   Pattern padrao = Pattern.compile(".+@.+\\.[a-z]+");
   Matcher m = padrao.matcher(email);

   if (m.matches()) {
      System.out.println("O email " + email + " é valido!");
   } else {
      System.out.println("O email " + email + " nao é valido!");
   }
}

Conclusão

Para ser um bom desenvolver em Java é preciso, necessariamente, ter alguns anos de experiência. Seguir boas práticas e manter uma boa organização no projeto são também dois passos importantes para facilitar o entendimento e manutenção do código. Entretanto, saber evitar pequenos problemas e conhecer recursos importantes da linguagem ajudam consideravelmente. Esse post mostrou algumas das técnicas que você deve conhecer para que seja reconhecidamente um desenvolvedor diferenciado e saiba utilizar todo o poder que a linguagem pode fornecer.

Bibliografia Consultada

ANICHE, M. Revisitando a Orientação a Objetos: encapsulamento no Java. 2012. Disponível em http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsulamento-no-java/

CAELUM – ENSINO E INOVAÇÃO. Java e Orientação a Objetos. Disponível em http://www.caelum.com.br/apostilas/

K19 TREINAMENTOS. Orientação a Objetos em Java. 2013. Disponível em http://www.k19.com.br/downloads/apostilas/java/k19-k11-orientacao-a-objetos-em-java

NUNES, L. Novidades do Java 7. 2010. Disponível em http://www.slideshare.net/LeandroNunes85/novidades-do-java7

SIERRA, K.; BATES, B. SCJP Sun Certified Programmer for Java 6 Study Guide. New York: McGraw-Hill, 2008.

Anúncios
  1. 02/07/2013 às 00:20

    Parabéns Pablo, muito bacana!!

  2. 02/07/2013 às 08:42

    Oi, Pablo, post bem interessante e completo. Meio que um resumão dos tópicos que caem na prova de certificação ocjp6. Porém senti falta de uma coisa que muita dev se esquece: Passagem de parâmetros.

    Parabéns pelo post!
    Abs.

    • 02/07/2013 às 08:58

      Verdade, Henrique. Tem muita coisa da OCJP, mesmo. Tanto que o livro da Katy Sierra está nas referências bibliográficas. Apenas adicionei algumas coisas, como padrões de projetos. Porém, considero que os assuntos que caem na prova são importantíssimos para o dia-a-dia de um desenvolvedor Java. Se ele dominar tudo que está no livro vai ser um ótimo desenvolvedor.

  3. 02/07/2013 às 10:08

    Parabéns Pablo!

  4. Fernando
    03/07/2013 às 23:00

    Muito bom. Parabéns.

  5. 04/07/2013 às 08:41

    Excelente o post!

  6. 08/07/2013 às 10:30

    Parabéns ótimos post!

  7. 12/07/2013 às 15:25

    Muito bom!

  8. Rafael Meireles
    10/09/2013 às 23:10

    Se não me engano no Java 6 não precisa mais ter essa preocupação em não concatenar strings grandes, pois quando se usa string o byte code gerado é transformado para string builder.

    • 12/09/2013 às 22:14

      Você tem toda razão, Rafael Medeiros. Agora existem dois detalhes: 1) pode ser que você esteja mantendo um sistema legado e ele ainda use o Java 5. 2) se você usar a simples concatenação, o Java tem que fazer a conversão para StringBuilder por você, o que afeta um pouco a performance.

      Mas obrigado pela informação e boa sorte.

  9. Mauricio Lima
    11/11/2013 às 16:04

    Rafael Meireles e/ou Pablo Nóbrega poderiam passar o link da oracle onde confirma essa informação de que a String vira StringBuffer?

  10. Mauricio Lima
    12/11/2013 às 07:21

    Acho que houve uma interpretação errada da documentação. Ela diz que a String é alterada para uma StringBuffer, porém para cada concatenação é criada uma nova StringBuffer não é usada a mesa. Isso que dizer que essa história de ter mudado no java 6 não é verdade. A String ainda é imutável e sempre que precisar concatenar várias string deve-se usar StringBuffer/StringBuilder. Sempre!

    • 12/11/2013 às 09:51

      Maurício,

      Você tem razão. Fiz um teste aqui e realmente a cada concatenação é criado um novo objeto StringBuilder. Até já alterei o artigo. Só acho que a documentação não deixa isto claro.

      Abraço,

      Pablo.

  11. 26/11/2014 às 18:37

    OLÁ. ESTOU DESENVOLVENDO UM APP NO ECLIPSE PARA MEU RAMO DE TRABALHO, MAS ESTOU TENDO ERROS CONSTANTES. E PARA SIMPLIFICAR, GOSTARIA DE EXPLICAR PARA QUE ENTENDA.

    PARA SIMPLIFICAR, GOSTARIA QUE ME ESCREVE UM APP SIMPLES COM APENAS 3 CAMPOS.

    ASSIM FICARIA MAIS FÁCIL EU ENTENDER ONDE ESTOU ERRANDO.

    VOU LHE DAR A AMOSTRA DE COMO O SIMPLES PROGRAMA PARA EU ENTENDER O RESTO DA COISA.

    POR EXEMPLO:

    CRIAR UM APP APENAS COM 3 CAMPOS.

    PRIMEIRO CAMPO – PRODUTO

    SEGUNDO CAMPO VALOR DO PRODUTO

    TERCEIRO CAMPO – TOTAL – QUE SERIA A SOMA DE TUDO QUE FOSSE DIGITADO NO CAMPO VALOR DO PRODUTO.

    UM BOTÃO DE ADICONAR
    UM BOTÃO DE EXLUIR ou EDITAR
    UM BOTÃO DE SAIR.

    É COMO SE FOSSE UM CALCULADORA SIMPLES
    MAS VÃO CONSTAR APENAS O NOME DO PRODUTO, O VALOR E O TOTAL.

    ENTAO POR EXEMPLO, EU DIGITO –

    PRODUTO VALOR TOTAL
    ARROZ 10,00 E APARECE NO TOTAL 10,00
    FEIJÃO 15,00 E APARECE NO TOTAL 25,00
    CONTA SIMPLES MESMO.

    EU SÓ PRECISO ENTENDER ESSA PARTE, POIS NO MEU APP EM DESENVOLVIMENTO TEM OUTROS FATORES, COMO CALCULO DE %, DIVISAO, MÉDIA E AS COISAS BÁSICAS PARA UMA ANOTAÇÃO COM RESULTADO MAIS SOFISTICADO PARA O MEU TIPO DE TRABALHO.

    MAS SE PUDER ME PASSAR APENAS A SEQUENCIA DA CODIFICAÇÃO DE COMO FICARIA ESSE SIMPLES PROGRAMA, O RESTANTE FICARIA MAIS FÁCIL PARA EU ENTENDER ONDE ESTOU ERRANDO.

    JÁ PEDI PARA UNS 10 PROGRAMADORES EM JAVA OU ANDROID, MAS NINGUEM SE INTERESSOU EM AJUDAR. AGUARDO UM CONTATO CASO INTERESSE PARA VC ME AJUDAR COM ESSE PROBLEMA. NO MAIS. DESDE JÁ AGRADEÇO POR PELO MENOS TER O SEU ESPAÇO E PODER DEIXAR COM QUE A GENTE ENTRE EM CONTATO COM VC.

    BOA TARDE. ATENCIOSAMENTE RICK.

    • 27/11/2014 às 09:07

      Rick, você está desenvolvendo esta aplicação em que? Desktop? Web? Qual framework?

  1. No trackbacks yet.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: