【问题标题】:Using a Private Property directly vs using Get and Let/Set直接使用私有属性与使用 Get 和 Let/Set
【发布时间】:2014-03-31 12:02:03
【问题描述】:

VBA 初学者(以及一般的编程初学者)希望了解更多有关如何有效地完成 OOP 的信息。

有人可以解释或提供参考来讨论使用的好处/目的 - 类模块的内部 - VBA 中的 Private Property Get 和/或 Let/Set 语句与直接访问属性,尽管不需要操作数据?

例子:

我创建了一个cDimension 类(在 Excel 中)。此类将线条绘制为Shape 对象,以及其他一些不相关的东西。 DrawingScale 变量允许根据需要缩放整个图形。某些属性在获取/设置时需要操作,而其他属性则不需要。

因此,例如,pWidth 需要进行缩放:

'clsDimension
Private pWidth As Single    
Private Property Get Width() As Single
    Width = pWidth
End Property
Private Property Let Width(w As Single)
    pWidth = w / DrawingScale
End Property

pColor 不需要任何操作,进出:

Private pColor As Integer
Private Property Get Color() As Integer
    Color = pColor
End Property
Private Property Let Color(c As Integer)
    pColor = c
End Property

pWidth 属性是一个实例,在该实例中,对类本身的过程使用私有属性 Get 和 Let 方法对我来说很有意义。但是,我的问题是:是否有任何理由也使用私有属性方法来获取和设置 pColor 属性,就像我在上面给出的那样?

Public Function Line(sht As Worksheet, L As tLine, Optional c = vbBlack) As Shape
    Width = DistanceBetweenTwoPoints(L.first.x, L.first.y, _
                                     L.second.x, L.second.y) '<-- pWidth is scaled
    Color = c '<-- Vs. just using pColor = c
    Set Line = sht.Shapes.AddLine(L.first.x, L.first.y, L.second.x, L.second.y)
End Function

提前致谢。

【问题讨论】:

  • 代码维护和进化意味着“不需要任何操作”并不总是以“永远不需要...”而告终,因此“总是”使用属性 Let 被认为是一种好习惯/Get,甚至在类中,而不是直接使用私有支持字段。
  • 简单的答案,但我想这是有道理的。谢谢!
  • 我曾与一个将所有类模块变量声明为公共而不是私有的人一起工作,这样它们就可以在没有 get 和 let 的情况下使用,这对我来说总是很奇怪。我通常认为类模块执行某些操作,而不仅仅是用作数据类型,因此我通常使用 get 和 let 并对任何传入的内容执行一些数据验证,以限制和控制我的类中显示的内容。如果您问我,这是优势之一,但我不确定您会如何在现有的编码范例中描述这一点。
  • 您的语法实际上并不完全正确,您可能需要对其进行编辑以包含 Property 关键字。编写的代码不会编译。
  • 谢谢。相应地进行了编辑。

标签: class vba oop properties private


【解决方案1】:

我看到的值是减少的代码,您没有在示例代码中利用它。你可以替换这个:

'clsDimension
Private pWidth As Single    
Private Property Get Width() As Single
    Width = pWidth
End Property
Private Property Let Width(w As Single)
    pWidth = w / DrawingScale
End Property

用这个:

'clsDimension
Private Property Get Width() As Single
    Width = w / DrawingScale
End Property

这消除了访问 pWidth 或 width 属性的潜在歧义,因为 pWidth 不再存在。它还消除了在写入之前读取 Width 的潜在缺陷,尽管在读取 Width 之前添加一些代码来检查 w 和 DrawingScale 是否已设置为有效值是明智的。

【讨论】:

    【解决方案2】:

    如果您没有在输入或输出的过程中操作值,只需使用公共变量即可。 VBA 比 Java 或 C++ 更像 Python,因为 从公共变量切换到“getter/setter”函数并没有真正的惩罚

    假设您从以下代码开始:

    'clsCar
    Public Speed As Double
    Public Sub Drive()
        MsgBox "Driving at " & Speed & " MPH"
    End Sub    
    
    
    'Module1
    Sub DriveCar()
        Set Car = New clsCar
        Car.Speed = 100
        Car.Drive  'shows msg:  "Driving at 100 MPH"
    End Sub
    

    然后你决定开那么快是危险的,所以你想为你的车辆添加一个“州长”并且需要更新你的类:

    'clsCar
    Private mSpeed As Double
    Private Const SpeedLimit As Double = 55
    
    Public Property Get Speed()
        Speed = mSpeed
    End Property
    Public Property Let Speed(Val As Double)
        If Val > SpeedLimit Then
            mSpeed = SpeedLimit
        ElseIf Val < 0 Then
            mSpeed = 0
        Else
            mSpeed = Val
        End If
    End Property
    Public Sub Drive()
        MsgBox "Driving at " & Speed & " MPH"
    End Sub    
    
    
    'Module1
    'Note that no changes to this code are necessary; the change
    '   is entirely encapsulated within the class (as it should be)
    Sub DriveCar()
        Set Car = New clsCar
        Car.Speed = 100
        Car.Drive  'shows msg:  "Driving at 55 MPH"
    End Sub
    

    Tim Williams 的评论是您经常听到的在 VBA 中不必要地使用 Get/Let/Set 的理由,但这是其他语言(尤其是 C++ 和 Java)的良好建议被误用于 VBA/VB6 的副产品。

    【讨论】:

      【解决方案3】:

      一如既往....这取决于。您的 x 属性绝对应该通过字母访问,因为字母对输入执行计算。

      'clsDimension
      Private Let Width(w As Single)
          pWidth = w / DrawingScale
      End Property
      

      您应该直接访问pWidth 变量。如果这样做,您将不得不在模块的其他位置复制pWidth = w / DrawingScale 逻辑。

      您的pColor 属性可能是一个公共变量,因为获取或设置它没有逻辑。我不推荐它。如果稍后您意识到您不想允许某些颜色怎么办?然后你需要它背后的逻辑,无论如何你都需要切换到一个属性。该属性更易于维护且语义更正确。

      【讨论】:

        猜你喜欢
        • 2021-01-08
        • 2012-04-05
        • 2013-10-24
        • 1970-01-01
        • 2015-08-19
        • 1970-01-01
        • 2016-02-25
        • 2019-04-05
        • 2017-02-27
        相关资源
        最近更新 更多