Anda bertanya pada diri sendiri: "Bagaimana cara menulis dengan bersih, dapat dimengerti?" Bagaimana cara cepat memahami kode orang lain? "
Ingat aturan di bawah ini dan terapkan!
Artikel ini tidak membahas aturan dasar untuk penamaan variabel dan fungsi, lekukan sintaksis, dan topik refactoring skala besar. Kami mempertimbangkan 5 aturan sederhana untuk menyederhanakan kode dan mengurangi beban pada otak selama proses pengembangan.
Pertimbangkan proses mempersepsikan data untuk mengkorelasikan aturan yang dijelaskan dengan proses persepsi dan menentukan kriteria untuk kode sederhana.
Proses persepsi yang disederhanakan terdiri dari langkah-langkah berikut:
- Data yang diterima melalui reseptor konsisten dengan pengalaman sebelumnya.
- Jika tidak ada korelasi, ini adalah noise. Suara itu dengan cepat dilupakan. Jika ada sesuatu untuk dihubungkan, faktanya diakui.
- Jika faktanya penting - kita ingat, atau menggeneralisasi, atau bertindak, misalnya, kita katakan atau ketik kode.
- Untuk mengurangi jumlah informasi yang dihafal dan dianalisis, generalisasi digunakan.
- Setelah meringkas, informasi tersebut kembali dikorelasikan dan dianalisis (langkah 1).
Para ilmuwan membagi memori menjadi jangka pendek dan jangka panjang. Memori jangka pendek kecil volumenya, tetapi informasi diekstraksi dan disimpan secara instan. Memori jangka pendek adalah cache otak. Ia dapat menyimpan 7 + -2 kata, angka, objek. Memori jangka panjang memiliki volume yang lebih besar, tetapi membutuhkan lebih banyak energi (upaya) untuk menyimpan dan mengambil informasi daripada memori jangka pendek.
Kesimpulan:
- semakin sedikit elemen, semakin sedikit energi yang dihabiskan,
- diperlukan untuk mengurangi jumlah elemen yang dirasakan menjadi 9,
- gunakan memori jangka panjang sesedikit mungkin: menggeneralisasi atau melupakan.
Kami melanjutkan ke deskripsi aturan.
Aturan 1. Kami menggunakan pernyataan dalam kondisi, singkirkan "tidak."Menghapus operator "tidak" mengurangi jumlah elemen yang dianalisis. Juga, dalam banyak bahasa pemrograman, "!" Digunakan untuk operator negasi. Karakter ini mudah dilewati saat membaca kode.
Bandingkan:
if (!entity.IsImportAvaible) {
Setelah:
if (entity.IsImportAvaible) {
Aturan 2. Mengurangi tingkat sarang.Selama analisis kode, setiap level bersarang harus disimpan dalam memori. Kurangi jumlah level - kurangi biaya bahan bakar.
Pertimbangkan cara untuk mengurangi jumlah level sarang.
1) Kontrol pengembalian. Kami memotong beberapa kasus dan fokus pada yang tersisa.
if (conributor != null) {
Konversikan ke
if(contributor == null) { return; }
atau
while( 1) { if( 2) { break; }
atau
for(; 1;) { if( 2) { continue; }
Contoh diperluas diberikan dalam aturan 5. Perhatikan melempar pengecualian.
2) Isolasi metode. Nama fungsi adalah hasil dari generalisasi.
if( ) { foreach(var sender in senders) { sender.Send(message); } }
masuk
if( ) { SendAll(senders, message); } void SendAll(IEnumerable<Sender> senders, string message) { foreach(var sender in senders) { sender.Send(message); } }
3) Menggabungkan kondisi.
if (contributor == null) { if (accessMngr == null) {
masuk
if (contributor == null && accessMngr == null) {
4) Menghapus variabel dan membaginya menjadi blok semantik. Akibatnya, blok dapat diubah secara independen, dan yang paling penting, membaca dan memahami kode seperti itu jauh lebih mudah. Satu blok - satu fungsionalitas. Kasus umum adalah pencarian dengan pemrosesan. Penting untuk memecah kode menjadi blok semantik yang terpisah: pencarian elemen, pemrosesan.
for (int i=0;i<array.length;i++) { if (array[i] == findItem) {
masuk
for(int i=0;i<array.length;i++) { if(array[i] == findItem) { foundItem =array[i]; break; } } if (foundItem != null) {
Aturan 3. Kami menyingkirkan pengindeks dan panggilan melalui properti.Pengindeks - operasi mengakses elemen array di indeks arr [indeks].
Dalam proses memahami kode, otak beroperasi dengan simbol [] sebagai pembatas, dan pengindeks sebagai ekspresi.
function updateActiveColumnsSetting(fieldsGroups) { var result = {}; for (var i = 0; i < fieldsGroups.length; i++) { var fields = fieldsGroups[i].fields; for (var j = 0; j < fields.length; j++) { if (!result[fieldsGroups[i].groupName]) { result[fieldsGroups[j].groupName] = {}; } result[fieldsGroups[i].groupName][fields[j].field] = createColumnAttributes(j, fields[j].isActive); } } return JSON.stringify(result); }
Pengindeks adalah tempat kesalahan yang sering terjadi. Berdasarkan nama indeks pendek, sangat mudah untuk mencampur I, j atau k.
Dalam contoh di atas, dalam hasil baris [fieldsGroups [j] .groupName] = {}; kesalahan dibuat:
j digunakan sebagai ganti i.
Untuk menemukan di mana tepatnya nilai ke-i digunakan, Anda harus:
1) secara visual menyorot variabel array
function updateActiveColumnsSetting(fieldsGroups) { var result = {}; for (var i = 0; i < fieldsGroups.length; i++) { var fields = fieldsGroups[i].fields; for (var j = 0; j < fields.length; j++) { if (!result[fieldsGroups[i].groupName]) { result[fieldsGroups[j].groupName] = {}; } result[fieldsGroups[i].groupName][fields[j].field] = createColumnAttributes(j, fields[j].isActive); } } return JSON.stringify(result); }
2) untuk menganalisis setiap kejadian untuk penggunaan pengindeks yang diinginkan I, j, i-1, j-1, dll., Dengan mengingat tempat penggunaan pengindeks dan referensi yang sudah diidentifikasi dalam persepsi.
Dengan menyorot pengindeks dalam suatu variabel, kami mengurangi jumlah tempat berbahaya dan kami dapat dengan mudah menggunakan otak untuk memahami variabel, tanpa perlu menghafal.
Setelah diproses:
function updateActiveColumnsSetting(fieldsGroups) { var columnsGroups = {}; for (var i = 0; i < fieldsGroups.length; i++) { var fieldsGroup = fieldsGroups[i]; var groupName = fieldsGroup.groupName; var columnsGroup = columnsGroups[groupName]; if (!columnsGroup) { columnsGroup = columnsGroups[groupName] = {}; } var fields = fieldsGroup.fields; for (var j = 0; j < fields.length; j++) { var fieldInfo = fields[j]; columnsGroup[fieldInfo.field] = createColumnAttributes(j, field.isActive); } } return columnsGroups; }
Pemilihan visual jauh lebih sederhana, dan lingkungan pengembangan modern dan editor membantu dengan menyoroti substring di berbagai bagian kode.
function updateActiveColumnsSetting(fieldsGroups) { var columnsGroups = {}; for (var i = 0; i < fieldsGroups.length; i++) { var fieldsGroup = fieldsGroups[i]; var groupName = fieldsGroup.groupName; var columnsGroup = columnsGroups[groupName]; if (!columnsGroup) { columnsGroup = columnsGroups[groupName] = {}; } var fields = fieldsGroup.fields; for (var j = 0; j < fields.length; j++) { var fieldInfo = fields[j]; columnsGroup[fieldInfo.field] = createColumnAttributes(j, field.isActive); } } return columnsGroups; }
Aturan 4. Kelompokkan blok sesuai dengan artinya.Kami menggunakan efek psikologis persepsi - "Efek kedekatan": tokoh-tokoh yang berjarak dekat dalam persepsi digabungkan. Untuk menyiapkan kode untuk analisis dan generalisasi dalam proses persepsi, dan untuk mengurangi jumlah informasi yang tersimpan dalam memori, Anda dapat mengatur satu baris di samping satu sama lain, disatukan dengan makna atau fungsi yang dekat, membaginya dengan garis kosong.
Kepada:
foreach(var abcFactInfo in abcFactInfos) { var currentFact = abcInfoManager.GetFact(abcFactInfo); var percentage = GetPercentage(summaryFact, currentFact); abcInfoManager.SetPercentage(abcFactInfo, percentage); accumPercentage += percentage; abcInfoManager.SetAccumulatedPercentage(abcFactInfo, accumPercentage); var category = GetAbcCategory(accumPercentage, categoryDictionary); abcInfoManager.SetCategory(abcFactInfo, category); }
Setelah:
foreach (var abcFactInfo in abcFactInfos) { var currentFact = abcInfoManager.GetFact (abcFactInfo); var percentage = GetPercentage(summaryFact, currentFact); accumPercentage += percentage; var category = GetAbcCategory(accumPercentage, categoryDictionary); abcInfoManager.SetPercentage(abcFactInfo, percentage); abcInfoManager.SetAccumulatedPercentage(abcFactInfo, accumPercentage); abcInfoManager.SetCategory(abcFactInfo, category); }
Dalam contoh atas ada 7 blok, di bawah 3: mendapatkan nilai, terakumulasi dalam satu lingkaran, mengatur properti manajer.
Lekukan baik untuk mengidentifikasi tempat yang patut diperhatikan. Jadi, garisnya
accumPercentage += percentage; var category = GetAbcCategory(accumPercentage, categoryDictionary);
selain bergantung pada perhitungan sebelumnya, mereka mengakumulasikan nilai dalam variabel akumulasiPersentase. Untuk menekankan perbedaan, kode diindentasi.
Satu kasus penggunaan khusus untuk suatu aturan adalah mendeklarasikan variabel lokal sedekat mungkin dengan tempat penggunaan.
Aturan 5. Mengikuti prinsip keunikan tanggung jawab.Ini adalah prinsip SOLID pertama dalam OOP, tetapi di samping kelas, dapat diterapkan untuk proyek, modul, fungsi, blok kode, tim proyek, atau pengembang individu. Ketika ditanya siapa atau apa yang bertanggung jawab untuk bidang ini, segera jelas siapa atau apa. Satu koneksi selalu sederhana. Setiap kelas digeneralisasikan ke satu konsep, frasa, metafora. Akibatnya, semakin sedikit untuk diingat, proses persepsi lebih mudah dan lebih efisien.
Sebagai kesimpulan, sebuah contoh komprehensif:
private PartnerState GetPartnerStateForUpdate( PartnerActivityInfo partner, Dictionary<int, PartnerState> currentStates, Dictionary<int, PartnerState> prevStates) { PartnerState updatingState; if (prevStates.ContainsKey(partner.id)) { if (currentStates.ContainsKey(partner.id)) { var prevState = prevStates[partner.id]; updatingState = currentStates[partner.id]; // 1 } else { // 2 } } else if (currentStates.ContainsKey(partner.id)) { updatingState = currentStates[partner.id]; } else { throw new Exception(string.Format(" {0} {1}", partner.id, month)); } return updatingState; }
Setelah mengganti pengindeks ContainsKe, membalikkan percabangan, mengalokasikan metode, dan mengurangi tingkat bersarang, kami mendapat
private PartnerState GetPartnerStateForUpdate( PartnerActivityInfo partner, Dictionary<int, PartnerState> currentStates, Dictionary<int, PartnerState> prevStates) { PartnerState currentState = null; PartnerState prevState = null; prevStates.TryGetValue(partner.id, out prevState); currentStates.TryGetValue(partner.id, out currentState); currentState = CombineStates(currentState, prevState); return currentState; } private PartnerState CombineStates( PartnerState currentState, PartnerState prevState) { if (currentState == null && prevState == null) { throw new Exception(string.Format( " {0} {1}" , partner.id, month)); } if (currentState == null) { // 1 } else if (prevState != null) { // } return currentState; }
Fungsi pertama bertanggung jawab untuk memperoleh status dari kamus, yang kedua untuk menggabungkannya menjadi yang baru.
Aturan yang disajikan sederhana, tetapi dalam kombinasi mereka menyediakan alat yang ampuh untuk menyederhanakan kode dan mengurangi beban memori selama proses pengembangan. Anda tidak akan selalu bisa mengikutinya, tetapi jika Anda menyadari bahwa Anda tidak memahami kode tersebut, akan lebih mudah untuk memulainya. Mereka telah berulang kali membantu penulis dalam kasus yang paling sulit.