Nesta semana algo surpreendente aconteceu: Eu ando trocando e-mails com o pessoal que lê a coluna e um e-mail me intrigou, foi do nosso amigo e leitor Denílson, que enviou-me, entre outras coisas, quatro perguntas mais que pertinentes.
- Todo atributo deve ter seu modificador privado (private)? Isso é regra?
- Mesmo que minha classe não necessite retornar (get) ou passar (set) para um determinado atributo, sou obrigado, ou seja, é boa prática criar os métodos get e set de cada atributo?
- Em toda classe deve-se criar o método construtor da mesma?
- O método construtor de uma classe é representado no diagrama UML?
Ex: Imagine que em minha classe existe um método imprime e este acaba imprimindo o valor de um atributo privado da mesma classe, se não vou usar esse valor em nem um outro lugar da aplicação, qual a necessidade de criar o método get para esse atributo? Apenas boa prática?
Mas o mais fantástico não está nas perguntas, mas na coincidência que isso gerou, estou trabalhando segurança da informação com meus alunos do terceiro ano. Bom, vamos por partes como diria qualquer processador Pipe-line. Primeiramente vamos pensar no que é informação:
Para nós da tecnologia, informação é qualquer conjunto de bits que possa ter algum significado específico, para termos uma idéia do que estamos falando pense em Bytes, nos sabemos que um byte possui oito bits certo? Não errado. Na realidade um byte moderno pode possuir até onze bits. São oito bits que representam o valor binário mais três bits para o cálculo da paridade. É uma forma que a informática arrumou para verificar a Autenticidade do bit. Agora vamos pensar, o que é segurança da informação?
A Segurança da Informação é a proteção existente sobre as informações, sejam pessoais ou empresariais. Essa segurança pode ser feita de várias maneiras, desde garantindo a segurança física dos dados, quanto o uso de métricas para a definição do nível de segurança existente. Uma informação tem a sua segurança alterada por alguns fatores externos que regem o seu comportamento:
- do uso de quem se utiliza dela;
- pelo ambiente ou infra-estrutura que a cerca ou;
- por pessoas mal intencionadas que tem o objetivo de furtar, destruir ou modificar a informação.
Ao proteger uma informação devemos pensar em 3 itens:
- Confidencialidade – Garantir que somente modelos legítimos, aqueles que fazem parte do projeto de software, tenham acesso a ela;
- Integridade – Garantir a originalidade da informação, não que devemos garantir que a informação não sofra alterações, mas sim que caso ela sofra essas alterações tenham procedência e representem a vontade daquele que gerou a informação garantindo assim o seu ciclo de vida (nascimento, manutenção e destruição);
- Disponibilidade – Garantir que a informação esteja disponível para o uso daqueles que possam utilizá-la.
Esses três elementos - Confidencialidade, Integridade e Disponibilidade – definem bem aquilo que espera-se de um projeto de segurança de informação.
Mas o que isso tudo tem a ver com as perguntas do nosso amigo? Simplesmente muito, ou melhor, tudo a ver. Vamos analisar pergunta por pergunta agora.
“Todo atributo deve ter seu modificador privado (private)? Isso é regra?”
Disponibilidade
É uma classe que possua todos os seus modificadores privates, certamente irá contra a regra da disponibilidade. Métodos privados são aqueles que pertencem somente a classe na qual ele foi escrito. Veja o exemplo abaixo:
class Tabuadas
{
static private void calculaTabuada(int numeroCalcula)
{
for(int contador = 0; contador < 11; contador++)
{
System.out.println(contador +" x " + numeroCalcula + "=" + (contador *
numeroCalcula ));
}
}
public Tabuadas(int numeroQueVouCalcular)
{
calculaTabuada(numeroQueVouCalcular);
}
}
O método calculaTabuada que não é um método modificar mas é um método privado, está completamente errado para um modelo de solução genérica, para calcularmos qualquer tabuada teríamos que construir um objeto da classe Tabuadas e durante a sua construção solicitar a tabuada desejada.
Agora imagina se o infeliz do programador quer escrever as tabuadas do 1 ao 10 e na hora de construir esses objetos, ele constrói da seguinte forma:
static Tabuadas tabuadaDoUm = new Tabuadas(1);
static Tabuadas tabuadaDoDois = new Tabuadas(2);
static Tabuadas tabuadaDoTres = new Tabuadas(3);
...
Teríamos 10 objetos estáticos na memória da maquina sem necessidade alguma. Agora vamos analisar um segundo exemplo:
class Tabuadas
{
static void calculaTabuada(int numeroCalcula)
{
for(int contador = 0; contador < 11; contador++)
{
System.out.println(contador +" x " + numeroCalcula + "=" + (contador *
numeroCalcula ));
}
}
}
O método calculaTabuada agora é um método publico e pode ser acessado de qualquer outra classe do sistema tornando assim a nossa solução em uma solução genérica.
for(int contador = 0; contador < 11; contador++)
{
Tabuadas.calculaTabuada(contador);
}
Pronto, tabuadas do 0 ao 10 sem nenhum objeto desnecessário. Pensemos então: Será que devemos sempre deixar os métodos publicos então? Claro que não, temos que pensar no modelo, qual a sua necessidade? Métodos públicos ou privados, um método modificar privado, ou seja, interno a classe, tem alguma utilidade? Se o modelo disser que sim quem somos nós para discordar?
Existem modelos computacionais que facilmente permitem uma pequena visualização do comportamento do objeto (o diagrama de eventos é um deles). Estude o comportamento deste objeto, ou classe, que o modelo lhe trará a solução adequada. Vamos a segunda pergunta agora:
“Mesmo que minha classe não necessite retornar (get) ou passar (set) para um determinado atributo, sou obrigado, ou seja, é boa prática criar os métodos get e set de cada atributo?”
Ex.: Imagine que em minha classe existe um método imprime e este acaba imprimindo o valor de um atributo privado da mesma classe, se não vou usar esse valor em nem um outro lugar da aplicação, qual a necessidade de criar o método get para esse atributo? Apenas boa prática?
Confidencialidade
É garantir quem tem permissão para acessar tal atributo pode ser fundamental em um sistema de computador, realmente ao pensamos em um atributo privado à uma classe fica impossível de pensarmos em utilidades para métodos acessadores e modificadores não é?
Sim, geralmente isso acontece, mas gosto de refletir um pouco mais quando chego a uma solução que me parece obvia, vamos imaginar o seguinte, o que realmente define a necessidade da criação de acessadores ou modificadores é a quantidade de objetos ou a segurança que a ele é oriunda?
Um modelo de sistema de Sockets, para transações bancárias, por exemplo, será que esse tipo de encapsulamento pode ser necessário? Vamos deixar a coisa um pouco mais interessante: Uma informação criptografada seus métodos acessadores e modificadores possuem necessidade apenas para encapsular o objeto? Muito possivelmente o atributo saldoCorrentista, da classe ContasCorrentes não será um objeto da classe Double, associar o encapsulamento de dados a criação de Atributos Privados e métodos publico para alterar e resgatar esses atributos é um erro.
Em algum lugar de um método setNomeCorrentista muito possivelmente iremos encontrar um insert em algum banco de dados. A nossa obrigação enquanto programador não esta em decidir se tal atributo precisa ou não de métodos acessadores ou modificadores, mas sim compreender o sistema para encontrar no problema a sua solução, e após isso feito, facilitar o uso desta solução, e parece-me que os métodos Set e Get, facilitam e muito a nossa vida.
“Em toda classe deve-se criar o método construtor da mesma?”
Voltamos a classe Tabuadas, a segunda mostrada no artigo, se a função da classe fosse apenas de escrever e calcular tabuadas, certamente a classe desenvolvida por mim seria muito parecida com ela, e não possuiria método construtor, (e olha que geralmente eu busco nortear a solução OO por métodos construtores).
“O método construtor de uma classe é representado no diagrama UML?”
Essa resposta acredito vou ficar devendo, a UML possui N diagramas, você tem Diagrama de Classe, de Caso de Uso, são muitos diagramas. Um diagrama é um pedaço do modelo, e ele, o digrama, serve para que nos possamos entender o modelo, vou escrever algo aqui que certamente vai custar meu “emprego” como colunista O.O.
Se você tem duvidas em relação a sua classe precisar ou não precisar de um método construtor, aqui, só entre nos, que meus alunos e coordenadores não leiam isso e depois que você pegar o esquema esquece isso também, pense no seu objeto como um depósito de dados de um DFD, quais atributos são realmente necessários para que ele exista? Se você encontrar algum, é bom começar a pensar em escrever um método construtor, mas se você não encontrar nenhum depois de um bom tempo de pesquisa, muito possivelmente essa classe não possuirá um método construtor definido, a não ser que os diagramas de seqüência, estado, solicitem tal método.
Em meus modelos eu represento todos os métodos no diagrama de Classe. Inclusive se minha classe tiver mais de um método construtor eu indico todos eles com seus parâmetros.
Bom, acho que por hoje chega. Obrigado a todos que estão acompanhando meu trabalho e queria desejar um agradecimento especial ao Eduardo Spinola, o editor do site que coloca os nomes as minhas colunas, juro a vocês que quando envio a coluna fico curioso para saber qual o nome que ele dará a ela, faço aqui com meus botões uma listinha de uns 10 nomes, mas quando vejo o nome que ele coloca percebo que tenho que melhorar muito, ele tem o don de sintetizar todo o artigo em 5 ou seis palavras. Muito obrigado Eduardo pelo excelente trabalho.