Refactoring: Extract type from parameters
06.01.2009 | Gunnar
Extract type from parameters on koodi korrastamise meetod, mis seisneb meetodite parameetrite asendamises tüübiga. Antud tüüp koondab siis kokku kõik parameetrid, mille abil meetodi kutsuti. Keeltes, kus on olemas klassid, saab mängu tuua uue klassi.
Asume kohe asja juurde ja vaatame järgmist koodijuppi VBA-s. Lihtsuse huvides ei aja ma koodiridu siin hästi pikaks. Seda, kui hulluks annab asja ajada, aimab ehk iga progeja ise.
'...
s = GetFolder(AppDir & "\import\", "Please select import folder", Me.Hwnd, 1)
'...
End Sub
Function GetFolder(sInitialFolder As String, sTitle As String, lHwnd As Long, lFlags As Long)
Dim sFolderWithBuffer As String, sTitleWithBuffer As String
'...
GetFolder = BrowseForFolder();
'...
End Function
See kood on suhteliselt halvasti loetav kahes kohas. Üks on koht, kus kutsutakse meetod välja üüratult pika parameetrite loendiga. Teine koht on too kutsutav meetod ise. Parameetreid on päris palju ja pole kuigi hästi arusaada, milline muutuja on meetodi parameeter ja milline on lokaalne muutuja.
Kui seda meetodi kutsutakse välja mitmes kohas, siis on meil üks probleem lisaks. Kui meetodi parameetreid tuleb juurde või jääb vähemaks, peame me muutused tegema ka kõikides nendes kohtades, kus meetodi kutsutakse.
Probleemi lahendame ära sel teel, et defineerime uue tüübi, mille atribuutideks on eeltoodud meetodi parameetrid. Uue tüübi definitsioon olgu näiteks selline.
hwndOwner As Long
pidlRoot As Long
sDisplayName As String
sTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Nüüd jääb üle vaid teha muutused meetoditesse. Peale muutusi näevad meetodid välja sellised.
Dim binfo As BrowseInfo
'...
With binfo
.hwndOwner = Me.Hwnd
.sDisplayName = AppDir & "\import\"
.sTitle = "Please select import folder"
.ulFlags = 1
End With
s = GetFolder(binfo)
'...
End Sub
Function GetFolder(info As BrowseInfo)
Dim sFolderWithBuffer As String, sTitleWithBuffer As String
'...
GetFolder = BrowseForFolder();
'...
End Function
Teist meetodi vaadates on meil üheselt selge, millised muutujad on meetodi mõttes lokaalsed ja millised on tulnud parameetrite kaudu. Vajadusel võime me kirjutada ka muid meetode, mis sama tüüpi parameetrina kasutavad. Tulemuseks on kood, mis on paremini loetav ja hallatav.

07.01.2009 kell 19:03
Ma arvan javascriptiga on palju selgem seda näidata, kuna objektide initsialiseerimise süntaks on väiksem. Teine asi on see et siin on kõik parametrid vaikmisi edastatud väärtusena (by Value), ja reference’id tavaliselt edastatakse ikkagi parametrina (ehk veel objekti sisse ei pane), aga v.o. ma eksin?
function GetFolder(options){
…
}
GetFolder({
hwndOwner:5,
sDisplayName:’me’
});
07.01.2009 kell 23:43
JavaScript ja VBA lasevad selliseid asju teha. On aga palju keeli, kus vaikeväärtused puuduvad. Mu point tuleb ehk paremini välja siis, kui kõikidele parameetritele pikas parameetrite listis on vaja väärtus anda ja selleks polegi paremat lahendust kui moodustada üks pikk väärtuste rida.