INICIO EM POO DE VERDADE AGORA RS
Boa tarde amigos.
Após várias tentativas frustradas de iniciar. Arrumei um projeto onde não tenho nada pronto, e melhor oportunidade para iniciar meu aprendizado do que esta.
Então com base em um pouco de curiosidade em alguns tópicos que sempre estou vendo e o básico que vi num curso montei o inicio do meu primeiro cadastro.
Queria que voces me dessem a opiniao se estou no caminho certo, sugestões de melhorias e tal.
Segue abaixo minhas classes.
Um teste através de um botão qualquer:
Está muito ruim ? Bom? Aceitável ?
Testei e funcionou rs.
Abraços !
Após várias tentativas frustradas de iniciar. Arrumei um projeto onde não tenho nada pronto, e melhor oportunidade para iniciar meu aprendizado do que esta.
Então com base em um pouco de curiosidade em alguns tópicos que sempre estou vendo e o básico que vi num curso montei o inicio do meu primeiro cadastro.
Queria que voces me dessem a opiniao se estou no caminho certo, sugestões de melhorias e tal.
Segue abaixo minhas classes.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using System.Data;
namespace FBGMedic
{
public class databases
{
private string err;
static public MySqlConnection conexao;
public string conectaMySql()
{
try
{
// tentando conectar na base de dados
string strCon = [Ô]Server=192.168.0.114;Database=teste;Uid=root;Pwd=[ô]aaaaaa[ô];Connect Timeout=30;[Ô];
conexao = new MySqlConnection (strCon);
conexao.Open();
}
// aqui retorna o erro
catch (MySqlException erro)
{
this.err = erro.Message;
}
// verifica se a conexao foi aberta com sucesso
if (conexao.State == ConnectionState.Open)
{
return [Ô]Conectou[Ô];
}
else
{
conexao.Close();
return this.err;
}
}
}
// inicia a classe insercao
public class insert : databases
{
private string err;
private string sql;
public string insert_dados(string campos,string valores,string tabela)
{
MySqlCommand insert = new MySqlCommand();
try
{
// MONTANDO A SQL PASSADA PELO FORM
insert.Connection = conexao;
this.sql = [Ô]INSERT INTO [Ô] + tabela + [Ô] ([Ô];
this.sql = this.sql + campos + [Ô]) VALUES ([Ô];
this.sql = this.sql + valores + [Ô])[Ô];
insert.CommandText = this.sql;
insert.ExecuteNonQuery();
return [Ô]Dados inseridos com sucesso![Ô];
}
catch (MySqlException erro)
{
this.err = erro.Message;
return this.err;
}
}
}
}
Um teste através de um botão qualquer:
private void cmdGravar_Click(object sender, EventArgs e)
{
if (txtCodigo.TextLength == 0)
{
if (MessageBox.Show([Ô]Deseja realmente inserir este registro?[Ô], [Ô]ATENÇÃO![Ô], MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
// aqui conectamos a base de dados
databases conecta = new databases();
if (conecta.conectaMySql() != [Ô]Conectou[Ô])
{
}
else
{
// aqui instanciamos a classe insert
insert metodo_inserir = new insert();
// aqui utilizamos o metodo de insercao de dados
string retorno;
retorno = metodo_inserir.insert_dados([Ô]razao[Ô], [Ô][ô]teste[ô][Ô], [Ô]cliente[Ô]);
MessageBox.Show(retorno);
}
}
}
else
{
if (MessageBox.Show([Ô]Deseja realmente alterar este registro?[Ô], [Ô]ATENÇÃO![Ô], MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
}
else
{
}
}
}
Está muito ruim ? Bom? Aceitável ?
Testei e funcionou rs.
Abraços !
Sinceramente, está entre ruim e aceitável. Sugiro que dê uma olhada no tópico fixo que tem no topo do fórum, tem muita coisa interessante lá.
Pontos a ponderar:
1 - A própria string de conexão é um objeto e deve ser tratado como tal
2 - Para cada objeto, uma classe correspondente com a estrutura de dados da tabela deve ser criada e não um método genérico em que você concatena valores para insert.
3 - Concatenação de SQL é uma falha grave e não deve jamais ser utilizada, ao invés disso, use parametrização de comandos
Mas muito legal a iniciativa de melhorar! Precisando estamos ae para ajudar!
Pontos a ponderar:
1 - A própria string de conexão é um objeto e deve ser tratado como tal
2 - Para cada objeto, uma classe correspondente com a estrutura de dados da tabela deve ser criada e não um método genérico em que você concatena valores para insert.
3 - Concatenação de SQL é uma falha grave e não deve jamais ser utilizada, ao invés disso, use parametrização de comandos
Mas muito legal a iniciativa de melhorar! Precisando estamos ae para ajudar!
Ola Kerplunk
Primeiramente, obrigado pela resposta. Darei uma olhada no topico.
Mas tenho alguma sduvidas.
1- se um dos objetivos da poo é aproveitamento de codigo, a maneira que fiz reduziria muito o volume de codigos. Ebtao porque é uma falha?
2- Nao entendi o que voce quis dizer na parte da string de conexao.
3- Se eu for montar uma classe para cada informacao que eu for inserir em cada tabela, nao vi mudancas po eqto na POO.um pouco suas colocaçoes rsrs.
Desculpe se as perguntas parecem grosseiras, nao e minha intencao. Mas me confundiu
Primeiramente, obrigado pela resposta. Darei uma olhada no topico.
Mas tenho alguma sduvidas.
1- se um dos objetivos da poo é aproveitamento de codigo, a maneira que fiz reduziria muito o volume de codigos. Ebtao porque é uma falha?
2- Nao entendi o que voce quis dizer na parte da string de conexao.
3- Se eu for montar uma classe para cada informacao que eu for inserir em cada tabela, nao vi mudancas po eqto na POO.um pouco suas colocaçoes rsrs.
Desculpe se as perguntas parecem grosseiras, nao e minha intencao. Mas me confundiu
Vamos ver se consigo explicar...
Primeiro você criou uma classe database, porém você deixou a conexão estática, então qual o sentido de se poder instanciar vários objetos database se todos eles vão usar a mesma conexão? Objetos devem ser reusáveis e geralmente se espera que criando um novo objeto você vai ter isso, um novo objeto totalmente diferente do anterior que foi criado.
Depois você criou uma classe insert que herda de database, só que esta classe serve apenas para uma função, que é inserir dados no banco de dados, e isso poderia simplesmente ser uma função da classe database.
Você deve pensar em classes como se fossem objetos reais, por exemplo eu tenho uma caneta, eu crio uma classe para representar esta Caneta, se eu quero que ela escreva eu não vou criar uma classe nova para escrever, pois escrever não é um objeto, escrever é uma função da Caneta, então eu criaria um método escrever nesta Caneta.
Você pode perguntar então quando eu criaria um novo objeto herdando de Caneta, e isso seria quando ele mudasse fisicamente, por exemplo eu poderia criar uma classe chamada CanetaHidrografica, pois ela é exatamente uma Caneta, mas mudou a forma que ela libera a tinta. Quem usa a Caneta não precisa aprender a usar ela de novo pois ela funciona exatamente como a outra Caneta então qualquer lugar que precise de uma Caneta deve funcionar com a CanetaHidrografica.
Com o banco de dados pode ser a mesma coisa, eu tenho uma classe Database. A função do Database (não entrando nos especÃficos da implementação) é fazer inserts, updates, deletes e selects, então isso devem ser funções desta classe.
Dai eu preciso conectar em um MySQL, então eu posso herdar Database e criar uma classe chamada MySqlDatabase e nela implementar as funções de forma que funcionem no MySQL. Assim no programa se ele sabe usar o Database ele vai aceitar um MySqlDatabase sem problemas. Eu poderia então criar outras opções como SQLServerDatabase entre outros.
O importante ai é você perceber que herança deve geralmente significar [Ô]é um[Ô]
Primeiro você criou uma classe database, porém você deixou a conexão estática, então qual o sentido de se poder instanciar vários objetos database se todos eles vão usar a mesma conexão? Objetos devem ser reusáveis e geralmente se espera que criando um novo objeto você vai ter isso, um novo objeto totalmente diferente do anterior que foi criado.
Depois você criou uma classe insert que herda de database, só que esta classe serve apenas para uma função, que é inserir dados no banco de dados, e isso poderia simplesmente ser uma função da classe database.
Você deve pensar em classes como se fossem objetos reais, por exemplo eu tenho uma caneta, eu crio uma classe para representar esta Caneta, se eu quero que ela escreva eu não vou criar uma classe nova para escrever, pois escrever não é um objeto, escrever é uma função da Caneta, então eu criaria um método escrever nesta Caneta.
Você pode perguntar então quando eu criaria um novo objeto herdando de Caneta, e isso seria quando ele mudasse fisicamente, por exemplo eu poderia criar uma classe chamada CanetaHidrografica, pois ela é exatamente uma Caneta, mas mudou a forma que ela libera a tinta. Quem usa a Caneta não precisa aprender a usar ela de novo pois ela funciona exatamente como a outra Caneta então qualquer lugar que precise de uma Caneta deve funcionar com a CanetaHidrografica.
Com o banco de dados pode ser a mesma coisa, eu tenho uma classe Database. A função do Database (não entrando nos especÃficos da implementação) é fazer inserts, updates, deletes e selects, então isso devem ser funções desta classe.
Dai eu preciso conectar em um MySQL, então eu posso herdar Database e criar uma classe chamada MySqlDatabase e nela implementar as funções de forma que funcionem no MySQL. Assim no programa se ele sabe usar o Database ele vai aceitar um MySqlDatabase sem problemas. Eu poderia então criar outras opções como SQLServerDatabase entre outros.
O importante ai é você perceber que herança deve geralmente significar [Ô]é um[Ô]
Ola pessoal.
Obrigado pela resposta OCELOT.
Concordo que a organização fica bem melhor. Mas confesso que esperava alguma coisa de diminuição de código com a POO.
Então para cada cadastro, ou operação tenho que criar uma classe pra isso ?
Tipo
Class orcamento
dentro dela, inserir cabecalho, inseriritem, apagaritem
E por aà vai ?
O mesmo seria com consulta para povoar um grid por exemplo ?
Obrigado pela resposta OCELOT.
Concordo que a organização fica bem melhor. Mas confesso que esperava alguma coisa de diminuição de código com a POO.
Então para cada cadastro, ou operação tenho que criar uma classe pra isso ?
Tipo
Class orcamento
dentro dela, inserir cabecalho, inseriritem, apagaritem
E por aà vai ?
O mesmo seria com consulta para povoar um grid por exemplo ?
A diminuição é código é algo meio relativo, dependendo de como você fizer pode diminuir muito o código no seu formulário por exemplo, mas ele vai estar em algum outro lugar, em alguma outra camada do seu programa, afinal dificilmente você elimina algum código, no máximo ele vai se tornar reusável. A diminuição de código vem mais com a eliminação da repetição do mesmo código. Se você se ver tendo de escrever o mesmo código em mais de um lugar então você tem algo errado e deveria tentar tornar este código que é usado em vários lugares um só.
E se pretende fazer em camadas você precisa aprender a fazer separações no seu código dando a cada um a sua responsabilidade, se algo não faz parte da sua responsabilidade geralmente ele não deve nem saber que aquilo existe.
Você pode precisar mesmo criar métodos para cada tipo de cadastro que tenha, pois isso é algo especÃfico de cada lugar, ou pode fazer algo mais genérico só que assim você perde a separação e coloca a responsabilidade de saber fazer isso em outro lugar.
Por exemplo, se tenho 3 camadas, a interface gráfica, a lógica e o acesso a dados.
Se eu faço o acesso a dados muito genérico a lógica pode acabar tendo que saber quais campos pedir e como passar os valores para o banco de dados, ou eu poderia fazer coisas mais especÃficas na camada de acesso a dados e a lógica só precisa chamar ela que ela cuida de tudo. Então se eu diminuo o código em um lado eu aumento no outro e não tem muito o que fazer quanto a isso pois eu preciso deste código.
Isso vale também para o caso da consulta povoar o grid, se você fizer o acesso a dados povoar o grid diretamente você está amarrando a interface ao acesso a dados, coisa que ele não deveria saber que existe, o ideal é que um não conhecesse o outro, inclusive a lógica não deveria saber que existe um grid, ele deveria saber apenas que a interface precisa dos dados, então a lógica pede os dados para a classe de acesso a dados e repassa para a interface, ela é que deveria saber como preencher o grid.
Eu não recomendo a ninguém tentar fazer a sua própria separação de camadas ou tentar criar as próprias classes de acesso a dados, para a separação de camadas acho muito melhor você aprender algum design pattern tipo MVC ou MVP, existem vários as vezes com variações dentro deles mesmo e vai de cada um encontrar o que melhor se adapta, pode ser que você encontre frameworks pontos que facilitam o uso destes patterns mas na maioria das vezes depois que você entende como funcionam pode até mesmo criar o seu próprio framework, ou nem mesmo usar um framework, é que geralmente o uso destes frameworks ajudam a obrigar o uso das suas regras.
Já para acesso a dados recomendo usar algum mapeador ORM tipo EntityFramework ou algum outro qualquer, eu por exemplo uso uma versão modificada do Xpo da DevExpress que acho muito bom, porém é pago.
Fazer estas separações corretamente não é algo que se aprende da noite para o dia, da trabalho entender no começo e pode até parecer que ele aumenta o seu trabalho e até que deixa o código maior, só que com o tempo você começa a acostumar com isso vai ficando mais fácil, mais organizado e a manutenção no código se torna algo muito mais simples.
E se pretende fazer em camadas você precisa aprender a fazer separações no seu código dando a cada um a sua responsabilidade, se algo não faz parte da sua responsabilidade geralmente ele não deve nem saber que aquilo existe.
Você pode precisar mesmo criar métodos para cada tipo de cadastro que tenha, pois isso é algo especÃfico de cada lugar, ou pode fazer algo mais genérico só que assim você perde a separação e coloca a responsabilidade de saber fazer isso em outro lugar.
Por exemplo, se tenho 3 camadas, a interface gráfica, a lógica e o acesso a dados.
Se eu faço o acesso a dados muito genérico a lógica pode acabar tendo que saber quais campos pedir e como passar os valores para o banco de dados, ou eu poderia fazer coisas mais especÃficas na camada de acesso a dados e a lógica só precisa chamar ela que ela cuida de tudo. Então se eu diminuo o código em um lado eu aumento no outro e não tem muito o que fazer quanto a isso pois eu preciso deste código.
Isso vale também para o caso da consulta povoar o grid, se você fizer o acesso a dados povoar o grid diretamente você está amarrando a interface ao acesso a dados, coisa que ele não deveria saber que existe, o ideal é que um não conhecesse o outro, inclusive a lógica não deveria saber que existe um grid, ele deveria saber apenas que a interface precisa dos dados, então a lógica pede os dados para a classe de acesso a dados e repassa para a interface, ela é que deveria saber como preencher o grid.
Eu não recomendo a ninguém tentar fazer a sua própria separação de camadas ou tentar criar as próprias classes de acesso a dados, para a separação de camadas acho muito melhor você aprender algum design pattern tipo MVC ou MVP, existem vários as vezes com variações dentro deles mesmo e vai de cada um encontrar o que melhor se adapta, pode ser que você encontre frameworks pontos que facilitam o uso destes patterns mas na maioria das vezes depois que você entende como funcionam pode até mesmo criar o seu próprio framework, ou nem mesmo usar um framework, é que geralmente o uso destes frameworks ajudam a obrigar o uso das suas regras.
Já para acesso a dados recomendo usar algum mapeador ORM tipo EntityFramework ou algum outro qualquer, eu por exemplo uso uma versão modificada do Xpo da DevExpress que acho muito bom, porém é pago.
Fazer estas separações corretamente não é algo que se aprende da noite para o dia, da trabalho entender no começo e pode até parecer que ele aumenta o seu trabalho e até que deixa o código maior, só que com o tempo você começa a acostumar com isso vai ficando mais fácil, mais organizado e a manutenção no código se torna algo muito mais simples.
Caro OCELOT, novamente agradeço sua paciência e atençao em responder meu tópico. Suas explicações foram muito esclarecedoras!!
Estou começando a entender e visualizar meu futuro próximo em codificação com essas situações da POO.
Para evitar o tumulto no fórum, vou encerrar este tópico e comecei a postar no tópico em destaque sobre este assunto.
Se puder dar uma olhada na minha última postagem em http://www.vbmania.com.br/pages/index.php?varModulo=Forum&varMethod=abrir&varID=423042&varPagina=10#bottom
Abraços !!
Estou começando a entender e visualizar meu futuro próximo em codificação com essas situações da POO.
Para evitar o tumulto no fórum, vou encerrar este tópico e comecei a postar no tópico em destaque sobre este assunto.
Se puder dar uma olhada na minha última postagem em http://www.vbmania.com.br/pages/index.php?varModulo=Forum&varMethod=abrir&varID=423042&varPagina=10#bottom
Abraços !!
Tópico encerrado , respostas não são mais permitidas