封裝
封裝隱藏了客戶端程式碼的實現細節
該處理將對 QueryClose 示例演示封裝:形式都有一個核取方塊控制,但它的客戶端程式碼不直接合作 -核取方塊是一個實現細節,什麼客戶端程式碼需要知道的是設定是否啟用。
當核取方塊值更改時,處理程式將分配一個私有欄位成員:
Private Type TView IsCancelled As Boolean SomeOtherSetting As Boolean 'other properties skipped for brievety End Type Private this As TView '... Private Sub `SomeOtherSettingInput_Change()` this.SomeOtherSetting = `CBool(SomeOtherSettingInput.Value)` End Sub
當客戶端程式碼想要讀取該值時,它不需要擔心核取方塊 - 而只是使用 SomeOtherSetting
屬性:
Public Property Get `SomeOtherSetting()` As Boolean SomeOtherSetting = this.SomeOtherSetting End Property
SomeOtherSetting
屬性封裝了核取方塊’state; 客戶端程式碼不需要知道有一個核取方塊,只是有一個布林值的設定。通過封裝 Boolean
值,我們在核取方塊周圍新增了一個抽象層。
使用介面來強制實現不變性
讓我們通過將表單的模型**封裝在專用的類模組中來進一步推進。但是如果我們為 UserName
和 Timestamp
製作了一個 Public Property
,我們將不得不暴露 Property Let
訪問器,使屬性變得可變,並且我們不希望客戶端程式碼能夠在設定後更改這些值。
抽象示例中的 CreateViewModel
函式返回一個 ISomeModel
類:這是我們的介面,它看起來像這樣:
Option Explicit
Public Property Get Timestamp() As Date
End Property
Public Property Get UserName() As String
End Property
Public Property Get AvailableItems() As Variant
End Property
Public Property Let AvailableItems(ByRef value As Variant)
End Property
Public Property Get SomeSetting() As String
End Property
Public Property Let SomeSetting(ByVal value As String)
End Property
Public Property Get SomeOtherSetting() As Boolean
End Property
Public Property Let SomeOtherSetting(ByVal value As Boolean)
End Property
請注意,Timestamp
和 UserName
屬性僅顯示 Property Get
訪問器。現在 SomeModel
類可以實現該介面:
Option Explicit
Implements ISomeModel
Private Type TModel
Timestamp As Date
UserName As String
SomeSetting As String
SomeOtherSetting As Boolean
AvailableItems As Variant
End Type
Private this As TModel
Private Property Get ISomeModel_Timestamp() As Date
ISomeModel_Timestamp = this.Timestamp
End Property
Private Property Get ISomeModel_UserName() As String
ISomeModel_UserName = this.UserName
End Property
Private Property Get ISomeModel_AvailableItems() As Variant
ISomeModel_AvailableItems = this.AvailableItems
End Property
Private Property Let ISomeModel_AvailableItems(ByRef value As Variant)
this.AvailableItems = value
End Property
Private Property Get ISomeModel_SomeSetting() As String
ISomeModel_SomeSetting = this.SomeSetting
End Property
Private Property Let ISomeModel_SomeSetting(ByVal value As String)
this.SomeSetting = value
End Property
Private Property Get ISomeModel_SomeOtherSetting() As Boolean
ISomeModel_SomeOtherSetting = this.SomeOtherSetting
End Property
Private Property Let ISomeModel_SomeOtherSetting(ByVal value As Boolean)
this.SomeOtherSetting = value
End Property
Public Property Get Timestamp() As Date
Timestamp = this.Timestamp
End Property
Public Property Let Timestamp(ByVal value As Date)
this.Timestamp = value
End Property
Public Property Get UserName() As String
UserName = this.UserName
End Property
Public Property Let UserName(ByVal value As String)
this.UserName = value
End Property
Public Property Get AvailableItems() As Variant
AvailableItems = this.AvailableItems
End Property
Public Property Let AvailableItems(ByRef value As Variant)
this.AvailableItems = value
End Property
Public Property Get SomeSetting() As String
SomeSetting = this.SomeSetting
End Property
Public Property Let SomeSetting(ByVal value As String)
this.SomeSetting = value
End Property
Public Property Get SomeOtherSetting() As Boolean
SomeOtherSetting = this.SomeOtherSetting
End Property
Public Property Let SomeOtherSetting(ByVal value As Boolean)
this.SomeOtherSetting = value
End Property
介面成員都是 Private
,並且必須實現介面的所有成員才能編譯程式碼。Public
成員不是介面的一部分,因此不會暴露於針對 ISomeModel
介面編寫的程式碼。
使用工廠方法模擬建構函式
使用 VB_PredeclaredId 屬性,我們可以使 SomeModel
類有一個預設例項,並編寫一個函式,類似於型別級(VB.NET 中的 Shared
,C#中的 static
)成員,客戶端程式碼可以呼叫而無需首先建立像我們在這裡做的一個例項:
Private Function `CreateViewModel()` As ISomeModel Dim result As ISomeModel Set result = SomeModel.Create(Now, Environ$("UserName")) result.AvailableItems = GetAvailableItems Set CreateViewModel = result End Function
這個工廠方法分配從 ISomeModel
介面訪問時只讀的屬性值,這裡是 Timestamp
和 UserName
:
Public Function Create(ByVal pTimeStamp As Date, ByVal pUserName As String) As ISomeModel
With New SomeModel
.Timestamp = pTimeStamp
.UserName = pUserName
Set Create = .Self
End With
End Function
Public Property Get Self() As ISomeModel
Set Self = Me
End Property
現在我們可以對 ISomeModel
介面進行編碼,該介面將 Timestamp
和 UserName
作為只讀屬性公開,永遠不能重新分配(只要程式碼是針對介面編寫的)。