Introdução

Um dos assuntos que gera calorosas discussões entre desenvolvedores Java Web é a utilização ou não de DTO's no desenvolvimento Web. Trata-se de um tema bastante polêmico e de grande relevância e devido a isso vou tratar desse tema neste post.

Conceituação

Um DTO (Data Transfer Object = Objeto de Transferência de Dados) é um POJO (Plain Old Java Object) que não tem nada de especial. Trata-se apenas de uma instância de classe com atributos e métodos getters e setters, DTO's são conhecidos também como VO's (Value Objects).

Os DTO's são (?) utilizados na transferência de dados entre as diversas camadas existentes no desenvolvimento da aplicação, principalmente na transferência da interface gráfica para o código ou vice-versa.

Tipos

Eu costumo classificar os DTO's em dois tipos, os DTO's de top-down e de bottom-up que são utilizados para transferência de dados da interface gráfica para o código java e do código java para a interface gráfica, respectivamente. 

DTO's e JPA

Com o surgimento da especificação JPA (Java Persistence API), principalmente com a padronização que ocorreu com o lançamento do EJB 3.0 (Enterprise Java Beans) muitos desenvolvedores e inclusive autores da área, consideram que a utilização de DTO's se tornou obsoleta e desnecessária, porém, essa opinião está longe de ser unânime, muito pelo contrário, existe um outro grande número de profissionais que defendem a utilização dos DTO's mesmo com a nova padronização do JPA.

Contra DTO


O principal argumento contra a utilização de DTO's reside que a necessidade de utilização deste tipo de objeto era a inexistência de beans de entidade desacoplados, de modo que qualquer chamada de método em um bean de entidade refletiria em uma sincronização com o banco de dados o que tornava a utilização de entity beans para transferência de dados muito cara.

Porém, com o lançamento do EJB 3.0 os beans de entidade passaram a poder ser não gerenciados em determinados momentos, de modo que uma chamada em um método do entity bean que esteja desacoplado, que tem a mesma estrutura dos DTOs (somente atribudos e métodos getters e setters), não resulta em uma sincronização com o banco de dados. Surge aí então a possibilidade de utilizar os entity beans na função dos DTO's, o que torna a utilização destes desnecessárias por constituir uma camada a mais.

Pró DTO

Por outro lado, os defensores do DTO argumentam que a utilização dos beans de entidade na função de DTO constitui uma grande falha de coesão, lembrando que a coesão determina que as camadas tenham papel específico e bem definido e neste caso a utilização dos beans de entidade como DTO seria uma dupla utilização da camada de entidades o que de fato constitui uma ofensa aos padrões de coesão.

Além disso, existe o argumetno que os entity beans por certas vezes possuem muito mais informação do que o necessário em determinados momentos o que ocasiona um consumo de memória e de largura de banda (em aplicações web) desnecessário.

Conclusões

Dadas as definições, a classificação, os argumentos pró e contra, vou dar a minha opinião acerca da utilização ou não de DTOs.

Penso que na maioria dos casos os entity beans podem ser utilizados como DTOs de top-down de modo que as informações da interface gráfica já reflitam diretamente no bean que será persistido no banco de dados, porém, mesmo com essa utilização por certas vezes é necessário transportar informações da interface gráfica para o código java que não serão persistidas, nesse caso eu acho que a melhor solução é utilizar DTOs, embora os contra DTO utilizem campos transientes no entity bean para transportar essas informações o que eu acho uma falha de projeto.

Já no caso de bottom-up os DTOs são mais adequados na maioria dos casos, uma vez que quase sempre as consultas só necessitam recuperar algumas das informações existentes no banco de dados e a utilização de entity beans carregaria todos os campos da tabela o que consumiria memória e largura de banda de modo desnecessário. Mais uma vez os contra DTO argumentam que podem ser criados construtores nos entity beans somente com as informações necessárias de modo que no bean estariam carregadas somente as informações necessárias no momento. Peno que esse argumento não é válido pelo fato de que ter um bean carregado com vários campos nulos e somente alguns preenchidos ainda consome memória e largura de banda, além de ser algo muito deselegante.

Fato é que em determinadas situações utilizar os entity beans para a função de DTO's apesar de constituir uma falha de coesão não se trata de uma falha tão grave a ponto de ser evitada, já que gera o benefício de redução de complexidade e de quantidade de código e camadas, porém, querer "aposentar" os DTO's é algo bastante inviável, por isso deve-se buscar um meio termo entre os momentos de se utilizar DTO's e os momentos de evitá-los.

Bom, acho que esse post ficou um pouco longo, mas é sempre complicado tratar de assuntos polêmicos, espero que tenha ficado claro para todos quais são as grandes incógnitas, as vantagens e desvantagens dos DTOs e a minha opinião sobre o assunto. Depois vou tentar postar sobre outros assuntos polêmicos como a utilização de DAO's por exemplo, mas por hoje é só. Obrigado pela visita.

Introdução

Pouco tempo atrás tive a necessidade de executar comandos de sistema operacional através do código Java e por se tratar de uma necessidade que achei interessante e ser algo que raramente utilizo, resolvi compartilhar aqui no blog pra caso alguém tenha a mesma necessidade e também para que quando eu mesmo precisa dar uma consultada aqui.
Vou postar uma classe Main aqui que permite a execução de quaisquer comandos no terminal do Sistema Operacional, na solução aqui vou postar comandos do Windows mas nada impede a utilização deste código em outros sistemas operacionais.

Código

          1. public class Main {
          2.
          3.           public static void main(String[] args) throws Exception {
          4.                     String[] comandos = {
          5.                               "ping",
          6.                               "http://academicsmaster.blogspot.com.br/"
          7.                     }
          8.                     Process p = Runtime.getRuntime().exec(comandos);
          9.                     InputStream is = p.getInputStream();
          10.                   resposta = convertStreamToString(is);
          11.                   System.out.println(resposta);
          12.         }
          13.
          14.          public static String convertStreamToString(InputStream is) throws IOException {
          15.                   if(is != null) {
          16.                              Writer writer = new StringWriter();
          17.                              char[] buffer = new char[1024];
          18.                              try {
         19.                                       Reader reader = new BufferedReader(new InputStreamReader(is,           20.                                                     "ISO-8859-1"));
          21.                                           int n;
          22.                                           while((n = reader.read(buffer)) != -1) {
          23.                                                    wirter.write(buffer, 0, n);
          24.                                           }
          25.                              } finally {
          26.                                        is.close();
          27.                              }
          28.                              return writer.toString();
          29.                   }
          30.
          31.                   else {
          32.                             return "";
          33.                   }
          34.          }

Detalhes
Vamos agora ao detalhamento do código:

  • Linha 3: destaque para o fato de o método main lançar uma exceção. Essa exceção deve ser declarada por dois motivos: 1 - O execução de comandos pelo sitema operacional pode gerar exceções, caso um comando esteja com a sintaxe errada por exemplo; 2 - o método para conversão do InputStream para String pode gerar um IOException; 
  • Linhas 4 a 7: Um array de String é instanciado com todos os comandos que devem ser executados. Convém destacar que comandos parametrizados, como é o caso do "ping" que tem o parâmetro do nome de site ou ip que deve ser "pingado", cada parâmetro corresponde a uma entrada diferente no array;
  • Linha 8: A classe java.lang.Runtime é utilizada para então executar os comandos no sistema operacional através de seu método estático "getRuntime()";
  • Linha 9: Após a execução dos comandos na linha 8, o processo está atualizado com a resposta do sistema operacional ao comando e pode ser processado através do método getInputStream();
  • Linha 10: Uma vez recuperado o InputStream basta convertê-lo para uma String e ter então a resposta do Sistema Operacional ao comando completamente legível.
O método convertStreamToString() é outro que pode ser muito útil. Eu particularmente não consigo lembrar os detalhes desse código sempre que preciso converter um InputStream para uma String, então fica aí mais um local para consulta de método para conversão de InputStrem para String.

Conclusão

Este código apesar de simples e curso pode ser utilizado de forma muito poderosa. É como se tivesse um prompt do DOS (no caso do Windows) disponível para executar qualquer comando imaginável. Sem falar no método de conversão de InputStream para String que também é bastante utilizado no desenvolvimento de aplicações java.

Acho que é o suficiente por esse post, até a próxima.
Introdução

Os modelos OSI e TCP/IP são os dois grandes núcleos de discussão quando o assunto é Redes de Computadores. Em salas de aula virou clichê dos professores e instrutores utilizarem a frase "O Modelo OSI deve ser utilizado quando se tratar de teoria e o TCP/IP quando se tratar de prática". Essa frase é um tanto questionável e superficial mas apesar disso eu já vi muitos utilizando-na.

Tratam-se de modelos de distribuição de complexidade em camadas utilizados na comunicação de dados nas redes de computadores. Enquanto o modelo OSI trata apenas de um "modelo de referência", o modelo TCP/IP trata-se de um "modelo de protocolo". E o que isso significa na prática?

 Modelo de Referência

Os modelos de referência (o OSI é o mais amplamente utilizado) fornecem uma referência que permite uma manutenção concisa dentro de todos os tipos de protocolos de rede e serviços, tal tipo de modelo não tem a intenção de ser uma especificação de implementação ou de fornecer em nível suficiente de detalhe para definir de maneira precisa os serviços da arquitetura de rede, seu principal propósito é auxiliar em um entendimento mais claro das funções e processos envolvidos. Como o próprio termo "referência" já diz é algo que serve de base para utilização em outros protocolos permitindo a manutenção de um padrão.

Modelo de Protocolo

Já o modelo TCP/IP por tratar-se de um modelo de protocolos corresponde de perto a um conjunto específicos de protocolos. A pilha de protocolos TCP/IP é bastante conhecida e é utilizada pela rede mais utilizada de todas (Internet).

A partir dessas definições de Modelo de Referência e Modelo de Protocolo é possível entender porque eu penso ser equivocada a afirmação que citei no início do post. Não é que o modelo OSI é algo pra ser estudado como teoria e o TCP/IP como prática, a definição dos modelos vai muito além disso.

Um pouco de história

A grande verdade é que o modelo TCP/IP surgiu antes do modelo OSI o que já é um belo chute no fígado do modelo OSI, como que um modelo que se propõe a servir de referência surge depois de um outro que deveria utilizá-lo como base?

Por ter surgido antes do OSI o TCP/IP passou a ser utilizado em larga escala e devido ao seu exponencial crescimento não tem dado muitas chances a outros modelos....

As camadas

O modelo OSI propõe 7 camadas como ideal para representação de redes (observe que o modelo não é a rede em si, mas apenas uma representação desta), enquanto que o TCP/IP opera a todo vapor utilizando 4 camadas. As camadas de ambos os modelos podem ser observadas na seguinte figura:


A grande verdade sobre essas distribuições de camadas é que nenhuma delas é a ideal.

O modelo OSI apresenta duas camadas com funções muito curtas e que não estão claramente definidas, trata-se das camadas de Apresentação e Sessão. Neste ponto o modelo TCP/IP apresenta algo mais conciso já que a sua camada de Aplicação corresponde ás três primeiras camadas do modelo OSI (Aplicação, Apresentação e Sessão), de modo que a camada não ficou sobrecarregada e pode ser melhor definida.

Por outro lado o modelo TCP/IP sobrecarrega a camada de Acesso à Rede de modo que a distribuição feita pelo modelo OSI neste ponto é mais adequada, observer que a camada de Acesso à Rede do TCP/IP equivale às camadas de Enlace de Dados e Física do modelo OSI. Isso ocasiona a criação de "sub-camadas" dentro da camada de Acesso à Rede do modelo TCP/IP.

Uma coisa que poucos sabem sobre o modelo OSI é que ele só possui 7 camadas por ter se baseado em um modelo que já estava em utilização na IBM e a ISO (criadora do modelo OSI) não queria contrariar a então toda poderosa IBM.

Conclusões

Fato é que, na minha visão, um modelo mais próximo do ideal para representação em camadas das redes seria uma mesclagem entre os dois modelos de modo que teríamos as seguintes 5 camadas:

5 - Aplicação
4 - Transporte
3 - Rede/Internet
2 - Enlace de dados
1 - Física


Essa organização é muito utilizada por vários autores na área de rede como Tanembaum por exemplo e o que poucos sabem é que as redes da Novell (ela mesma!) são organizadas utilizando um modelo nessa estrutura.

Vou tentar dedicar um post a cada uma dessas cinco camadas em breve para que a representação fique clara para quem acompanha as postagens e por hoje é isso!
Uma das ferramentas mais populares na utilização de redes de computadores é o e-mail. Nos primórdios havia quem apostasse que o e-mail poderia substituir outros meios de comunicação como o fax por exemplo, porém, apesar do alto nível de popularidade que os aplicativos de e-mail alcançaram não conseguiram aposentar os blogs.

O e-mail tornou-se tão popular que várias empresas passaram a oferecer contas gratuitas com vários recursos sofisticados e grande capacidade de armazenamento. Podemos destacar o gmail da Google, yahoo mail da Yahoo, hotmail atualmente da Microsoft, dentre outros.



Mas enfim, para profissionais de Tecnologia da Informação é importante destacar em se tratando de redes de computadores, como os clientes e servidores de e-mail "trabalham" para que um e-mail possa ser criado, enviado e recebido e é disso que trata esta postagem.

O processo de envio de e-mail se inicia com a criação do mesmo pelo remetente, para tal criação é utilizado um programa cliente denominado Mail User Agent (MUA), portanto o MUA é o programa cliente utilizado pelo remetente para criação de e-mails. Podemos citar como exemplos de MUA o Groupwise da Novell, o Outlook da Microsoft, Thunderbird para usuários do Ubuntu, dentre outros.

Uma vez criado o e-mail utilizando o MUA, o e-mail deve ser direcionado para um servidor de e-mails. Esse direcionamento do MUA para o servidor de e-mail é feito utilizando o Simple Mail Transfer Protocol (SMTP). O SMTP é um protocolo que opera na camada de aplicação (camada 7 do modelo OSI). O SMTP está definido na RFC 2821 e o processo TCP/IP que responde no lado servidor para o SMTP está identificado pela porta número 25, em momento oportuno vou publicar um post exclusivamente sobre a definição de porta no contexto do modelo TCP/IP e um outro exclusivamente sobre SMTP, por hora o postado até aqui é suficiente para entender em quais momentos o SMTP é utilizado no envio de e-mails.

Existem dois processos que atuam no servidor de e-mail que são o Mail Transfer Agent (MTA) e o Mail Delivery Agent (MDA), na sequência um detalhamento sobre estes processos:

O MTA é o processo que recebe a mensagem de e-mail enviada pelo MUA. Após recebê-la O MTA verifica se o endereço de e-mail à qual se destina a mensagem faz parte da lista de e-mails gerenciada pelo servidor. Caso faça o MTA encaminha o e-mail para o MDA para que realize a entrega, caso não faça o MTA encaminha a mensagem para outros MTA em outro servidor de e-mail e este processo é repetido até que a mensagem chegue ao servidor de e-mail responsável pela entrega àquele endereço. Para encaminhar as mensagens para outro MTA ou para o MDA é utilizado também o protocolo SMTP.

Vimos que quando o MTA recebe uma mensagem e identifica que o endereço de destino faz parte da lista gerenciável pelo servidor de e-mail ele a encaminha ao MDA. O papel do MDA é entregar a mensagem ao destinatário final que a acessará através de um MUA. O MDA "escuta" quando o destinatário se conecta ao e-mail utilizando um MUA, quando a conexão é identificada o MDA entrega a mensagem ao MUA utilizando Post Office Protocol (POP ou POP3).

O POP ou POP3 é um outro protocolo da camada de aplicação (camada 7 do modelo OSI) utilizado exclusivamente para entrega de e-mails de um MDA para um MUA. O POP está definido na RFC 1939 e seu processo está identificado pela porta padrão 110 no modelo TCP/IP. Provavelmente futuramente postarei algo exclusivo sobre o POP3.

Bom, analisados os papéis dos MUA, MTA e MDA e como estes agentes utilizam SMTP e POP3 no envio, encaminhamento e entrega de e-mails acho que estão esclarecidos os pontos mais importantes sobre o envio de e-mails, estando portanto o objetivo do post concluído.
Não é necessário um esforço muito grande para que se encontre um "técnico de informática" por aí. O que me preocupa é o conhecimento que possui e que busca possuir uma boa parte desses profissionais que se dizem técnicos de informática. O motivo de tal preocupação é a possibilidade crescente de banalização e desvalorização da categoria.

Particularmente, não me digo "técnico de informática", por dois motivos, o primeiro é que minha área de atuação é mais voltada para desenvolvimento e segundo que na minha visão ser técnico de informática envolve conhecimentos bem mais amplos e complexos do que os atuais que tenho. O pior de tudo é que os técnicos de informática que encontro por aí hoje em dia tem menos conhecimento do que eu, e isso me parece bem estranho. Sugiro que antes de sair falando por aí que é técnico de informática por saber formatar um computador e instalar um Windows, estude um pouco mais, adquira conhecimentos sólidos, aprenda conceitos para evitar sua própria desvalorização.

Bom, depois desse alerta inicial, vamos ao que realmente interessa. Como estava com essa preocupação com a falta de conhecimento sólido, principalmente em conceitos importantes, resolvi começar a realizar algumas postagens acerca de conhecimentos que julgo serem importantes. A primeira postagem vai ser a respeito de uma tecnologia essencialmente importante tratando-se de hardware e que muita gente abre a boca pra falar dela sem ao menos saber do que se trata, que é a Tecnologia SCSI.

SCSI é uma sigla que significa Small Computer System Interface. Essa sigla representa uma tecnologia de enorme importância e sofisticação para os sistemas de hardware de computadores. A essência da SCSI é a transmissão de dados entre os componentes dos computadores com uma performance altamente elevada.


O modelo de arquitetura de Computadores Pessoais (PC) proposto por Von Neumann que é utilizado atualmente na maior parte (senão em todos) dos computadores traz uma descentralização da composição do hardware dos computadores, onde vários periféricos independentes e harmônicos interagem para o funcionamento da máquina.

Com essa descentralização é frequente que um componente do computador se comunique com o outro e é essencial que essa comunicação ocorra no menor tempo possível aumentando o desempenho das máquinas.

É nesse ponto que atua a Tecnologia SCSI, na comunicação entre os diversos componentes dos computadores. Além da questão da velocidade o SCSI traz outras vantagens como as questões da compatibilidade e estabilidade. Sendo o CPU (processador) o componente mais rápido do computador, a utilização do padrão SCSI permite que essa velocidade seja aproveitada e assim, aumenta-se de forma significante o desempenho do computador.
 
Nesse post não entrarei em detalhes acerca do funcionamento da tecnologia, como ocorrem as transmissões, os motivos de a tecnologia ter uma performance tão alta e ter se consolidado no mercado há anos sem que haja nenhuma outra nova tecnologia que sequer assuste a sua utilização. O objetivo desta postagem é simplesmente ilustrar o conceito da tecnologia.
Com isso, essa primeira postagem se encerra. Outros conceitos importantes para a área técnica serão ilustrados nas próximas postagens.