代码之家  ›  专栏  ›  技术社区  ›  kjack

重构到n层

  •  1
  • kjack  · 技术社区  · 18 年前

    我是一个自学成才的vb6程序员,使用DAO。下面是一段典型代码的示例,我可以大量编写:

    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应用程序的全部源代码。 我知道这个设计很糟糕,所有东西都混在一起了。理想情况下,它应该有三个不同的层:用户界面、业务逻辑 和数据访问。我有点明白为什么这是可取的,但我不知道它是如何做到的,我怀疑 这就是为什么我不完全明白为什么这样的分离是好的。 我想,如果有人能荒谬地重构上述内容,我会走得更远

    4 回复  |  直到 18 年前
        1
  •  3
  •   Steven A. Lowe    18 年前

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

    '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
    

    [真正的应用程序将缓存当前客户,为客户查询提供常量或存储过程等;为简洁起见,将忽略]

        2
  •  1
  •   Brian Schmitt    18 年前

    通常,您的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
    
        3
  •  1
  •   Hapkido    18 年前

    知道如何重构是一件好事。从现在起,您将知道如何分离层。

        4
  •  1
  •   TAbdiukov miltonb    6 年前

    这个按钮的用途是什么?

    我的第一步是:

    • 提取访问数据库的部件。(警告:前方有航空代码)
    function getCustomer(CurrentCustomerID as Long)
    
    strSQL = "select * from tblCustomers where ID = " & CurrentCustomerID
    set rec1 = GlobalDataBase.openrecordset(strSQL)
    result = 1
    
    if rec1.recordcount >0 then
        getCustomer = rec1
    else
        getCustomer = false
    endif
    end function
    
    function getCustomerDiscount(customerID as Long)
    
    customer = getCustomer(customerID)
    
    res = 1
    if customer then
        if customer("category")=1) then
            res = .9
        endif
    endif
    
    getcustomerdiscount = res
    
    end function
    
    • 然后,更改按钮:
    Sub cmdMultiplier_Click() 
        pricemultiplier = getcustomerdiscount(currentcustomerid)
    end sub