我是否理解未正确使用getter和setter

Alf*_*avo 2 vba get set

看完这个由叶戈尔关于不使用getter和setter一块,这听起来像的东西,对我来说很有意义。

请注意,仅当我正确实施此问题时,此问题才是关于它是否更好/最坏的问题

我想在VBA中的以下两个示例中了解我是否正确理解了这个概念,以及我是否正确地应用了它。

标准方法是:

Private userName As String

Public Property Get Name() As String
    Name = userName
End Property
Public Property Let Name(rData As String)
    userName = rData
End Property
Run Code Online (Sandbox Code Playgroud)

在我看来,他的方式将是这样的:

Private userName As String

Public Function returnName() As String
    returnName = userName
End Function

Public Function giveNewName(newName As String) As String
    userName = newName
End Function
Run Code Online (Sandbox Code Playgroud)

从上面的两个示例可以理解,如果我想更改userName的格式(可以说以全大写形式返回),则可以使用第二种方法来完成此操作,而无需更改给出名称的方法的名称。通过命名-我可以让returnName指向userNameCaps属性。我程序中的其余代码仍然可以保持不变,并指向方法userName。

但是,如果我想在第一个示例中执行此操作,则可以创建一个新属性,但随后又必须在程序中的任何地方更改代码,以指向该新属性……对吗?

换句话说,在第一个示例中,API从属性获取信息,而在第二个示例中,API从方法获取信息。

Mat*_*don 5

您的第二个片段既不是惯用语言也不是等效语言。您链接到的文章是关于Java的,它是一种没有任何对象属性概念的语言- getFoo/ 在Java中setFoo只是一种约定

在VBA中:

Private userName As String

Public Property Get Name() As String
    Name = userName
End Property
Public Property Let Name(rData As String)
    userName = rData
End Property
Run Code Online (Sandbox Code Playgroud)

最终等于这样:

Public UserName As String
Run Code Online (Sandbox Code Playgroud)

不服气吗?将这样的公共字段添加到类模块中,例如Class1。然后添加一个新的类模块并添加以下内容:

Implements Class1
Run Code Online (Sandbox Code Playgroud)

编译器将强制您实现Property GetProperty Let,以便Class1可以实现接口协定。

那么,为什么还要麻烦属性呢?属性是一个工具,可以帮助封装

Option Explicit
Private Type TSomething
    Foo As Long
End Type
Private this As TSomething

Public Property Get Foo() As Long
    Foo = this.Foo
End Property

Public Property Let Foo(ByVal value As Long)
    If value <= 0 Then Err.Raise 5
    this.Foo = value
End Property
Run Code Online (Sandbox Code Playgroud)

现在,如果您尝试Foo使用负值进行赋值,则会遇到运行时错误:该属性封装了只有该类才知道并且能够突变的内部状态:调用代码看不到或不知道封装的值-它所知道的Foo只是一个读/写属性。“设置者”中的验证逻辑可确保对象始终处于一致状态。

如果要将属性分解为方法,则需要Function为getter分配一个,而赋值为a Sub而不是一个Function。实际上,Rubberduck会告诉您,giveNewName从未分配的返回值存在问题:这比“正在使用属性的OMG!”的代码味道差得多。

函数返回一个值。Subs / method 做某事 -在对象/类的情况下,某事可能暗示内部状态发生了变化。

但是,通过避免Property Let仅仅因为某些Java专家说getter和setter是邪恶的,您就使VBA API变得比所需的更加混乱-因为VBA理解属性,而Java却不了解。但是C#和VB.NET可以,因此,至少在属性方面,这些语言的原理比Java更适用于VBA。请参阅属性与方法

VB中的FWIW公开成员名称将按照PascalCase惯例使用。camelCase公共成员名称是Java的东西。请注意,标准库中的所有内容如何以大写首字母开头?