it-swarm-id.com

Praktik terbaik untuk menggunakan ruang nama di C ++

Saya telah membaca Paman Bob Kode Bersih beberapa bulan yang lalu, dan itu memiliki dampak mendalam pada cara saya menulis kode. Bahkan jika sepertinya dia mengulangi hal-hal yang harus diketahui oleh setiap programmer, menggabungkan semuanya dan mempraktikkannya menghasilkan kode yang jauh lebih bersih. Secara khusus, saya menemukan memecah fungsi besar menjadi banyak fungsi kecil, dan memecah kelas besar menjadi banyak kelas kecil sangat berguna.

Sekarang untuk pertanyaannya. Contoh-contoh buku semuanya di Jawa, sementara saya telah bekerja di C++ selama beberapa tahun terakhir. Bagaimana gagasan dalam Kode Bersih meluas ke penggunaan ruang nama, yang tidak ada di Jawa? (Ya, saya tahu tentang paket Java, tetapi sebenarnya tidak sama.)

Apakah masuk akal untuk menerapkan ide menciptakan banyak entitas kecil, masing-masing dengan tanggung jawab yang jelas, untuk ruang nama? Haruskah sekelompok kecil kelas terkait selalu dibungkus dalam namespace? Apakah ini cara untuk mengelola kompleksitas memiliki banyak kelas kecil, atau apakah biaya mengelola banyak ruang nama akan menjadi penghalang?

Sunting: Pertanyaan saya dijawab dalam --- entri Wikipedia tentang Prinsip Paket .

39
Dima

(Saya belum membaca Kode Bersih dan tidak tahu banyak tentang Java.)

Apakah masuk akal untuk menerapkan ide menciptakan banyak entitas kecil, masing-masing dengan tanggung jawab yang jelas, untuk ruang nama?

Ya, seperti halnya dengan refactoring ke dalam beberapa kelas dan beberapa fungsi.

Haruskah sekelompok kecil kelas terkait selalu dibungkus dalam namespace?

Tanpa benar-benar menjawab: ya, Anda setidaknya harus menggunakan satu namespace tingkat atas. Ini dapat didasarkan pada proyek, organisasi, atau apa pun yang Anda suka, tetapi menggunakan beberapa nama global akan mengurangi konflik nama. Satu namespace untuk mengelompokkan semua yang lain di bawahnya hanya memperkenalkan satu nama global. (Kecuali fungsi "C" eksternal, tapi itu karena interoperabilitas C dan hanya mempengaruhi fungsi "C" eksternal lainnya.)

Haruskah sekelompok kecil kelas terkait dibungkus dalam namespace yang didedikasikan untuk mereka? Mungkin. Terutama jika Anda menemukan diri Anda menggunakan awalan umum pada kelas-kelas tersebut - FrobberThing, FrobberThang, FrobberDoohickey - Anda harus mempertimbangkan namespace - frobber :: Thing dan sebagainya. Ini masih berada di bawah namespace root Anda atau namespace lain jika mereka merupakan bagian dari proyek yang lebih besar.

Apakah ini cara untuk mengelola kompleksitas memiliki banyak kelas kecil, atau apakah biaya mengelola banyak ruang nama akan menjadi penghalang?

Mengambil contoh di atas nama awalan, tidak sulit untuk mengelola frobber :: Thing daripada FrobberThing. Bahkan mungkin lebih mudah dengan beberapa alat, seperti dokumentasi dan penyelesaian kode. Ada perbedaan dengan ADL, tetapi ini bisa menguntungkan Anda: lebih sedikit nama dalam ruang nama terkait membuat ADL lebih mudah untuk diketahui, dan Anda dapat menggunakan deklarasi untuk menyuntikkan nama tertentu ke dalam satu namespace atau lainnya.

Alias ​​Namespace memungkinkan Anda menggunakan nama yang lebih pendek untuk namespace yang lebih panjang dalam konteks tertentu, yang sekali lagi memungkinkan penggunaan yang lebih mudah:

void f() {
  namespace CWVLN = Company_with_very_long_name;  // Example from the standard.
  // In this scope, use CWVLN::name instead of Company_with_very_long_name::name.
  namespace fs = boost::filesystem;  // Commonly used.
}

Pertimbangkan Boost, yang memiliki ruang nama root tunggal, boost, dan kemudian banyak ruangnama - boost :: asio, boost :: io, boost :: filesystem, boost :: tuple, dll. - untuk berbagai perpustakaan. Beberapa nama "dipromosikan" ke root namespace:

Semua definisi ada di namespace :: boost :: tuple, tetapi nama yang paling umum diangkat ke namespace :: boost dengan menggunakan deklarasi. Nama-nama ini adalah: Tuple, make_Tuple, ikat, dan dapatkan. Selanjutnya, ref dan cref didefinisikan langsung di bawah :: boost namespace.

Perbedaan terbesar dari bahasa dengan modul "nyata" adalah seberapa umum menggunakan struktur yang lebih rata, yang sebagian besar terjadi karena itulah cara kerjanya kecuali jika Anda mengambil upaya ekstra dan spesifik untuk mendefinisikan nama bersarang.

23
Fred Nurk

Anda harus memiliki satu ruang nama utama untuk semua kode Anda. Ini membedakannya dari kode eksternal berkaitan dengan ruang nama.

Di dalam master namespace Anda, tergantung pada ukuran dan kompleksitasnya, Anda dapat membuka sub-namespaces. Di sinilah nama jelas berarti sesuatu dalam konteks, dan nama yang sama dapat digunakan dalam konteks yang berbeda.

Khususnya jika Anda memiliki nama yang terdengar umum seperti FileInfo yang berarti sesuatu yang khusus dalam konteks, letakkan di namespace.

Anda juga dapat menggunakan kelas untuk ini, meskipun kelas tidak dapat diperluas sehingga Anda tidak dapat menambahkan deklarasi baru ke kelas tanpa memodifikasi headernya.

9
CashCow

Namespace bukan konsep Modul jadi saya akan menggunakannya hanya di mana konflik nama bisa terjadi.

3
Brainlag

Saya suka ruang nama yang dalam (yang biasanya berarti tiga tingkat).

  • Saya punya nama perusahaan.
  • app/util/lib/etc
  • Nama Proyek/atau Paket yang sesuai

Tergantung pada situasi saya mungkin memiliki satu level lagi

  • detail (Detail implementasi spesifik platform)
  • utils (objek utilitas yang belum dipindahkan ke utilitas umum).
  • apapun yang saya butuhkan.
1
Martin York

Java memiliki ruang nama, mereka tidak benar-benar menyebutnya. Di javax.swing.*javax adalah namespace dan swing adalah sub-namespace. Saya belum membaca buku ini untuk mengetahui apa yang dikatakannya tentang paket Java, tetapi prinsip yang sama akan berlaku hampir secara langsung pada ruang nama dalam bahasa apa pun.

Heuristik yang baik adalah Anda menggunakan namespace ketika Anda ingin mengetikkan awalan yang sama untuk kelas berulang kali. Sebagai contoh, saya baru-baru ini menulis beberapa kelas yang disebut OmciAttribute, OmciAlarm, OmciMe, dll. Dan menyadari bahwa saya perlu memecah Omci ke dalam namespace-nya sendiri.

1
Karl Bielefeldt