Get do Pojo com conhecimento

Pessoal estou com uma dúvida que me parece simples, mas que eu não chego a uma conclusão.

Quando tenho sistemas Web com telas simples do tipo CRUD com um campo, por exemplo, descrição o usuário pode informar espaços em branco desnecessários que não devem ir para o banco de dados.

Por exemplo, o usuário colocou " Caneta". Antes de enviar para o banco de dados devemos dar um trim para ficar “Caneta”.

Minha dúvida é: Se eu colocar no método get do objeto (POJO) que tem o atributo descrição um trim como abaixo eu estou “quebrando” a qualidade da programação?

public String getDescricao() {
        if (descricao != null) {
            return descricao.trim();
        }
        return descricao;
    }

Será que estou “ferindo” algum conceito em que diz que o get deve ser simples sem conhecimento de qualquer manipulação?

Obrigado.

Olha, na minha opinião, esse é o tipo de serviço mas apropriado para o método que está recebendo o dado - no caso o set. Imagine que em algum outro ponto do seu código você precisasse do valor desse atributo. Seria meio chato repetir o tratamento de limpeza dele, concorda? No get eu colocaria mais coisas que tratassem da forma de exibição do dado - por exemplo se tivesse que aplicar uma máscara.

Na minha opinião não tem problema.

É interessante vc colocar essa verificação no set porque garante que o atributo tenha um valor consistente logo no início.

Claro que isso leva a discussão do padrão javabeans,DDD e outras coisas , dá uma pesquisada no próprio forum tem muita coisa.

Ferindo? Nada rapaz, isso que você está fazendo é o que TEM que ser feito. Todo dado que entra no banco de dados deve ser tratado, o set e o get foram feitos para fazer essas verificações que tu mesmo demonstraste, ou tu acha que é apenas para acessar os atributos? o get e o set são utilizados para fazer tratamentos dos valores antes que seja passado para “frente”, se não era mais fácil acessar diretamente as variáveis

eu acho que ta errado sim

se isso tem que ser feito porque é regra do teu sistema, isso nao deveria ser feito na camada de negocios, nao?

se o teu sistema te uma camada logo acima do repositorio, que trata das regras de negocio e isso é uma regra de negocio, vc nao deveria fazer isso nela, nao?

o que ta fazendo é gravando um dado tal qual ele ta sendo digitado e quando tenta pegar de volta da uma “maquiada” nele.

nao ta errado do ponto de vista funcional, porque no final vai funcionar, so que ta meio gambiarra, ne?

Discordo.

Não acho que isso seja regra de negócio, é o mesmo tipo de validação que ocorre quando vc coloca acentos num campo que não deve ter .

A “maquiagem” citada no meu ver é garantir que os dados que o objeto que está recebendo são corretos e ele pode nesse nível verificar.

Cara de acordo com o livro MUITO BOM e recomendado pelo próprio site do hibernate, “Java Persistence with hibernate”, afirna que o tratamento deve ser feito nos get e set
eles FORAM feitos para isso! se tu utiliza get e set para apenas retornar valores ai sim TÁ ERRADO

Só complementando.

Válida sua colocação, o código está limpo, mas tem um pequeno porém.
Se a descrição permite valor nulo, melhor seria você utilizar o seguinte:

public String getDescricao() {  
        if (descricao != null) {  
            return descricao.trim();  
        }  
        return new String("");
    }

Assim você evita null pointers na hora de imprimir um possível valor nulo com a descrição.

Outra forma de utilizar bem esse código seria assim:

public String getDescricao(){
		
		String s = (descricao == null) ? descricao.trim() : "";
		
		return s;
		
	}

tb discordo do que vc falou.

vc diz que ele quer verificar nesse nivel (“get”). So que como ele ta usando um “get” pra verificar, entao ele pode ja ter posto no repositorio, correto? ele quer pegar um cara que ta gravado no repositorio.

se foi gravado no repositorio ele ja passou pela camada de negocio. se ele passou pela camada de negocio ele so tem dados validos (pois ja foram aceitos e gravados). Se ele so tem dados validos, vai verificar mais o que?

ele pode no maximo usar algum teste no contrutor ou no “set” (acho mais correto no contrutor, no maximo) para validar os dados ainda na variavel (caso nao tenha sido gravado no repositorio, ou seja, assim que os dados forem inseridos no objetos criado, algo desse tipo). Entretando se as regras do negocio forem usadas, isso nao e necesasrio. Tb tem que ver quando ele coloca os dados no objeto, talvez isso so seja possivel msm no set…

se o cara ta usando um “get” e validando os dados no “get” significa dizer que os dados JA ESTAO em algum lugar e ESTAO invalidos de alguma forma. Entao é maquiagem, pois ele ta mostrando uma coisa que foi gravada de forma errada. Nesse caso, é apenas um espaço, mas poderia ser coisa mais seria.

é estranho sim fazer isso (no “get”). Mas isso é apenas uma opiniao minha. é como dizer “ah, temos o dados, mas antes de mostrar da uma melhoradinha p ninguem ver como foi gravado com esses caracteres que nao deviam estar aqui, ok?”.

o tratamento de um dado deve ser feito ANTES de se gravar, antes de se aceitar o dado. e nao depois que ele ja foi aceito no sistema. E o “get” é usado para pegar dados que estao no sistema ou numa variavel.

além disso, olhe o que o cara que abriu a duvida colocou (estou copiando o que ele disse) :

"Pessoal estou com uma dúvida que me parece simples, mas que eu não chego a uma conclusão.

Quando tenho sistemas Web com telas simples do tipo CRUD com um campo, por exemplo, descrição o usuário pode informar espaços em branco desnecessários que não devem ir para o banco de dados.

Por exemplo, o usuário colocou " Caneta". Antes de enviar para o banco de dados devemos dar um trim para ficar “Caneta”. "

Notou que ele AFIRMOU que o espaço em branco é algo QUE NAO DEVE ir para o banco? obseve a frase de dele : “Por exemplo, o usuário colocou " Caneta”. Antes de enviar para o banco de dados devemos dar um trim para ficar “Caneta”. "

Se o espaço em branco é uma coisa que o BANCO nao pode aceitar, isso nao e regra de negocio, nao? Se nao e regra de negocio, é regra de GUI? regra do repositorio? da fachada?

o que eu queria so deixar claro é que como o ADEMILTON falou no inicio, vc é livre pra colocar o que quiser nos metodos get e set.

o que é estranho demais é dizer que um dado foi aceito num sistema e querer tratar, modificar o dado na hora do get. no maximo no set ou no construtor.

mas ainda acho que se isso é algo que nao deveria ir pro repositorio e é uma regra de negocio (e nao se discute regra de ne negocio, porque é uma necessidade de cada um, cada um sabe o que é necessario) entao deveria ser feito antes de ir para o repositorio, na minha opiniao.

Se o cara depois de um tempo deve aceitar espaços em branco por um motivo qualquer, ao inves de ir em todas as classes de modelo, apenas vai na classe de negocio, retira o metodo que valida espaços e pronto, ta feito (dependendo de como ele programou, ne? se ele separar esse metodo de validação vindo de uma classe Utils, por exemplo é só tirar o metodo).

de acordo com o livro de certificação da autora: Kathy Sierra página 153 capitulo 2: “Encapsulated code has two features: Instance variables are kept protected (usually with the private modifier). ,Getter and setter methods provide access to instance variables.”

como te disse, get e set pra mim servem pra prover acesso às variaveis. Entre colocar no set ou get, voto no set. Ainda assim, acho que se isso pe algo que vc nao deve gravar, é regra de negocio e vc deveria colocar na camada referente.

gpmdf2 na 1ª mensagem eu falei que se ele fosse fazer essa verificação seria no SET e NAO NO GET vc não leu a minha 1ª mensagem.

[quote] …gpmdf2
ele pode no maximo usar algum teste no contrutor ou no “set” (acho mais correto no contrutor, no maximo) para validar os dados ainda na variavel (caso nao tenha sido gravado no repositorio, ou seja, assim que os dados forem inseridos no objetos criado, algo desse tipo)…[/quote]

Pra mim estaria de ótimo tamanho, simple e direto !!

[quote]
Se o espaço em branco é uma coisa que o BANCO nao pode aceitar, isso nao e regra de negocio, nao? Se nao e regra de negocio, é regra de GUI? regra do repositorio? da fachada? [/quote]
Não concordo que regra de negócio é TUDO que o BANCO não pode aceitar,acho sim que TUDO tem que ser analisado e NADA é absolutoe tbm porque depende de algo chamado NEGÓCIO…

Agora qual a responsabildiade deste simples objeto ? Guardar atributos e ter um monte de get/set que vc nem precisa de todos e jogar a responsabilidade de seus atributos serem preenchidos por outros objetos/camadas ?

luiz renato,

eu li sua mensagem. Quando eu disse que tava errado, estava me referindo a ser errado colocar no get.

eu tava pensando sobre a questão e li alguns artigos. Nunca pensei que esse assunto fosse reder tanto, mas tem ate artigos relacionados a isso. Inclusive quem usa hibernate sao os maiores defendores que coisas assim devem ser colocados no set, pelo que vi. entao depende muito da visao do cara.

Eu parei pra pensar e eu fui meio radical em falar que tudo deve ser colocado na camada de negocio, uma vez que apenas regras de negocio devem ser colocadas la. No entanto o nosso amigo falou tao enfaticamente que deveria ser retirados os espaços que eu pensei que fosse realmente uma regra.

Tem uma forma de fazer isso que pode resolver o problema, na GUI. Em algum ponto essa informacao é colocada numa caixa de texto qualquer e ai ao inves de pegar dessa forma :

caixaDeTexto.getText(), pq nao pega assim : caixaDeTexto.getText().trim() ?

Se vc nao quiser mudar a interface do programa, isso resolve. Se vc tiver uma GUI que mude (uma hora use num html, depois com j2se, depois d outra forma), nao use assim, pq vc vai ter que fazer em todas as interfaces.

Caso isso seja uma exigencia do negocio, coloque na camada de negocio (nao posso dizer se é ou nao).

Caso nao seja e quando vc for criar o objeto ja tiver com essa informação definida, coloque no construtor.

caso vc so tenha acesso a essa informacao depois ou ela mude e vc precise dar um update, use no set.

mas nao use no get porque aí é maquiagem sim. vc ta pegando um dado que foi aceito, entretanto foi aceito errado e quando vai expor ai usuario vc “da uma arrumadinha” numa coisa que teoricamente, se foi aceita, já tá certa.

Porisso que eu disse que era regra de negócio, porque ele disse que nao poderia aceitar de jeito nenhum. Se ele disse tao enfaticamente, entendi dessa forma. E porisso eu disse mais acima que nao posso dizer com certeza se é regra do negocio dele, porque eu nao sei o contexto do problema. Ele apenas disse que era um CRUD web, so isso.

Outra coisa… uma classe modelo tem a responsabilidade basica (claro, pode fazer mais coisas) de guardar atributos e comportamentos, modelando o objeto relacionado. Se nao se pudesse guardar nenhum objeto com atributos null, ´por exemplo, eu nao colocaria essa responsabilidade de verificação na classe basica de modelo, nao.

Quando fosse GRAVAR a camada de negocio deveria mostrar que tem alg coisa como null e reclamar. Dessa forma, se for algo relacionado ao negocio, um espaço pode sim ser verificado nessa camada. É uma regra tao simples como a que eu exemplifiquei com o null.

de qualquer forma, acho que já estao claras varias formas para se fazer isso sem usar essa do get. Inclusive formas bem elegantes. Acho que ja da p colocar como resolvido =). A maioria concordou com o set, entao coloca la, po.

Em poucas linhas:
É recomendável, e considerada uma boa prática, a inserção de códigos de tratamento tanto a nível de set como a nível de get.
Veja, por exemplo, a NFe. Tem tanto XML com dado gravado de forma incorreta, daí vc tem que validar tudo… Claro que é possível validar no set, mas em relação ao get é considerado vital quando se trata de dados extrangeiros.

Não é uma regra de negócio explícita na documentação do cliente a situação que apresentei ao postar a dúvida. No entanto, não faz sentido gravar com espaços no início e fim do campo. O cliente tem uma regra de negócio que não podem ser cadastrados 2 produtos com a mesma descrição. Se ele digitar " Caneta" será diferente se digitar “Caneta”.

Por isso, nossa preocupação com os espaços. Aí veio a dúvida: é uma boa prática ou não usar get e set para tal situação.

Pelas respostas entendi que não é uma má prática desde que não seja Regra de Negócio do cliente.

Obrigado.

Valeu a todos pelas respostas.