2008-10-22 112 views
1

我是一位使用DAO的自学vb6程序员。下面是一个代码典型件,我可以生产出的示例:重构为n层

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 

请假装上面是CRUD应用程序的整个源代码。 我知道这个设计很糟糕,一切都混在一起。理想情况下,它应该有三个不同的层次,用户界面,业务逻辑 和数据访问。我想 - 为什么这是可取的,但我不知道它是如何做的,我怀疑 这就是为什么我不完全明白为什么这样的分离是好的。 我认为如果有人能够将上面可笑的 重新构造成3层,我会更进一步。

+0

这很难重构这个,因为它很荒谬。有一个3层应用程序会给这样一个简单的例子带来很多复杂性,因为它不能正确说明3层架构比一般的混杂代码更简单。 – workmad3 2008-10-22 22:30:22

+0

我知道你的意思,但我想看看它是如何完成的。考虑到这一点,我认为分层可能会使数据库规范化。在表面层面上,它似乎会增加复杂性而没有任何奖励 – kjack 2008-10-23 09:52:08

+0

是的,正常化数据库是不合理的。乔治我认为他有它(tm)! – 2008-10-23 15:56:48

回答

3

一个简单的例子,是的,但所有的基本要素 - 他们只是属于3个不同类别(见下文)。其主要原因是“关注点分离”原则,即GUI只涉及GUI事物,Biz逻辑层仅关注业务规则,而数据访问层只涉及数据表示。这允许每个层被独立地维护和跨应用程序重用:

'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 

[“真正的”应用程序将缓存当前顾客,对客户查询等常量或存储过程.;为简洁而忽略]

将此与您原始的一切按钮处理程序示例(在VB代码中非常常见,因为它非常容易这样做)对比 - 如果您需要价格乘数规则在另一个应用程序中,您必须将代码复制,粘贴并编辑到该应用程序的按钮处理程序中。现在将有两个地方来维护相同的业务规则,并且有两个地方执行相同的客户查询。

1

该按钮的用途是什么?

我的第一个步骤是:

  • 提取部分访问数据库。 (警告:空气向前代码)

功能GETCUSTOMER(CurrentCustomerID如龙)

STRSQL = & CurrentCustomerID 组REC1 = GlobalDataBase.openrecordset(STRSQL) 结果 “从tblCustomers其中ID =选择*”= 1

如果rec1.recordcount> 0,那么 GETCUSTOMER = REC1 否则 GETCUSTOMER =假 ENDIF 端功能

  • 构成业务逻辑函数:

功能getCustomerDiscount(CustomerID作为龙)

顾客= GETCUSTOMER(的customerID)

RES = 1 如果顾客然后 如果客户(”类别“)= 1)然后 res = .9 endif endif

getcustomerdiscount = RES

端功能

  • 然后,更改按钮:

子cmdMultiplier_Click() pricemultiplier = getcustomerdiscount(currentcustomerid) 端子

+0

我忘了坚持按钮的目的。也许在标签上显示乘数。谢谢你的回答,Stephen A. Lowe的回答更加丰富了一些,这对我来说更容易理解。 – kjack 2008-10-23 08:57:59

1

通常您让你的UI代码响应用户提出的事件,在这种情况下,按钮点击。

之后,它真的取决于你的程序是如何设计的,最基本的设计是引用一个Customer实例,它将包含一个乘数属性。 您的客户对象由DAL中的数据填充。

用户界面的验证将进入UI层,业务验证规则可能会进入您的业务对象,然后您的DAL就是您的持久层。

这是一个非常基本的伪代码示例:

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 
1

知道如何重构是件好事。从现在开始,您将知道如何分层。
但是,我认为你的时间花在升级同时使用的工具上会更好。你有没有考虑用VB.Net做到这一点?

一种方法可以保留你现有的代码库,在VB.Net中编写数据层和BR代码。然后通过COM接口公开BR(这是项目中的复选框选项)。然后,您可以使用当前界面中的新BR。

一旦所有的BR和DAL都完成了,您将离开一个完整的新平台。