dodogo

Testujem

Objektovo orientované VBA: Návrhové vzory: komplexná továreň [Complex Factory] 

V mojom poslednom príspevku som spomenul možnosť vytvoriť továreň za behu pomocou prístupu k kolekcii VBComponents. Ak to chcete urobiť, musíte najskôr vytvoriť referenciu na:


Microsoft Visual Basic for Applications Extensibility 5.3
(C:\Program Files\Common Files\Microsoft Shared\VBA\VB6\VBE6.DLL)

Po tomto máte teraz prístup ku knižnici VBIDE a najmä kolekcii VBComponents.

Nižšie je komplexná továreň. Upozorňujeme, že niektoré riadky pokračujú na ďalší riadok a ja som nezahrnul znaky na pokračovanie riadku, ale potom nikdy slepo nekopírujete a nevložíte z HOWTO, však!


Public Function CreateFactory() As Variant
Dim str As String: str = BuildString("IAnimal")
Call WriteCode(str)
End Function

Private Function BuildString(ByRef interfaceName As String) As String
Dim str As String
str = "Public Function Instantiate(ByRef className As String, ByRef varState As Variant) As " & interfaceName & vbCrLf
str = str & "Select Case className" & vbCrLf
' go through all classes and find the ones that implement interfaceName
Dim comp As VBIDE.VBComponent
For Each comp In VBE.ActiveVBProject.VBComponents
If comp.Type = vbext_ct_ClassModule Then
If comp.CodeModule.Find("Implements " & interfaceName, 1, 1, comp.CodeModule.CountOfDeclarationLines + 1, 1) Then
str = str & vbTab & "Case """ & comp.Name & """" & vbCrLf
str = str & vbTab & vbTab & "Set Instantiate = New " & comp.Name & vbCrLf
str = str & vbTab & vbTab & "Call Instantiate.Constructor(varState)" & vbCrLf
End If
End If
Next comp
str = str & "End Select" & vbCrLf
str = str & "End Function"
BuildString = str
End Function

Private Sub WriteCode(ByRef str As String)
Dim cls As VBIDE.CodeModule
Set cls = VBE.ActiveVBProject.VBComponents("Factory").CodeModule
' remove any existing code lines
If cls.Find("Instantiate", 1, 1, 2, 1) Then
Dim start As Long: start = cls.ProcStartLine("Instantiate", vbext_pk_Proc)
Dim count As Long: count = cls.ProcCountLines("Instantiate", vbext_pk_Proc)
Call cls.DeleteLines(start, count)
End If
' write the new code lines
Call cls.AddFromString(str)
End Sub

Ako vidíte, proces vytvárania komplexnej továrne je dvojkrokový: najprv vytvorte reťazec kódu VBA a potom ho zapíšte do modulu kódu – pozri postup „CreateFactory“. Vytvorenie reťazca (funkcia „BuildString“) by malo byť celkom jednoduché na pochopenie. Všimnite si, že vytváram polymorfnú továreň, ktorá vytvára inštancie všetkých tried, ktoré sú v súlade s rozhraním „IAnimal“, ktoré som vytvoril. Aby som našiel tieto triedy, prechádzam cez všetky VBComponents a skúmam len moduly tried (VBComponent.Type = vbext_ct_ClassModule). Pre každý modul triedy ma zaujímajú iba tie, ktoré obsahujú v riadkoch deklarácie reťazec „Implements IAnimal“. Po splnení týchto podmienok potom reťazec, ktorý vytváram, spájam s potrebným „mäsom“ v sendviči Select Case. Všimnite si, že moja definícia rozhrania pre IAnimal obsahuje procedúru „Constructor“, ktorá akceptuje variant ako vstup („varState“). Každá trieda, ktorá implementuje IAnimal, bude obsahovať svoj vlastný kód, ktorý funguje na vstupe Variant, aby sa nastavil stav vytvoreného objektu predtým, ako tento novovytvorený objekt vráti továreň. V praxi môže byť varState ako Variant jednoduchý ako reťazec obsahujúci hodnotu pre jedno z polí triedy, alebo by to mohlo byť zložité pole obsahujúce mnoho rôznych objektov, ktoré sa používajú pri vytváraní objektu, ktorý zodpovedá triede. .

Po vytvorení reťazca „str“ a jeho odovzdaní späť do CreateFactory, táto potom pokračuje v písaní kódu do CodeModule vyhradeného modulu „Factory“. Ako som uviedol vo svojom predchádzajúcom príspevku o Simple Factory, „Factory“ môže byť štandardný modul, modul triedy alebo modul statickej triedy. Pred napísaním kódu však „WriteCode“ odstráni akýkoľvek existujúci kód v „Factory“. robí to preto, že „CreateFactory“ je navrhnutý tak, aby sa zavolal pri otvorení súboru Access/Excel. V Accesse sa to dosiahne vytvorením makra, ktoré po otvorení súboru spustí „CreateFactory“. V Exceli sa to dosiahne volaním „CreateFactory“ pri spustení udalosti Workbook_Open (v module kódu „ThisWorkbook“).

A to je naozaj všetko. Aj keď sa to nazýva „komplex“, jedinou zložitou vecou je neznalosť práce s kolekciou VBComponents. V skutočnosti je to celkom jednoduché, keď pochopíte, čo sa robí. Krása vyššie uvedenej Complex Factory prichádza pri rozšírení počtu tried, ktoré implementujú zvolené rozhranie (v mojom príklade IAnimal). Všetko, čo vývojár musí urobiť, je vytvoriť modul triedy a uložiť súbor. Pri ďalšom otvorení súboru vyššie uvedený kód zachytí túto novú triedu a zahrnie ju do továrne – vývojár sa nemusí starať o manuálnu aktualizáciu objektu Factory.

Leave comment

Your email address will not be published. Required fields are marked with *.