AO VALIDAR DADOS NO OO,TENHO DE USAR EXCE?ÕES?

MARCOS 31/12/2015 13:30:21
#455673
Bom dia,pessoal!
Estou me esforçando bastante para fazer meus próximos projetos somente com Orientação a Objeto.
Para tanto,pesquiso na Internet e também estou assistindo as ótimas aulas do Kerplunk no Youtube.
As dúvidas,são muitas.Neste momento peço ajuda com relação ao seguinte:

O caso:

Sempre que quero validar,um dado de entrada do usuário eu tenho o hábito de criar o código de validação
de modo tal que ,se o valor de entrada for indevido,eu abro uma [Ô]tela (formulário)[Ô] de mensagem,explicando
ao usuário que o dado é inválido,etc...
No entanto,eu percebi que vários colegas,inclusive o colega Kerplunk nas aulas,ao validar um dado de entrada,
prefere tratar o dado indevido como uma exceção.Inclusive criando uma classe especifica para lidar com as
exceções geradas pelo usuário.

Minha dúvida:

Ao se trabalhar com OO, é errado fazer como eu tenho feito. Ou seja, no código de validação , simplesmente abrir
um form (Tela), explicando ao usuário que o dado é indevido , etc...?
Existe algum motivo técnico, para lidar com esta situação gerando exceções no código???

Se algum colega puder esclarecer , fico grato
JABA 31/12/2015 13:57:26
#455674
Citação:

Ao se trabalhar com OO, é errado fazer como eu tenho feito. Ou seja, no código de validação , simplesmente abrir
um form (Tela), explicando ao usuário que o dado é indevido , etc...?
Existe algum motivo técnico, para lidar com esta situação gerando exceções no código???



Acho que sua dificuldade aí é porque ainda não entendeu o conceito de camadas. A camada de negócio é a representação abstrata do seu produto e onde só lida com a parte lógica da coisa, nada de telas ali. A responsabilidade de mostrar toda essa abstração fica à cargo da sua camada de apresentação, é aí que você tem que capturar as exceções da camada de negócio e emitir uma mensagem mais amigável para o usuário, que poderia ser através de um form, conforme já vem fazendo.
NILSONTRES 31/12/2015 16:56:21
#455678
Não sou a pessoa indicada para essa opinião, mas vou me aventurar, Acho que existe um certo exagero, nem tudo tem que ser OO.

JABA 31/12/2015 17:58:51
#455682
Citação:

Não sou a pessoa indicada para essa opinião, mas vou me aventurar, Acho que existe um certo exagero, nem tudo tem que ser OO.



NILSONTRES, posso estar enganado, mas acho que você disse isso pelo fato de não concordar com a criação de uma nova classe de exceção para tratar eventuais falhas. Mas isso não é uma obrigação, pois vai depender muito do que você quer realmente fazer. Na própria plataforma .Net existem milhares de classes de Exceções, criadas justamente para facilitar a nossa vida. Só que nem sempre existe uma que atenda perfeitamente o que queremos, por isso criamos uma.

E pra finalizar, nem todas as exceções devem chegar até a camada de apresentação. As vezes elas podem ser capturadas nas camadas mais baixas e serem tratadas por lá mesmo. Por exemplo, imagina que sua aplicação tente abrir uma conexão com a base de dados, só que ao fazer isso dispare uma exceção por algum motivo. Com isso, você pode deixar que essa exceção chegue até a camada de apresentação e mostre uma mensagem para o usuário, ou então, pode captura-la onde foi a causa do problema - no caso na camada de acesso a dados - e fazer uma nova tentativa. Assim, se houver uma conexão na segunda tentativa, o usuário jamais seria notificado, pois o problema foi tratado internamente.
KERPLUNK 01/01/2016 04:03:30
#455687
NILSONTRES, de modo bem simplificado, sim, em se tratando de .NET tudo deve ser feito sempre visando OOP.
Validação de dados é tarefa de uma camada intermediária, comumente chamada de [Ô]regras de negócio[Ô]. Por exemplo, suponhamos que o nome do cliente precise conter ao menos 3 caracteres. Essa é uma regra de negócio e deve ser consultada ao menos uma vez ao tentar gravar o cliente no banco de dados propriamente dito. Para isso, existem vários meios de se fazer. Pode-se por exemplo, criar um método [Ô]Validar[Ô] para uma entidade que faz a validação de todos os dados da entidade(no caso do exemplo, um cliente). Esse método pode retornar qualquer uma das exceções da regra de validação ou simplesmente uma exceção genérica com uma mensagem dizendo o que está errado, seja uma ou mais regras que não estejam satisfatórias. A criação de exceções customizadas, facilita na hora da captura no momento que a mesma deva ser exibida na tela, apesar de não ser obrigatório que se faça dessa maneira. Além disso, a captura de exceções, não somente de modo genérico, ajuda muito na resolução de problemas. Por exemplo, o método Open, da classe SqlConnection pode lançar(esse é o termo correto) 3 exceções quando invocado: InvalidOperationException, SqlException e ConfigurationErrorsException. Logo, o bloco try...catch onde a esse método for chamado, DEVERIA tratar essas 3 exceções ou no mínimo jogar de forma genérica para a camada superior. Algo como:

try
{
conexao.Open();
}
catch (InvalidOperationException)
{
throw;
}
catch(SqlException)
{
throw;
}
catch(ConfigurationErrorsException)
{
throw;
}
catch(Exception)
{
throw;
}


Na camada superior, ou seja, a camada que chamou o método em que esse bloco está, deve também implementar blocos try...catch para receber essas exceções e se necessário também lançá-las para a camada superior e assim substantivamente até que se chegue na camada onde o erro seria exibido, geralmente a UI, que também implementaria um bloco try...catch e exibiria o erro. O fato é que cada passo desse a propriedade StackTrace da exceção é atualizado, mostrando o caminho que o programa fez e o local específico onde o erro ocorreu especificamente, incluindo a linha de código de cada uma das chamadas. Veja o exemplo abaixo:

ConsoleApplication1.MyCustomException: some message .... ---> System.Exception: Oh noes!
at ConsoleApplication1.SomeObject.OtherMethod() in C:\ConsoleApplication1\SomeObject.cs:line 24
at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 18
at ConsoleApplication1.Program.DoSomething() in C:\ConsoleApplication1\Program.cs:line 23
at ConsoleApplication1.Program.Main(String[] args) in C:\ConsoleApplication1\Program.cs:line 13

Leia-o de baixo para cima: o método [Ô]Main[Ô] da aplicação console na linha 13 chamou o método [Ô]DoSomething[Ô]. O método DoSomething, na linha 23, instanciou a classe SomeObject. O construtor da classe SomeObject(ctor()), na linha 18, chamou o método [Ô]OtherMethod[Ô] que por sua vez, teve uma exceção na linha 24. Essa exceção foi lançada de dentro do método OtherMethod e é uma exceção customizada. Logo, verifique o que é feito na linha 24 do método [Ô]OtherMethod[Ô] da classe [Ô]SomeObject[Ô] e vai descobrir onde a exceção ocorreu e exatamente o que ocorreu, pois sendo uma exceção customizada, é algo que você já previu que poderia acontecer e é essa a principal utilidade de exceções customizadas, pois sendo elas classes, podem conter propriedades e métodos como qualquer outra classe. Propriedades e métodos esses que podem muito bem serem usados para resolver a exceção, não mostrando absolutamente nada ao usuário que nem sequer vai notar que algo errado ocorreu.

No exato momento em que a exceção é disparada, você pode gravar um log do problema, contendo tudo o que você necessitar para resolver. Mas nesse ponto, o stack trace ainda não vai existir dessa maneira, ele só vai estar com todos esses passos na última camada, geralmente a de apresentação.

Exceções pode parecer um assunto simples, mas realmente não é. é uma das coisas mais complexas do .NET pois pode ter nuances difíceis de serem interpretadas e muitas vezes ainda mais difíceis de serem resolvidas, mas o stack trace pode ajudar em muito. Principalmente em aplicações que não possuem uma camada de apresentação, como um WebService por exemplo.
LAMPIAO 01/01/2016 14:57:54
#455694
Fala rapaziada, feliz ano novo para todos, e que esse ano novo que se inicia seja de novas conquistas, saúde e paz para todos nós e essa humanidade que de uma forma geral anda meio fora do trilho.

Eu diria que para quem está iniciando agora na orientação a objetos seja difícil entender certos conceitos, principalmente quando se tenta aplicar os métodos que se usava no antigo VB6. Procedimento esse totalmente equivocado e que deve ser abolido totalmente, pois uma coisa não tem nada haver com a outra.

Validação disparando excessões eu diria que é a forma mais prática e simples de se utilizar na OO. Isso porque existem outras formas bem mais complexas de se fazer a mesma coisa.

Como o KERPLUNK já mencionou, tudo no .NET deve ser feito sempre visando OO. E como o JAVA citou, é necessário que se entenda o conceito da coisa toda.

Então eu sugiro que continue estudando e sobretudo pesquisando, principalmente pesquisando, uma hora você vai começar a ver tudo com mais clareza.

O que você já faz pode ser feito em um projeto/classe especifica para isso. A interface do usuário deve conter o mínimo de linhas de código possível, ela deve ser o mais leve possível e totalmente desacoplada, isso tornará a manutenção algo muito simples.

Não faça o que muitos fazem aqui, colocam tudo dentro de um botão, concatenam textbox's direto na consulta sql e outras coisas impressionantes as quais eu não entendo porque ainda fazem desse jeito, ai fica aquela coisa horrível, que dá até arrepios de ver.

Abraços.




KERPLUNK 01/01/2016 17:27:20
#455701
Pois é LAMPIAO. OOP é muito mais simples que a programação procedural. O que acontece realmente, em geral, é o não entendimento dela. é uma daquelas coisas que uma hora dá [Ô]um estalo[Ô] e você passa a entender tudo, tudinho mesmo. Já ajudei várias pessoas a ganharem esse [Ô]estalo[Ô] e tive que fazer de várias formas diferentes para cada um. A única coisa em comum que percebi é uma forte necessidade de ver código, tentar entender tudo olhando o código. Não sei bem porque, provavelmente faz com que a pessoa se sinta mais segura, pois se ainda não entende um conceito mais abstrato, pelo menos quer ver a parte mais concreta dela. é mais ou menos como um labirinto de tamanho real. A pessoa não consegue ver o labirinto de cima então quer pelo menos estar dentro dele para tentar sair. Quando você pega essa pessoa de dentro do labirinto e eleva, aí ela vai entender por completo que o que ela estava tentando fazer por tentativa e erro, não tem nem ao menos sentido. é mais ou menos isso a comparação de uma programação procedural com OOP, que aliás, é um dos alicerces fundamentais de TODA a tecnologia .NET, logo, usar OOP com ela é seguir um caminho já trilhado e verificado como correto.
MARCOS 03/01/2016 17:20:53
#455713
Bom dia!!
Ao postar este tópico,Estou aprendendo muito com os colegas.
Não consigo absorver tudo de imediato,pois sou novato em OO e
programei do modo estruturado a vida toda.

Então,peço paciência aos colegas:

1.) Digamos,que eu tenho uma propriedade na classe Cliente, chamada idade.Por algum motivo eu quero que somente se possa entrar com idade de 20 até 30 .
Pelo que eu entendi,se eu criar uma rotina para validar o valor desta propriedade,dentro da propriedade,eu não posso de dentro da mesma,emitir uma mensagem
ao usuário,dizendo que a idade de entrada esta indevida (Quando estiver).Pelo que entendi,eu devo tratar isto como uma exceção e [Ô]lançar[Ô] para o nível acima.Esta
correto???

2.) Nos cursos ,o colega Kerplunk,aconselha que ao se conectar um Banco de Dados.Se use uma estrutura [Ô]Try/Catch[Ô] separada , para cada operação,como
abrir o Banco (Con.Open),e outras.Eu não entendo o motivo,pois se eu tenho o código todo ,dentro de apenas uma estrutura,eu capturo as
exceções do mesmo modo.Existem alguma explicação?

KERPLUNK 03/01/2016 17:31:20
#455717
Resposta escolhida
1 - Exatamente.
2 - A explicação está nas minhas respostas anteriores. Considere que métodos podem retornar exceções. O bloco try...catch, deve tratar cada exceção possível de cada método coberto no bloco try. Então se você tiver uns 4 ou 5 métodos, cada um lançando umas 5 exceções diferentes, você vai ter que ter uma [Ô]tripa[Ô] de blocos catch tratando cada uma delas e isso fica muito grande e de difícil leitura. Mas tecnicamente nada impede de ser feito.
MARCOS 08/01/2016 09:11:26
#455889
Muito obrigado a todos pelos esclarecimentos.
A medida que vou aprendendo,vou implementando
tudo nos meus projetos daqui em diante.
Tópico encerrado , respostas não são mais permitidas