Entendendo orientação a objetos, parte 1
Posted by Paulo Canedo in Java, TI on 25 de agosto de 2009
Hoje venho iniciar uma série para demonstrar o conceito de orientação a objetos dentro do mundo da programação. A POO (Programação Orientada a Objetos) foi implementanda a fim de suprir algumas deficiências do principal modelo anterior, a programação estruturada. Atualmente temos as linguagens C++ e Java como sendo as mais conhecidas no mundo da POO, entre outras que estão ganhando cada vez mais força, como python, ruby e scala, por exemplo, neste artigo teremos uma pequena direcionalização ao Java, porém todos os conceitos aqui apresentados podem ser facilmente adaptados a qualquer linguagem de programação que utilize POO.
Para começarmos com o conceito de POO vamos fazer uma pequena analogia entre programação estruturada e POO, na programação estruturada criamos nossos algoritmos no estilo “passos para executar uma receita de bolo”, você descreve passo a passo todas as operações que devem ser realizadas até que o bolo esteja pronto, já no estilo POO nós temos um paradigma um pouco mais completo, ainda considerando o exemplo do bolo, na POO teríamos um conjunto de objetos que podem ou não ter uma capacidade de executar tarefas, e com a reunião de todos os objetos conseguiríamos preparar o bolo.
A primeira coisa a qual precisa ser desmistificada na POO é o conceito de classe. Explicando da forma mais simples possível uma classe é um conjunto de atributos e métodos, mas o que são atributos e métodos? Os atributos de uma classe são as características que esta pode assumir, suas personificações. Os métodos são semelhantes às funções comuns que estamos acostumados na programação estruturada, com a diferença que os métodos são funções particulares de cada classe, ou seja, um método é uma operação que determinada classe é capaz de executar.
Vamos pensar em exemplos para facilitar o compreendimento do que é uma classe. Podemos assumir no mundo da POO que uma pessoa é uma classe, se uma pessoa é uma classe e que esta classe tem alguma utilidade então esta deve possuir pelo menos um atributo ou um método, vamos analisar o que pode ser atributo e o que pode ser método na classe pessoa. Vamos pensar, quais são as caraterísticas de uma pessoa? Tente descrever as características de você mesmo: meio alto, magro, cabelos pretos, inteligente, rápido, todas estas características são consideradas atributos de uma pessoa, então temos, neste caso, que pessoa é uma classe, e se esta pessoa possui as características descritas anteriormente podemos assumir que estas características são os atributos da classe pessoa. E o que seria os métodos de uma classe? Um método seria a capacidade que esta classe tem de interagir com o seu ambiente. Voltamos a classe pessoa, quais seriam as capacidades de uma pessoa interagir com o seu ambiente? Falar, andar, pular, gesticular, etc.
OBS.: Em geral, os métodos são as ações de uma classe, ou seja, métodos no mundo da gramática são os verbos, por exemplo: conversar, andar, pular, tocar, etc. Os atributos poderiam ser considerados os adjetivos, por exemplo: feio, fraco, chato, lerdo, etc.
É muito importante conseguir identificiar o que pode ser uma classe e conseqüentemente seus atributos e seus métodos. Um exercício muito indicado é procurar “coisas” na natureza e fazê-las como classe, a partir daí identificar seus atributos, exemplo: Caixa de som, animal, carro, árvore, computador, etc.
Acesso simples e rápido às linhas de uma query
Posted by Paulo Canedo in Java, banco de dados on 31 de julho de 2009
Abaixo segue duas classes para encapsular e facilitar o acesso a banco de dados via JDBC, a classe DBQuery encapsula uma query onde a mesma é capaz de gerar um iterator para navegação nas linhas da consulta de forma rápida, leve e eficiente.
O iterator é implementado de uma forma em que ele não guarde os dados da consulta em memória, possibilitando o uso dessa classe para queries que retornem muitas linhas de resultado.
Outra coisa interessante é a possibilidade de se trabalhar com genéricos, caso sua consulta ao banco retorne um tipo homogêneo de dados (por exemplo, todos os campos sejam do tipo String).
classe DBQuery.java
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * * @author Paulo Canedo C Rodrigues */ public class DBQuery<T> implements Iterable<T> { private Connection connection; private String query; public DBQuery(Connection connection, String query) { this.connection = connection; this.query = query; } public Iterator<T> iterator() { try { Statement stm = connection.createStatement(); ResultSet rs = stm.executeQuery(query); return new DBRowIterator(rs); } catch (SQLException ex) { return null; } } } |
classe DBRowIterator.java
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /** * * @author Paulo Canedo C Rodrigues */ public class DBRowIterator<T> implements Iterator<Map<String, T>> { private ResultSet rs; private Map<String, T> rowFields = new HashMap<String, T>() { //Sobrescrita do metodo get do mapa para transformar o get em case insensitive @Override public T get(Object key) { return super.get(((String) key).toUpperCase()); } }; private String[] columnsName; private boolean objectReaded = false; private int columnCount; DBRowIterator(ResultSet rs) throws SQLException { this.rs = rs; columnCount = rs.getMetaData().getColumnCount(); columnsName = new String[columnCount]; for (int i = 0; i < columnCount; i++) { columnsName[i] = rs.getMetaData().getColumnName(i + 1).toUpperCase(); } } public boolean hasNext() { if (objectReaded == false && rowFields.size() != 0) { return true; } try { boolean flag = rs.next(); if (flag = true) { rowFields.clear(); for (int i = 0; i < columnCount; i++) { Object o = rs.getObject(i + 1); rowFields.put(columnsName[i], (T) o); } } else { if (rowFields != null) { try { rs.getStatement().close(); rs.close(); } catch (Exception ex) { } } rowFields = null; } return flag; } catch (Exception ex) { } return false; } public Map<String, T> next() { objectReaded = true; return rowFields; } public void remove() { } } |
Abaixo segue dois exemplos de utilização, por favor, deixem comentário sobre o que achou das classes e da ideia.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | java.sql.Connection connection = null; //Exemplo 1 com genérico sem casting - apenas para tipo de dados homogêneos DBQuery dbQuery1 = new DBQuery(connection, "SELECT nome, sobrenome, endereco FROM tb_agenda ORDER BY nome"); for (Iterator<Map<String, String>> it = dbQuery1.iterator(); it.hasNext();) { Map<String, String> linhaDaConsulta = it.next(); String nome = linhaDaConsulta.get("nome"); //nome do campo da consulta: case insensitive String sobrenome = linhaDaConsulta.get("sobrenome"); String endereco = linhaDaConsulta.get("endereco"); System.out.println(String.format("Nome: %s; Sobrenome: %s; Endereço: %s", nome, sobrenome, endereco)); } //Exemplo 2 sem genérico com casting DBQuery dbQuery2 = new DBQuery(connection, "SELECT nome, idade, peso FROM tb_pessoa ORDER BY nome"); for (Iterator<Map<String, Object>> it = dbQuery2.iterator(); it.hasNext();) { Map<String, Object> linhaDaConsulta = it.next(); String nome = (String) linhaDaConsulta.get("nome"); Integer idade = (Integer) linhaDaConsulta.get("idade"); Float peso = (Float) linhaDaConsulta.get("peso"); System.out.println(String.format("Nome: %s; Idade: %d; Peso: %.2f", nome, idade, peso)); } |
Comentários