quarta-feira, 4 de novembro de 2015

Diferença Entre Padrão de Projeto e Convenção

Faaaaaaaaaaaaaaaaaaaaaala minha galerinha! Bem, o motivo deste tema foi devido à uma conversa que tive com alguns amigos do trabalho. Nesta, ocorreu uma história na qual uma pessoa chegou até um deles e foi falar sobre Padrões de Projeto se referenciando ao seu código fonte, identação, comentários etc... Ops! não pera!

Isso mesmo, como puderam ver, as pessoas confundem as vezes sobre a diferença de duas coisas básicas: Padrão de Projeto e Convenção. Tendo em vista este contexto, vamos falar um pouco sobre os dois. Lets!

Regras e convenções de nomenclatura


Quando programamos em Java, devemos levar em consideração as convenções de nomenclatura para deixar nosso código o mais legível e documentável possível, pois um dos objetivos da programação orientada a objetos é o reaproveitamento do código.

É muito provável que quem não tenha experiência com programação sinta dificuldade de identificar todos os termos utilizados neste artigo, mas garantimos que tudo que será visto aqui será detalhado mais adiante, embora que este artigo se torna trivial a medida que programamos. 

Muitos compiladores como Eclipse e NetBeans dão um grande auxilio na hora de criarmos nosso projeto nos informando sobre as convenções de nomenclatura no momento que estamos criando os pacotes, classes, etc...


Nome de Classes


Por convenção, toda classe deve começar com uma letra maiúscula e, de preferência, não pode conter letras não ASCII (caracteres de língua de origem latina, como caracteres acentuados). Portanto, não é possível declarar uma classe com qualquer caracter especial (@, #, $, %, &, *, _, etc...) ou número.
Caso o nome de uma classe seja composto por mais de uma palavra, a primeira letra de cada palavra deve ser em maiúscula.

O nome da classe deve ser exatamente o mesmo nome de seu arquivo fonte ( .java ).

O nome da classe deve fazer referência total ao seu objeto (atributos e métodos contidos dentro da classe). Por exemplo: se tivermos uma classe com os atributos canal, volume e sintonia; e os métodos mudarCanal (), aumentarVolume () e diminuirVolume (); então, possivelmente chamaríamos esta classe de TV ou Televisao. Contudo, em uma classe que contivesse o atributo corDasPenas e o método voar () jamais chamaríamos de Pessoa (por que pessoas não tem penas e nem voam).

Exemplos de nomes de classes: Pessoa, ImpostoDeRenda, Conta, AgenciaDeEmprego, ...


Nome de Pacotes


Os pacotes devem começar com uma letra minúscula e podem usar letras não ASCII. Jamais poderemos iniciar o nome de um pacote com caracteres especiais (@, #, $, %, &, *, _, etc...) ou número.
Caso o nome de um pacote seja composto por mais de uma palavra, a primeira letra de cada palavra deve ser em maiúscula.

O nome do pacote deve ser o mesmo nome da pasta a qual ele se refere. Por exemplo, se os arquivos fonte estão na pasta criptografia, então o nome do pacote deve ser criptografia.

O nome do pacote deve fazer referência total às funções exercidas pelas classes dentro do pacote, pois pacotes servem basicamente para organizar os arquivos de código fonte de nosso projeto.

Exemplos de nomes de pacotes: criptografia, usuários, conexõesDeBancoDeDados , ...


Nome de atributos ou variáveis


Os atributos (variáveis) podem começar com qualquer letra e os caracteres $ ou _, porém não podem começar com números.

Caso o nome de um atributo (variável) seja composto por mais de uma palavra, a primeira letra de cada palavra deve ser em maiúscula.

Exemplos de nomes de atributos ou variáveis: x, y, resultado, valorDeX, valorDeY, ligado, ...


Nome de atributos finais ou constantes


Os atributos finais (constantes) devem ser escritos em letras maiúsculas.

Usamos underline (_) para separar nomes compostos de atributos finais (constantes).

Exemplos de nomes de atributos finais ou constantes: TAMANHO, PARAR_DE_EXECUTAR, ...

Bem, falamos um pouco dos tais patterns, agora vamos aos padrões.

Padrões de Projeto


Diariamente, inúmeros programadores em torno do mundo lidam com diversos problemas que “devem” ser resolvidos através de sua implementação em uma linguagem de programação. Na grande maioria das vezes essa mesma necessidade é exigida com demasiada rapidez e pouquíssimo prazo.

Para tanto, os profissionais desenvolvedores de linguagens que fazem uso do conceito de orientação a objetos criaram, a partir de tais necessidades, os Padrões de Projeto. Padrões de projeto são extremamente usados, questionados, reanalisados e exigidos por inúmeras empresas do ramo de Tecnologia da Informação (especialmente as que desenvolvem softwares - fábricas). O conceito é tão famoso que já foi usado para resolver problemas fora do ramo de TI, com estratégias de implementação atuante, uma vez que o modelo remete ao mundo real com exemplos de objetos agindo e sendo tais como no cotidiano do negócio envolvido.

Dentre tantos padrões existentes, alguns são muito famosos pela genialidade de sua criação enquanto outros deixam muitos usuários confusos quanto a como e onde usar e as suas diferenças em relação a outros padrões semelhantes. O DAO, por exemplo, é muito conhecido e usado no mundo de desenvolvimento de software em Orientação a Objetos, entretanto muitos confundem a real diferença entre este padrão e o padrão Repository.

Persistent Object - PO


Esse padrão é muito usado em conjunto com o framework de persistência ORM Hibernate. Representa apenas um objeto de persistência simples com atributos, métodos de recuperação e setagem, muito semelhante ao VO ou TO (Transfer Object), porém sem nenhuma referência a códigos de transação com o banco de dados.

Data Transfer Object - DTO


O próprio nome já diz muito: um objeto simples usado para transferir dados de um local a outro na aplicação, sem lógica de negócios em seus objetos e comumente associado à transferência de dados entre uma camada de visão (view layer) e outra de persistência dos dados (model layer). Muito frequentemente você verá esse padrão sendo usado em conjunto com um DAO. Veja na Figura 2 um exemplo claro dessa representação e desse conjunto entre os dois padrões.

Exemplo de união entre os padrões DTO e DAO
Figura 2: Exemplo de união entre os padrões DTO e DAO

Esse padrão também é bastante usado quando não se deseja expor a camada de persistência, porém é preciso que sejam exibidos os mesmos dados na camada de apresentação. Por exemplo, considere uma tela de uma aplicação que necessite listar os dados de 10 pessoas cadastradas em uma tabela. Para acessar estes dados, a camada de persistência assim o faz com a listagem configurada em um ArrayList de 10 PO’s (vide padrão acima). Para passar esses valores à tela, a mesma lista antes tem de ser convertida para uma lista de DTO’s com mesmos atributos e métodos get’s/set’s. Tudo isso porque a mesma aplicação faz uso do JPA, por exemplo, ou Hibernate e os mesmos frameworks não permitem que os dados tidos como “lazy (preguiçosos)” perdurem até depois de a conexão ter sido fechada. Por tal razão a conversão se faz necessária e assim os dados poderão fazer o trajeto sem serem perdidos ou sem que nenhum erro de conexão venha a acontecer.

Observação: os padrões de projeto também não devem ser usados em detrimento do ambiente onde se está executando o mesmo projeto, a ideia é que eles sejam abstratos o suficiente para se adaptar, porém você será o autor principal disso, então não desconsidere o ambiente na hora de pensar em todos os cenários adaptáveis.

Plain Old Java Object - Pojo


Em setembro de 2000, Martin Fowler, Rebecca Parsons e Josh MacKenzie cunharam o novo termo para designar um objeto sem grande valor dentro do modelo de classes de um projeto, an ordinary Java Object. Na mesma ocasião os mesmos disseram:

“Nós nos perguntamos por que as pessoas eram tão contra o uso de objetos regulares em seus sistemas e concluímos que era porque faltava um nome fantasia para os objetos simples. Assim, demos-lhes um, e caiu muito bem.”

Resumindo, é um termo usado para denotar um objeto Java que não segue nenhum dos conceitos principais dos modelos de objetos Java, convenções e frameworks.

Os POJO’s conseguem, inclusive, ser convertidos em outros padrões já citados, como:
  1. POJO Persistence -> PO
  2. POJO Transmission Process -> DTO
  3. POJO como presentation layer -> VO
Por mais simples que seja, são considerados objetos centrais e importantes em um projeto OO
Figura 3: Por mais simples que seja, são considerados objetos centrais e importantes em um projeto OO


Business Object - BO


Um objeto de negócios é um tipo de uma entidade inteligível sendo e agindo como um ator dentro da camada de negócio em uma arquitetura de n camadas orientado a objeto.

Basicamente sua função é encapsular a lógica de negócios para um objeto (que pode incluir vários POs e geralmente precisam de um BO em um PO). Um PO pode ser um BO no final das contas, mas antes precisa ser convertido para tal.

Há três conceitos principais sobre BO:
  1. Contém apenas as propriedades do objeto de negócio;
  2. Contém apenas os métodos de negócio;
  3. Ambos.
Durante o uso efetivo, o conceito do que é correto não é importante, a chave é apropriada para a aplicação prática em suas próprias necessidades de projeto.

Value Object - VO


Esse padrão é um pouco confuso. Segundo a Wikipédia, um Objeto de valor “é um pequeno objeto que representa uma entidade simples, cuja igualdade não é baseada em identidade: ou seja, dois objetos de valor são iguais quando têm o mesmo valor, não necessariamente sendo o mesmo objeto”.

Isso parece confuso quando pensamos em objetos Java atuando como POJOs simples. Definições a parte, esse padrão até hoje sofre alterações em suas explicações. Alguns o definem de uma forma outros a sua maneira, etc. É um objeto usado basicamente para exibir dados na camada de apresentação.

Bem senhores, foi basicamente isso, espero que tenham gostado e não esqueçam: Padrão é Padrão e Convenção é Convenção.



sexta-feira, 2 de outubro de 2015

Reunião de Abertura do Projeto


Thururururu! Hoje vamos falar aqui sobre a importância da reunião inicial de nosso projeto. Esta tem por principal motivo repassar quais as premissas e restrições do produto. Nela falamos quem são as partes interessadas, os para quês e por quês do projeto. Este artigo tem como base o post do blog PTI. Vamos lá senhores!
No início de um projeto, é muito importante reunir todos os participantes para definir vários assuntos referentes ao desenvolvimento e implantação do software. Logo, pode-se dizer que este é um momento de “Kick-off” do projeto.
Se você já jogou futebol nos videogames, deve se lembrar que a partida começa quando a palavra “Kick-off” aparece na tela, não é? Pois bem, é nesse sentido que o conceito de Kick-off será tratado nesse artigo.
Kick-off, em inglês, significa o sinal de início de uma atividade ou evento, e é um termo bastante utilizado em várias ocasiões. Uma reunião de Kick-off na área de TI é o momento em que todos os participantes do projeto se reúnem para definir objetivos, recursos, restrições, prazos e cronogramas referente ao projeto em pauta. O evento deve ocorrer em um local separado do ambiente de trabalho para facilitar a comunicação e evitar interrupções.
Essa reunião normalmente tem duração de duas a três horas, dependendo da dimensão do projeto e do compartilhamento de informações para esclarecer as possíveis dúvidas dos participantes. Ao final desta reunião, finalmente dá-se o início ao desenvolvimento do projeto.
A reunião de Kick-off sempre conta com um responsável que irá conduzir o andamento de cada tópico da reunião. Para isso, é necessário que exista um documento principal composto de todas as características do projeto, de forma que todos possam acompanhar a discussão da reunião. Este documento recebe o nome de Project Charter, e deve ser visualizado em um Data Show ou uma cópia deve ser entregue a cada participante.
Project Charter, também conhecido como Termo de Abertura do Projeto (TAP), é extremamente importante para a reunião de Kick-off. Normalmente é elaborado pelo Gestor de Projetos, que se encarrega de enunciar todos os itens relacionados ao software que será desenvolvido, desde o planejamento até a fase de implantação e treinamento.
Em linhas gerais, o Project Charter contém a especificação do projeto em geral, envolvendo principalmente os pontos:

  • Objetivo, justificativa e propósito do projeto;
  • Recursos humanos do projeto (analistas, projetistas, gestores e desenvolvedores);
  • Demais stakeholders envolvidos (usuários, gerentes e parceiros);
  • Cronograma e prazos de entrega;
  • Recursos materiais e investimentos necessários;
  • Possíveis riscos que podem ocorrer, bem como um plano de prevenção e/ou recuperação;
  • Implantação e capacitação dos usuários (equipe residente, treinamento EaD, etc.).
Este documento, na verdade, é uma ferramenta que permite a decomposição do fluxo de trabalho em atividades específicas, na forma de um diagrama. Na prática, o WBS pode ser comparado a uma hierarquia. Quanto mais subníveis houver, maior será o detalhamento de uma atividade.

Como se pode perceber, este documento deve ser bem formalizado. É um artefato importante para que não haja obstáculos no andamento do projeto e não ocorra imprevistos não documentados.
Eventualmente, na reunião de Kick-off pode existir mais alguns documentos pautados para discussão. Um deles é o Work Breakdown Structure, abreviado como WBS.
Conforme a ocasião, outros documentos ainda podem aparecer na reunião. Se o projeto de software discutido for substituir um sistema já utilizado pelo cliente, talvez seja necessário elencar um documento com as especificações de migração de dados, ou seja, a documentação para o procedimento de cópia dos dados do software atual para a base de dados do software que será desenvolvido. A migração não é uma tarefa simples, e é um pouco mais complexa quando é feita entre sistemas de bancos de dados diferentes, como PostgreSQL para Firebird, por exemplo. Além disso, geralmente a estrutura das tabelas é diferente, exigindo que vários testes sejam realizados antes da cópia definitiva.
Na reunião de Kick-off, quando finalmente todos os itens forem abordados pelo responsável, abre-se um espaço para as dúvidas dos participantes e demais esclarecimentos necessários. Neste momento também é importante propor mudanças ou melhorias nas fases do projeto. Se a sugestão for aceita, o Project Charter é atualizado pelo Gestor de Projetos, destacando a parte alterada do documento com outra fonte ou formatação. Isso facilita a visualização das alterações no documento ocorridas durante a reunião de Kick-off.
Por fim, cada participante recebe um documento chamado Holdmap. Este documento contém as tarefas destinadas ao integrante para a fase atual do projeto. Para um desenvolvedor, por exemplo, o Holdmap seriam as tarefas de implementação, contendo data de início, término e estimativa de tempo. O Holdmap permite que o colaborador se organize dentro dos prazos e siga um roteiro linear de atividades com a ciência dos superiores.
Vale ressaltar que nem todas as reuniões de Kick-off são da mesma forma. Elas podem ser diferentes conforme a cultura da empresa, tipo de projeto ou quantidade de integrantes envolvidos, mas basicamente o contexto é o mesmo.
Então é isso senhores. De seu amigo de sempre Bruno Rafael. Até a próxima.

segunda-feira, 28 de setembro de 2015

Esse tal de Decorator


Salve Salve Galera! Vamos lá com mais esta dica para que vocês possam satisfazer ainda mais suas clientes na hora de fazer os programas. Vamos falar sobre decoração :D

Problema

Imagine que você está desenvolvendo um sistema para um bar especializado em coquetéis, onde existem vários tipos de coquetéis que devem ser cadastrados para controlar a venda. Os coquetéis são feitos da combinação de uma bebida base e vários outros adicionais que compõe a bebida. Por exemplo:
Conjunto de bebidas:
  • Cachaça
  • Rum
  • Vodka
  • Tequila
Conjunto de adicionais:
  • Limão
  • Refrigerante
  • Suco
  • Leite condensado
  • Gelo
  • Açúcar
Então, como possíveis coquetéis temos:
  • Vodka + Suco + Gelo + Açúcar
  • Tequila + Limão + Sal
  • Cachaça + Leite Condensado + Açúcar + Gelo
E então, como representar isto em um sistema computacional?

Uma solução?

Bom, poderíamos utilizar como uma solução simples uma classe abstrata Coquetel extremamente genérica e, para cada tipo de coquetel construir uma classe concreta.
Então teríamos a classe base Coquetel:
1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Coquetel {
    String nome;
    double preco;
 
    public String getNome() {
        return nome;
    }
 
    public double getPreco() {
        return preco;
    }
}
A nossa classe define apenas o nome e o preço da bebida para facilitar a exemplificação. Uma classe coquetel concreta seria, por exemplo, a Caipirinha:
1
2
3
4
5
6
public class Caipirinha extends Coquetel {
    public Caipirinha() {
        nome = "Caipirinha";
        preco = 3.5;
    }
}
No entanto, como a especialidade do bar são coquetéis, o cliente pode escolher montar seu próprio coquetel com os adicionais que ele quiser. De acordo com nosso modelo teríamos então que criar várias classes para prever o que um possível cliente solicitaria! Imagine agora a quantidade de combinações possíveis? Veja o diagrama UML abaixo para visualizar o tamanho do problema:
Além disso, pode ser que o cliente deseje adicionar doses extras de determinados adicionais, desse modo não seria possível modelar o sistema para prever todas as possibilidades! Então, como resolver o problema?

Decorator

Vamos ver qual a Intenção do padrão Decorator:
“Dinamicamente, agregar responsabilidades adicionais a objetos. Os Decorators fornecem uma alternativa flexível ao uso de subclasses para extensão de funcionalidades.” [1]
Perfeito, exatamente a solução do nosso problema! Queremos que, dado um objeto Coquetel, seja possível adicionar funcionalidades a ele, e somente a ele, em tempo de execução. Vamos ver a arquitetura sugerida pelo padrão:
Certo, então todos os objetos possuem o mesmo tipo Coquetel, esta classe define o que todos os objeto possuem e é igual a classe já feita antes. As classes de bebidas concretas definem apenas os dados relativos a ela. Como exemplo vejamos o código da bebida Cachaça:
1
2
3
4
5
6
public class Cachaca extends Coquetel {
    public Cachaca() {
        nome = "Cachaça";
        preco = 1.5;
    }
}
Todas as classes de bebidas possuirão a mesma estrutura, apenas definem os seus atributos. A classe Decorator abstrata define que todos os decoradores possuem um objeto Coquetel, ao qual decoram, e um método que é aplicado a este objeto. Vejamos o código para exemplificar:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class CoquetelDecorator extends Coquetel {
    Coquetel coquetel;
 
    public CoquetelDecorator(Coquetel umCoquetel) {
        coquetel = umCoquetel;
    }
 
    @Override
    public String getNome() {
        return coquetel.getNome()  + " + " + nome;
    }
 
    public double getPreco() {
        return coquetel.getPreco() + preco;
    }
}
Lembre-se de que como o decorador também é um Coquetel ele herda os atributos nome e preço. Nas classes concretas apenas definimos os modificadores que serão aplicados, de maneira semelhante as classes de bebidas concretas, vejamos o exemplo do adicional Refrigerante:
1
2
3
4
5
6
7
8
9
public class Refrigerante extends CoquetelDecorator {
 
    public Refrigerante(Coquetel umCoquetel) {
        super(umCoquetel);
        nome = "Refrigerante";
        preco = 1.0;
    }
 
}
Perceba que no construtor do decorador é necessário passar um objeto Coquetel qualquer, este objeto pode ser tanto uma bebida quanto outro decorador. Ai está o conceito chave para o padrão Decorator. Vamos acrescentando vários decoradores em qualquer ordem em uma bebida. Vamos ver agora como o padrão seria utilizado, veja o seguinte código do método main:
1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
        Coquetel meuCoquetel = new Cachaca();
        System.out.println(meuCoquetel.getNome() + " = "
                + meuCoquetel.getPreco());
 
        meuCoquetel = new Refrigerante(meuCoquetel);
        System.out.println(meuCoquetel.getNome() + " = "
                + meuCoquetel.getPreco());
    }
Perceba que o tipo do coquetel varia de acordo com o decorador aplicado. Então, quando chamamos o método getNome ou getPreco o primeiro método chamado é o método do último decorador aplicado.
O método do decorador por sua vez chama o método da classe mãe, este método então chama o método do Coquetel ao qual ele decora. Se esse coquetel for outro decorador o pedido é repassado até chegar a um coquetel que é uma bebida de fato e finalmente responde a requisição sem repassar a nenhum outro objeto.
De maneira semelhante a recursão, os valores calculados vão sendo retornados até chegar no último decorador aplicado e então são repassados ao objeto. É como se os decoradores englobassem tanto outros decoradores quanto o componente em si.

Um pouco de teoria

Como já dito o padrão Decorator adiciona funcionalidades ao objeto em tempo de execução. Note bem que, ao contrário da herança que aplica funcionalidades a todos os objetos dela, o padrão decorator permite aplicar funcionalidades apenas a um objeto específico.
Justamente devido a essa propriedade é que o padrão Decorator possui uma flexibilidade maior que a herança estática. Além disso, como o Decorator aplica apenas as funcionalidades necessárias ao objeto nós evitamos o problema de classes sobrecarregadas, que possuem funcionalidade que nunca são utilizadas.

Problemas com o Decorator

No entanto este comportamento altamente dinâmico do Decorator traz alguns problemas, como por exemplo, dado um objeto Coquetel não é possível verificar se ele possui um decorador Limão, Refrigerante ou qualquer outro. Assim, caso cada um dos decoradores implementasse outros métodos específicos, um desenvolvedor que utilizasse um coquetel qualquer não possui nenhuma garantia sobre o tipo do coquetel. Por exemplo, se o decorador Limão implementa um método arder(), não é possível afirmar que um coquetel qualquer possui este método.
O problema é pior ainda pois não é possível sequer verificar o tipo do coquetel, por exemplo, adicione este código no final do método main:
1
System.out.println(meuCoquetel instanceof Cachaca);
Será exibido no console “false” pois, como aplicamos o decorador Refrigerante modificamos o tipo do coquetel.
Além disso é necessário criar vários pequenos objetos, que possuem o mesmo comportamento, para criar os coquetéis necessários. No primeiro modelo apresentado teríamos várias classes, mas apenas um objeto para representar um Coquetel. Utilizando a estrutura do Decorator precisamos criar um objeto para cada novo decorador, além do objeto bebida.

Admin: Bruno

Olá Galera! muito grato por estarem acessando nosso blog. Espero que seja possível transmitir de forma compreensível um pouco de meus conhecimentos em programação, para esta comunidade de desenvolvedores que cresce cada vez mais! Espero que Gostem! Abraço! E meu enorme obrigado à Renato Simões, Átila Soares,Wanderson Quinto, Emerson e a toda galera que sempre ajudou meu sincero obrigado....
Especialmente a Natalia Failache e Rita de Cassia que sempre apoiaram este sonho....

De seu amigo Bruno Rafael.