Pergunta

Eu sou um autodidata programador VB6 que usa DAO. Abaixo está um exemplo de uma peça típica do código que eu poderia despejar:

Sub cmdMultiplier_Click()  'Button on form, user interface ' 
  dim Rec1 as recordset
  dim strSQL as string

  strSQL = "select * from tblCustomers where ID = " & CurrentCustomerID  'inline SQL '
  set rec1 = GlobalDataBase.openrecordset(strSQL)    ' Data access '

  if rec1.bof <> true or rec1.eof <> true then
    if rec1.fields("Category").value = 1 then
      PriceMultiplier = 0.9         ' Business Logic ' 
    else
      priceMultiplier = 1
    end if
 end if
End Sub

Por favor, fingir que o acima é todo o código-fonte de um aplicativo CRUD. Eu sei que este projeto é ruim, tudo é misturado juntos. Idealmente, deve ter três camadas distintas, interface do usuário, lógica de negócios e os dados de acesso. Eu meio-de get por que isso é desejável, mas eu não sei como ele é feito e eu suspeito É por isso que eu não entendo completamente por que tal separação é bom. Eu acho que seria muito mais abaixo na estrada, se alguém poderia refatorar acima ridiculamente exemplo trivial em 3 camadas.

Foi útil?

Solução

Um exemplo trivial, sim, mas com todos os elementos básicos - eles só pertencem em 3 classes diferentes (veja abaixo). A principal razão para isto é a "separação de interesses" princípio, ou seja, a GUI é apenas preocupado com GUI coisas, a camada Biz Logic é apenas preocupado com as regras de negócio, ea camada de acesso a dados só está preocupado com representações de dados. Isto permite que cada camada a ser mantido de forma independente e reutilizado em aplicações:

'in Form class - button handler
Sub cmdMultiplier_Click()
    PriceMultiplier = ComputePriceMultiplier(CurrentCustomerId)
End Sub

'in Biz Logic class
Function ComputePriceMultiplier(custId as Integer) as Double
    Dim cust as Customer = GetCustomer(custId)
    if cust.Category = 1 then   'please ignore magic number, real code uses enums
        return 0.9
    end if
    return 1
End Function

'in Data Access Layer class
Function GetCustomer(custId as Integer) as Customer
    Dim cust as Customer = New Customer    'all fields/properties to default values
    Dim strSQL as String = "select * from tblCustomers where ID = " & custId
    set rec1 = GlobalDataBase.openrecordset(strSQL)    ' Data access '
    if rec1.bof <> true or rec1.eof <> true then
        cust.SetPropertiesFromRecord(rec1)
    end if
    return cust
End Function

[uma aplicação 'real' seria armazenar em cache o cliente atual, têm constantes ou procedimentos armazenados para a consulta do cliente, etc .; ignorado por brevidade]

Contraste isso com o seu exemplo original tudo-em-o-botão-manipulador (que é assustadoramente comum em código VB, porque é tão fácil de fazer isso dessa maneira) - se necessário a regra do preço-multiplicador em outro aplicativo, você teria que copiar, colar e editar o código em botão manipulador desse aplicativo. Agora haveria dois lugares para manter a mesma regra de negócio, e dois lugares onde a mesma consulta ao cliente foi executado.

Outras dicas

Qual é o propósito do botão?

Os meus primeiros passos seria:

  • extrair a parte acessando o banco de dados. (Aviso: Código de ar à frente)

função GetCustomer (CurrentCustomerID como Long)

strSQL = "SELECT * FROM tblCustomers onde ID =" & CurrentCustomerID definido rec1 = GlobalDataBase.openrecordset (strSQL) result = 1

Se rec1.recordcount> 0, em seguida, GetCustomer = rec1 outro GetCustomer = false fim se End Function

  • compor a função lógica de negócios:

função getCustomerDiscount (customerID como Long)

cliente = GetCustomer (customerID)

res = 1 se o cliente, em seguida, Se o Cliente ( "categoria") = 1), em seguida, res = 0,9 fim se endif

getcustomerdiscount = res

Função final

  • em seguida, mudar o botão:

Sub cmdMultiplier_Click () pricemultiplier = getcustomerdiscount (currentcustomerid) end sub

Normalmente, você terá seu código UI responder aos eventos gerados pelo usuário, neste caso, o clique de botão.

Depois que ele realmente depende de como o programa foi concebido, o projeto mais básico seria para fazer referência a uma instância do cliente e conteria uma propriedade multiplicador. Seu objeto cliente é preenchida a partir de dados em seu DAL.

Validação de UI iria na camada de interface do usuário, as regras de validação de negócios pode entrar em seu objeto de negócios e, em seguida, o seu DAL é a sua camada de persistência.

Aqui está um exemplo muito básico pseudo-código:

btnClick
    Dim Cust as New Customer(ID)
    multplr = Cust.DiscountMultiplier
End Click

Class Customer
    Sub New(ID)
        Data = DAL.GetCustomerData(ID)
        Me.Name = Data("Name")
        Me.Address = Data("Address")
        Me.DiscountMultiplier = Data("DiscountMultiplier")
    End Sub
    Property ID
    Property Name
    Property Address
    Property DiscountMultiplier
        Return _discountMultiplier
    End
End Class


Class DAL
    Function GetCustomerData(ID)
        SQL = "Paramaterized SQL"
        Return Data
    End Function
End Class

Saber como refatorar é uma coisa boa. A partir de agora você vai saber separar as camadas.
No entanto, acho que seu tempo será gastar melhor para atualizar as ferramentas que você está usando, ao mesmo tempo. Você tem considere fazê-lo com VB.Net?

Uma maneira de fazer isso irá preservar a sua base de código existente é codificar a camada de dados e BR em VB.Net. Em seguida, para expor a BR por meio COM Interface (esta é uma opção caixa de seleção no projeto). Você pode então usar a nova BR de sua interface atual.

Uma vez que todos BR e DAL feito, você será um passo para uma plataforma completamente nova.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top