Dalam artikel saya kemarin, saya memperkenalkan konsep "Kereta Ketergantungan". Itulah yang terjadi ketika Anda mengimpor fungsi dari pustaka kode Anda, tetapi Anda akhirnya harus mengimpor beberapa modul tambahan hanya untuk memenuhi semua dependensi. Anda hanya memiliki satu "kereta" modul kode ketika yang Anda butuhkan hanyalah satu "kursi" (fungsi).
Anda berakhir dalam situasi ini ketika modul Anda digabungkan dengan erat. Jadi apa yang dapat Anda lakukan? Ada beberapa cara untuk menangani situasi ini.
Melanggar "jangan ulangi dirimu sendiri"
Salah satu cara untuk mempertahankan kopling longgar--yang menghasilkan lebih banyak modul "mandiri"--adalah membuat salinan pribadi fungsi dari modul sumber di modul panggilan. Ini menghilangkan ketergantungan antara dua modul, tetapi menghasilkan kode berulang.
Konsepnya sederhana. Anda menyalin fungsi dari modul kode utamanya. Anda kemudian menempelkannya di modul panggilan tetapi menandainya sebagai pribadi untuk menghindari ambiguitas.
Ini masuk akal dalam situasi berikut:
- Metode sederhana tanpa logika rumit.
- Prosedur yang tidak mungkin berubah.
- Saat rutinitas merupakan bagian dari modul yang jauh lebih besar dan Anda tidak memerlukan fungsi lain apa pun dalam modul. Menyalin satu fungsi akan menghindari kembung.
Pendekatan ini memiliki kelemahan sebagai berikut:
- Jika ada ada bug dalam fungsi yang disalin, Anda harus memperbaikinya di banyak tempat.
- Anda memiliki duplikasi kode jika akhirnya mengimpor modul sumber.
Pilih pertempuran Anda
Saya dulu berusaha keras untuk menjaga semua modul pustaka kode standar saya benar-benar mandiri. Masalahnya adalah itu menghasilkan banyak duplikasi kode. Alasannya adalah sebagian besar fungsi yang saya salin ke modul lain untuk penggunaan pribadi berasal dari modul yang saya impor ke dalam aplikasi saya.
Contoh utama dari ini adalah StringFunctions my saya modul. Modul itu memiliki beberapa metode sederhana yang sebagian besar ada untuk membuat kode saya lebih mudah dibaca. Misalnya, saya memiliki Conc()
fungsi yang saya sertakan sebagai fungsi pribadi di lebih dari setengah modul pustaka kode saya.
Seiring waktu, saya menyadari bahwa saya menyertakan StringFunctions . itu modul di semua proyek saya. Saya tidak pernah memperkenalkan ketergantungan baru ketika saya memanggil fungsi dari modul itu. Saya membuang-buang waktu dan memperkenalkan kode duplikat dengan sedikit atau tanpa manfaat.
Ada beberapa modul kode yang dapat saya asumsikan dengan aman di setiap aplikasi. Itulah modul-modul dengan fungsi yang paling sering saya gunakan. Artinya, banyak dari dependensi ini pada dasarnya dapat diabaikan.
Saya sekarang memelihara "Perpustakaan Standar" modul kode yang saya impor ke setiap proyek baru di awal. Saya dengan bebas memanggil fungsi dari modul-modul itu sekarang aman dengan pengetahuan bahwa saya tidak akan memperkenalkan dependensi baru.
Gunakan token komentar unik
Salah satu modul di "Perpustakaan Standar" saya adalah modul kelas (clsApp ) yang menyertakan properti dan metode tingkat aplikasi, seperti nama pengguna saat ini dan teks bilah judul. Saya juga mengekspos modul kelas lain dari dalam clsApp , seperti clsStatus dan clsRegistry , yang masing-masing menyediakan akses yang lebih mudah dibaca ke bilah status Access dan registri Windows.
Namun, saya tidak memerlukan akses ke bilah status atau registri Windows di setiap proyek. Jadi, untuk menghindari ketergantungan pada clsStatus atau clsRegistry kelas, saya akan mengomentari kode yang merujuk kelas tersebut menggunakan "token komentar" yang unik.
Ini paling mudah ditunjukkan dengan sebuah contoh:
' Notes
' - Find and replace '$$ with blank to enable Status property (requires clsStatus)
' - Find and replace '&& with blank to enable Reg property (requires clsRegistry)
'$$Private m_objStatus As clsStatus
'&&Private m_objReg As clsRegistry
'$$Public Property Get Status() As clsStatus
'$$ Set Status = m_objStatus
'$$End Property
'&&Public Property Get Reg() As clsRegistry
'&& Set Reg = m_objReg
'&&End Property
Private Sub Class_Initialize()
'$$ Set m_objStatus = New clsStatus
'&& Set m_objReg = New clsRegistry
End Sub
Jika saya ingin mengaktifkan Status
properti dari kelas di atas, saya dapat melakukan pencarian dan penggantian global pada '$$
.
Ini bekerja dengan baik untuk sementara waktu, tetapi selalu terasa kaku bagi saya. Mungkin karena itu. Hal lain yang perlu diperhatikan adalah bahwa token komentar harus unik secara global di seluruh pustaka kode saya. Ini akan menjadi mimpi buruk pemeliharaan jika saya terjebak dengan pendekatan ini lama.
Gunakan kompilasi bersyarat
Pendekatan yang jauh lebih bersih adalah dengan memanfaatkan kompilasi bersyarat. Itu adalah baris-baris di VBA yang dimulai dengan tanda pound/hashtag ("#"). Baris yang dimulai dengan karakter tersebut tunduk pada "pemrosesan awal".
Apa itu pra-pemrosesan? Itu adalah langkah yang diambil bahasa pemrograman sebelum kompilasi. Jadi, sebelum pemeriksaan waktu kompilasi terjadi, jalur pra-pemrosesan dievaluasi. Hal ini memungkinkan kami untuk menempatkan kode yang jika tidak akan gagal untuk dikompilasi ke dalam proyek kami.
Bagaimana kita bisa memanfaatkan ini dengan pustaka kode kita? Sekali lagi, ini paling sederhana untuk ditunjukkan dengan sebuah contoh:
' Notes
' - Replace the '$$ and '&& kludges with conditional compilation
#Const EnableStatusProperty = True 'If True, requires import of clsStatus class
#Const EnableRegProperty = False 'If True, requires import of clsRegistry class
#If EnableStatusProperty Then
Private m_objStatus As clsStatus
#End If
#If EnableRegProperty Then
Private m_objReg As clsRegistry
#End If
#If EnableStatusProperty Then
Public Property Get Status() As clsStatus
Set Status = m_objStatus
End Property
#End If
#If EnableRegProperty Then
Public Property Get Reg() As clsRegistry
Set Reg = m_objReg
End Property
#End If
Private Sub Class_Initialize()
#If EnableStatusProperty Then
Set m_objStatus = New clsStatus
#End If
#If EnableRegProperty Then
Set m_objReg = New clsRegistry
#End If
End Sub
Yang terbaik dari kedua dunia
Seperti yang Anda lihat, ini adalah cara yang sangat bersih untuk menghindari masalah "Kereta Ketergantungan".
Ini memungkinkan kita untuk membuat dependensi opsional . Setiap bagian kode yang bergantung pada modul pustaka kode lain dibungkus di dalam kompilasi bersyarat #If ... Then pernyataan. Konstanta kompilasi bersyarat semuanya terdaftar di bagian atas modul kode.
Sekarang ketika kita mengimpor kembali versi terbaru dari modul pustaka kode kita, kita hanya perlu melalui dan menyetel flag kompilasi bersyarat ke apa yang ada sebelumnya. Jika kita tidak ingat bagaimana flag disetel, kita harus dapat terus mengompilasi dan menyesuaikan flag hingga proyek dikompilasi sepenuhnya.
Dan jika kita menggunakan kontrol versi, kita tidak perlu khawatir melupakan apa yang ada sebelumnya.