Jika saya terus menulis kode lagi maka akan ada waktu ketika saya akan kesulitan mengatur kode.
Ini adalah masalah Anda: perbaiki organisasi, dan gaya harus mengalir lebih mudah.
Jangan menunggu untuk mengatur kode Anda: pertahankan kode Anda tetap berjalan. Meskipun bahasa tidak melakukannya untuk Anda, kode tetap harus diatur ke dalam modul dengan kopling rendah dan kohesi tinggi.
Modul-modul ini kemudian secara alami menyediakan namespace. Singkat nama modul (jika panjang) dan awali nama fungsi dengan modul mereka untuk menghindari tabrakan.
Pada tingkat pengidentifikasi individu, ini secara kasar berada dalam urutan subyektivitas yang meningkat:
- pilih satu konvensi dan ikuti saja
- misalnya,
function_like_this(struct TypeLikeThis variable)
umum
pasti menghindari notasi Hongaria (maaf JNL)
kecuali Anda bersedia menggunakannya seperti yang dimaksudkan semula, yang berarti notasi aplikasi Simonyi daripada versi sistem yang mengerikan
Mengapa? Saya bisa menulis esai tentang ini, tetapi saya akan menyarankan Anda membaca artikel ini oleh Joel Spolsky, dan kemudian berburu lagi jika Anda tertarik. Ada tautan ke kertas asli Simonyi di bagian bawah.
hindari pointer typedefs kecuali jenis cookie yang benar-benar buram - mereka hanya membingungkan hal-hal
struct Type *ok;
typedef struct Type *TypePtr;
TypePtr yuck;
Apa yang saya maksud dengan jenis cookie buram ? Maksud saya sesuatu yang digunakan di dalam modul (atau perpustakaan, atau apa pun) yang harus diteruskan ke kode klien, tetapi kode klien itu tidak dapat digunakan secara langsung. Itu hanya meneruskannya kembali ke perpustakaan.
Sebagai contoh, pustaka database mungkin mengekspos antarmuka seperti
/* Lots of buffering, IPC and metadata magic held in here.
No, you don't get to look inside. */
struct DBContextT;
/* In fact, you only ever get a pointer, so let's give it a nice name */
typedef struct DBContexT *DBContext;
DBContext db_allocate_context(/*maybe some optional flags?*/);
void db_release_context(DBContext);
int db_connect(DBContext, const char *connect);
int db_disconnect(DBContext);
int db_execute(DBContext, const char *sql);
Sekarang, konteksnya buram ke kode klien, karena Anda tidak dapat melihat ke dalam. Anda baru saja mengembalikannya ke perpustakaan. Sesuatu seperti FILE
juga buram, dan deskriptor file integer juga cookie , tetapi tidak buram.
Catatan tentang desain
Saya menggunakan frasa kopling rendah dan kohesi tinggi di atas tanpa penjelasan, dan saya merasa agak buruk tentang itu. Anda dapat mencarinya, dan mungkin menemukan beberapa hasil yang baik, tetapi saya akan mencoba mengatasinya secara singkat (sekali lagi, saya bisa menulis esai tetapi akan berusaha untuk tidak melakukannya).
Pustaka DB yang digambarkan di atas menunjukkan kopling rendah karena memperlihatkan antarmuka kecil ke dunia luar. Dengan menyembunyikan detail implementasinya (sebagian dengan trik cookie yang tidak jelas), ia mencegah kode klien bergantung pada detail itu.
Bayangkan alih-alih cookie buram, kami mendeklarasikan struktur konteks sehingga isinya terlihat, dan itu termasuk deskriptor file socket untuk koneksi TCP ke database. Jika kami kemudian mengubah implementasi untuk mendukung menggunakan segmen memori bersama ketika DB berjalan pada mesin yang sama, klien perlu dikompilasi ulang daripada hanya dihubungkan kembali. Lebih buruk lagi, klien bisa mulai menggunakan deskriptor file, misalnya panggilan setsockopt
untuk mengubah ukuran buffer default, dan sekarang perlu perubahan kode juga. Semua perincian ini harus disembunyikan di dalam modul kami di mana praktis, dan ini memberikan sambungan rendah antara modul.
Contoh ini juga menunjukkan kohesi yang tinggi , bahwa semua metode dalam modul berkaitan dengan tugas yang sama (akses DB). Ini berarti bahwa hanya kode yang perlu tahu tentang detail implementasi (yaitu, konten cookie kami) yang benar-benar memiliki akses ke mereka, yang menyederhanakan proses debug.
Anda juga dapat melihat bahwa memiliki satu masalah memudahkan untuk memilih awalan untuk mengelompokkan fungsi-fungsi ini bersama-sama.
Sekarang, mengatakan contoh ini baik itu mudah (terutama karena itu bahkan tidak lengkap), tetapi tidak segera membantu Anda. Triknya adalah menonton, saat Anda menulis dan memperluas kode Anda, untuk fungsi yang melakukan hal serupa atau beroperasi pada tipe yang sama (yang mungkin merupakan kandidat untuk modul mereka sendiri), dan juga untuk fungsi yang melakukan banyak hal terpisah yang tidak benar-benar terkait, dan mungkin menjadi kandidat untuk berpisah.