ESTA CLASSE E PROFISSIONAL?

MARCOS 05/10/2012 12:41:56
#411358
Prezados colegas,
Depois de postar alguns tópicos sobre minhas dúvidas na criação de uma classe
para acessar o SGBD(Classe DAL),aprendi bastante com as dicas dos colegas.
Estou postando uma nova classe que fiz como resultado do que aprendi.Peço aos colegas
o seu parecer profissional a respeito da qualidade da classe.


Obs: Por favor,Desconsidere o tratamento de erros,pois só deverei cuidar disto depois.


------------------------------------------------------------------------------------------------------------------------------------------------------------

Imports System.Data.SqlClient

Public Class ClFonteDados

[ô]-----------------------
[ô]Declaração de variáveis
[ô]-----------------------
#Region [Ô]Declaração de variáveis[Ô]

Dim StringDeConexao As String
Dim Con As SqlConnection
Dim Adap As SqlDataAdapter
Dim Cmd As SqlCommand
Dim Dt As DataSet

#End Region

[ô]----------
[ô]Construtor
[ô]----------
#Region [Ô]Construtor[Ô]

Public Sub New()

[ô]------------------------
[ô]Define String de conexão
[ô]------------------------

[ô]Sql Server
StringDeConexao = [Ô][Ô]

End Sub

#End Region


#Region [Ô]Create[Ô]

Public Function Create(ByVal RefNome As String, ByVal RefEnd As String, ByVal RefTel As String) As Boolean

Try

[ô]Cria objeto conexão
Con = New SqlConnection(StringDeConexao)

[ô]Verifica conexão
Select Case Con.State

Case Is = ConnectionState.Closed

[ô]Abre conexão
Con.Open()

[ô]Cria objeto de comando
Cmd = New SqlCommand([Ô]Create[Ô], Con)

[ô]Define tipo de comando
Cmd.CommandType = CommandType.StoredProcedure

[ô]Adiciona parâmetros
Cmd.Parameters.AddWithValue([Ô]@nome[Ô], RefNome)
Cmd.Parameters.AddWithValue([Ô]@End[Ô], RefEnd)
Cmd.Parameters.AddWithValue([Ô]@Tel[Ô], RefTel)

[ô]Executa
Cmd.ExecuteNonQuery()

[ô]Retorna valor
Return True

Case Else

[ô]Retorna valor
Return False

End Select


Catch ex As Exception

[ô]Registra Log exceção
[ô]Log

[ô]-------------
[ô]Trata Exceção
[ô]-------------

[ô]Retorna valor
Return False

Finally

[ô]Fecha conexão
Select Case Con.State
Case Is = ConnectionState.Open

Con.Close()

Case Else
End Select

[ô]Descarta objetos
Con.Dispose()
Cmd.Dispose()

End Try


End Function


#End Region


#Region [Ô]Read[Ô]

Public Function Read(ByVal RefNome As String, ByVal RefEnd As String, ByVal RefTel As String) As DataSet

Try

[ô]Cria objeto conexão
Con = New SqlConnection(StringDeConexao)

[ô]Verifica conexão
Select Case Con.State

Case Is = ConnectionState.Closed

[ô]Abre conexão
Con.Open()

[ô]Cria objeto DataAdapter
Adap = New SqlDataAdapter([Ô]Read[Ô], Con)

[ô]Cria objeto DataSet
Dt = New DataSet

[ô]Transfere dados
Adap.Fill(Dt, [Ô]Tb_Cliente[Ô])

[ô]Retorna valor
Return Dt

Case Else

[ô]Retorna valor
Return Nothing

End Select


Catch ex As Exception

[ô]Registra Log exceção
[ô]Log

[ô]-------------
[ô]Trata Exceção
[ô]-------------

[ô]Retorna valor
Return Nothing

Finally

[ô]Fecha conexão
Select Case Con.State
Case Is = ConnectionState.Open

Con.Close()

Case Else
End Select

[ô]Descarta objetos
Con.Dispose()
Cmd.Dispose()

End Try


End Function


#End Region




#Region [Ô]Update[Ô]

Public Function Update(ByVal RefCod As Integer, ByVal RefNome As String, ByVal RefEnd As String, ByVal RefTel As String) As Boolean

Try

[ô]Cria objeto conexão
Con = New SqlConnection(StringDeConexao)

[ô]Verifica conexão
Select Case Con.State

Case Is = ConnectionState.Closed

[ô]Abre conexão
Con.Open()

[ô]Cria objeto de comando
Cmd = New SqlCommand([Ô]Update[Ô], Con)

[ô]Define tipo de comando
Cmd.CommandType = CommandType.StoredProcedure

[ô]Adiciona parâmetros
Cmd.Parameters.AddWithValue([Ô]@Cod[Ô], RefCod)
Cmd.Parameters.AddWithValue([Ô]@nome[Ô], RefNome)
Cmd.Parameters.AddWithValue([Ô]@End[Ô], RefEnd)
Cmd.Parameters.AddWithValue([Ô]@Tel[Ô], RefTel)

[ô]Executa
Cmd.ExecuteNonQuery()

[ô]Retorna valor
Return True

Case Else

[ô]Retorna valor
Return False

End Select


Catch ex As Exception

[ô]Registra Log exceção
[ô]Log

[ô]-------------
[ô]Trata Exceção
[ô]-------------

[ô]Retorna valor
Return False

Finally

[ô]Fecha conexão
Select Case Con.State
Case Is = ConnectionState.Open

Con.Close()

Case Else
End Select

[ô]Descarta objetos
Con.Dispose()
Cmd.Dispose()

End Try


End Function

#End Region

#Region [Ô]Delete[Ô]

Public Function Delete(ByVal RefCod As Integer) As Boolean

Try

[ô]Cria objeto conexão
Con = New SqlConnection(StringDeConexao)

[ô]Verifica conexão
Select Case Con.State

Case Is = ConnectionState.Closed

[ô]Abre conexão
Con.Open()

[ô]Cria objeto de comando
Cmd = New SqlCommand([Ô]Delete[Ô], Con)

[ô]Define tipo de comando
Cmd.CommandType = CommandType.StoredProcedure

[ô]Adiciona parâmetros
Cmd.Parameters.AddWithValue([Ô]@Cod[Ô], RefCod)

[ô]Executa
Cmd.ExecuteNonQuery()

[ô]Retorna valor
Return True

Case Else

[ô]Retorna valor
Return False

End Select


Catch ex As Exception

[ô]Registra Log exceção
[ô]Log

[ô]-------------
[ô]Trata Exceção
[ô]-------------

[ô]Retorna valor
Return False

Finally

[ô]Fecha conexão
Select Case Con.State
Case Is = ConnectionState.Open

Con.Close()

Case Else
End Select

[ô]Descarta objetos
Con.Dispose()
Cmd.Dispose()

End Try

End Function

#End Region

End Class
KERPLUNK 05/10/2012 13:33:59
#411366
Resposta escolhida
Este é um exemplo perfeito da classe [Ô]Deus[Ô], aquela que faz tudo

Amigo, entenda bem OOP e vai ver que quanto mais especializada a classe, mellhor
KERPLUNK 05/10/2012 14:17:31
#411375
Mas enfim, está chegando perto, o que falta agora, é parar de passar os DataTable diretamente ao invés disso, use Listas de objetos(classes). Também não use DataTable para ler dados, use DataReader, um objeto especializado em [Ô]ler[Ô] dados.
GUIMORAES 05/10/2012 14:44:19
#411385
Marcos, como o Kerplunk disse, está quase lá.
Percebi que você usa as variaveis RefCod,RefNome,RefEnd,RefTel como parametro.
Porque você não cria uma classe para elas, e instancia a mesma.
Ex:

[ô]Classe cliente
public class clsCliente

Public Property nome as string
Public Property end as string
Public Property tel as string

end class

[ô]Seu metodo
Public Function Create(byval c as clsCliente) As Boolean

Try

[ô]Cria objeto conexão
Con = New SqlConnection(StringDeConexao)

[ô]Verifica conexão
Select Case Con.State

Case Is = ConnectionState.Closed

[ô]Abre conexão
Con.Open()

[ô]Cria objeto de comando
Cmd = New SqlCommand([Ô]Create[Ô], Con)

[ô]Define tipo de comando
Cmd.CommandType = CommandType.StoredProcedure

[ô]Adiciona parâmetros
Cmd.Parameters.AddWithValue([Ô]@nome[Ô],c.nome)
Cmd.Parameters.AddWithValue([Ô]@End[Ô], c.end)
Cmd.Parameters.AddWithValue([Ô]@Tel[Ô], c.tel)

[ô]Executa
Cmd.ExecuteNonQuery()

[ô]Retorna valor
Return True

Case Else

[ô]Retorna valor
Return False

End Select


Catch ex As Exception

[ô]Registra Log exceção
[ô]Log

[ô]-------------
[ô]Trata Exceção
[ô]-------------

[ô]Retorna valor
Return False

Finally

[ô]Fecha conexão
Select Case Con.State
Case Is = ConnectionState.Open

Con.Close()

Case Else
End Select

[ô]Descarta objetos
Con.Dispose()
Cmd.Dispose()

End Try


End Function

Com isso, você poderá implementar uma lista de objetos, para retornar suas pesquisas.

Abraços





MARCOS 05/10/2012 17:14:58
#411399
Boa tarde,Colegas!
Irei modificar a Classe,seguindo as orientações que os colegas citaram acima...

No entanto,como não gosto de fazer nada sem entender o que estou fazendo,peço aos colegas me esclarecer o seguinte:

Pergunta ao colega KERPlLUNK:

a.) Quando você explica que devo usar [Ô]DataReader[Ô] e não [Ô]DataTable[Ô].é por causa somente da Performance do DataReader ser melhor,ou existe outro motivo?

b.) Eu não entendi a questão da Especialização da classe.Eu sei o que é especialização em OO. Como eu fiz a classe para lidar [Ô]Somente[Ô] com a tabela [Ô]Tb_Cliente[Ô]
Pensei que estava seguindo a regra de usar uma Classe DAL para cada tabela. Você poderia explicar porque a classe não é especializada o suficiente???


Pergunta ao colega GUIMORAES123:

a.) A Classe que sugeriu que eu crie. Pode também funcionar como a [Ô]classe de Dados[Ô] ??

b) Qual a grande desvantagem em se passar os parâmetros do modo como passei.Porque é tão importante passar os parâmetros por meio de objetos???



Fico aguardando a resposta dos colegas,para fazer as mudanças de modo mais consciente.
KERPLUNK 05/10/2012 17:55:33
#411403
Citação:

a.) Quando você explica que devo usar [Ô]DataReader[Ô] e não [Ô]DataTable[Ô].é por causa somente da Performance do DataReader ser melhor,ou existe outro motivo?


Sim, principalmente quanto à performance e objetividade. DataTable, disponibiliza funcionalidades que não são necessárias para a leitura, onerando em muito o seu sistema

Citação:

b.) Eu não entendi a questão da Especialização da classe.Eu sei o que é especialização em OO. Como eu fiz a classe para lidar [Ô]Somente[Ô] com a tabela [Ô]Tb_Cliente[Ô]
Pensei que estava seguindo a regra de usar uma Classe DAL para cada tabela. Você poderia explicar porque a classe não é especializada o suficiente???


Sim, você está usando essa classe exclusivamente para tratar de uma tabela, porém a maneira como está sendo feita, ainda deixa marge para SQL Injection e outros problemas. O ideal é, por exemplo, no método [Ô]Inserir[Ô], ao invés de passar os valores como parâmetros, use como parâmetro uma classe que representa o dado a ser inserido, no caso, um Cliente.
MARCOS 06/10/2012 14:11:23
#411448
Boa tarde,Pessoal.
Baseado na resposta do KERPLUNK e dos outros colegas,irei refazer minha classe e tornar a postar ela em breve
para uma nova análise dos colegas.

Maas,antes de colocar a mão na massa e refazer a classe,quero perguntar se no caso de uma classe DAL ,como esta
é interessante que ela tenha propiedades???Se é ,que propiedades seria bom que ela tivesse para ficar mais profissional????
KERPLUNK 07/10/2012 22:00:31
#411473
Não se concentre apenas na DAL, as classes de entidades também são importantes....
MARCOS 08/10/2012 15:02:20
#411533
Olá,Kerlumk!
Sim,eu sei que as classes de entidades são importantes.Mas,como terei de refazer a classe DAL,baseado nas mudanças
sugeridas pelos colegas,queria aproveitar e mudar o que mais fosse necessário.Por isto estou pensando na possibilidade
de colocar propiedades na classe DAL (Pensei ,por exemplo,em colocar uma propiedade chamada [Ô]StringdeConexao[Ô],para
permitir ao usuário da classe,definir uma String de conexão diferente se for o caso.

Por isto,pergunto.Pode-se colocar propiedades numa classe DAL,ou elas devem em uma aplicação profissional OO, ter
somente métodos???
KERPLUNK 08/10/2012 15:20:37
#411537
Citação:

Por isto,pergunto.Pode-se colocar propiedades numa classe DAL,ou elas devem em uma aplicação profissional OO, ter
somente métodos???


Bem, eu, pessoalmente, quando preciso desenvolver aplicações multi-banco, costumo criar uma classe que busca o banco de dados dinamicamente de arquivos de configuração, geralmente XML encriptados, mas em alguns casos, busco de webservices.
Não costumo usar propriedades na classe DAL, quando preciso de algum valor, são as entidades que devem fornecer. Se o valor é uma configuração qualquer, deve existir uma entidade [Ô]Configuração[Ô], que tem sua respectiva classe DAL que busca os dados de onde quer que seja.
MARCOS 10/10/2012 09:58:12
#411693
Muito obrigado pelas orientações pessoal!!!

Irei refazer a classe,e tornarei a postar aqui para uma nova avaliação dos colegas....
Tópico encerrado , respostas não são mais permitidas