Ad alanlarını C ++ ile kullanmak için en iyi yöntemler [kapalı]


38

Bob Amca'nın Temiz Kodunu birkaç ay önce okudum ve kod yazma biçimim üzerinde derin bir etkisi oldu. Her programcının bilmesi gereken şeyleri tekrar ediyormuş gibi görünse bile, hepsini bir araya getirmek ve uygulamaya koymak daha temiz bir kodla sonuçlanır. Özellikle, büyük fonksiyonları birçok küçük fonksiyona bölmeyi ve büyük sınıfları inanılmaz derecede faydalı olması için birçok küçük sınıfa bölmeyi buldum.

Şimdi soru için. Kitabın örneklerinin tümü Java'da, son birkaç yıldır C ++ ile çalışıyorum. Temiz Kod'daki fikirler , Java'da bulunmayan ad alanlarının kullanımına nasıl uzanır? (Evet, Java paketlerini biliyorum, ancak gerçekten aynı değil.)

Her biri açıkça tanımlanmış bir sorumluluğu olan çok sayıda küçük varlık yaratma fikrini ad alanlarına uygulamak mantıklı mıdır? Küçük bir grup ilgili sınıflar her zaman bir isim alanına sarılmalı mıdır? Bu, çok sayıda minik sınıfa sahip olmanın karmaşıklığını yönetmenin yolu mu, yoksa çok sayıda isim alanı yönetmenin maliyeti yasaklayıcı mı olacak?

Düzenleme: Sorumum, Paket İlkeleri ile ilgili bu Wikipedia girişinde cevaplandırılmıştır .


7
Başka bir iyi ve gerçek dünya geliştirici sorusu örneği kapandı . Bu, stackexchange sitesinin geliştirici en iyi uygulamaları hakkında sorması gereken değilse, nedir?
Sam Goldberg

@SamGoldberg: daha iyi olur. Bu soruya burada iyi bir cevap buldum: en.wikipedia.org/wiki/Package_Principles . Bu cevabı ben gönderdim ve bir moderatör sildi, çünkü sadece bağlantıyı gönderdim ve içeriği kopyalamak / yapıştırmak için zamanım olmadı.
Dima,

1
Sanırım soru hakkındaki tek eleştirim, sonunda birden fazla soru sormak yerine, soruyu tek bir soruda özetlemeye çalışacağım, örneğin, "eşyanın aynı isim alanında mı yoksa farklı ad alanlarında mı olacağını belirlemek için kriterler ne olmalı? ".
Sam Goldberg

Yanıtlar:


22

( Temiz Kod okumamıştım ve fazla Java bilmiyorum.)

Her biri açıkça tanımlanmış bir sorumluluğu olan çok sayıda küçük varlık yaratma fikrini ad alanlarına uygulamak mantıklı mıdır?

Evet, aynı çoklu sınıflara ve çoklu fonksiyonlara yeniden yapılanmada olduğu gibi.

Küçük bir grup ilgili sınıflar her zaman bir isim alanına sarılmalı mıdır?

Aslında cevap vermeden: evet, en azından bir üst seviye ad alanı kullanmalısınız. Bu, projeye, organizasyona veya istediğiniz her şeye bağlı olabilir, ancak birkaç genel ad kullanmak ad çakışmalarını azaltacaktır. Altındaki her şeyi gruplamak için tek bir ad alanı yalnızca bir genel ad tanıtır. (Harici "C" işlevlerinin haricinde, ancak bu, C'nin birlikte çalışabilirliği nedeniyledir ve yalnızca diğer dış "C" işlevlerini etkiler.)

Küçük bir ilgili sınıflar grubu, kendilerine ayrılmış bir ad alanına sarılmalı mıdır? Muhtemelen. Özellikle, kendinizi bu sınıflar üzerinde ortak bir önek kullanarak bulursanız - FrobberThing, FrobberThang, FrobberDoohickey - Bir ad alanını düşünmelisiniz - frobber :: Thing vb. Bu, eğer daha büyük bir projenin parçasıysa, kök ad alanınız veya başka bir ad alanın altında olacaktır.

Bu, çok sayıda minik sınıfa sahip olmanın karmaşıklığını yönetmenin yolu mu, yoksa çok sayıda isim alanı yönetmenin maliyeti yasaklayıcı mı olacak?

Yukarıdaki önek adlarına bakıldığında, FrobberThing'den frobber :: Thing'i yönetmek zor değildir. Belgeleme ve kod tamamlama gibi bazı araçlarla daha kolay olabilir. ADL ile bir fark var, ancak bu sizin lehinize işe yarayabilir: ilişkili isim alanlarındaki daha az sayıda isim, ADL'nin daha kolay anlaşılmasını sağlar ve belirli isimleri bir isim alanına ya da başka birine enjekte etmek için bildirimler kullanarak koyabilirsiniz.

Ad alanı takma adları, belirli bir bağlamda daha uzun bir ad alanı için daha kısa bir ad kullanmanıza izin verir;

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.
}

Çeşitli kütüphaneler için tek bir kök ad alanına sahip, artır ve sonra birçok alt ad alanını içeren Boost'u düşünün - boost :: asio, boost :: io, boost :: filesystem, boost :: tuples, vs. Bazı isimler kök isim alanına "terfi" edilir:

Tüm tanımlar namespace :: boost :: tuples içindedir, ancak en yaygın isimler bildirimler kullanılarak namespace :: boost'a kaldırılmıştır. Bu isimler: tuple, make_tuple, kravat ve olsun. Ayrıca, ref ve cref doğrudan :: boost ad alanının altında tanımlanır.

"Gerçek" modülleri olan dillerden en büyük fark, yuvalanmış isimleri tanımlamak için fazladan ve özel bir çaba göstermediğiniz sürece nasıl çalıştığıdır, çünkü düz olan bir yapı kullanmak ne kadar yaygındır.


+1 @Fred Nurk bir satır yerine tüm analiz için cevaplar. Sorunun ne hakkında olduğunu öğrenmek için kitabı okumak zorunda değilsiniz. Bu yorum dizisi, bir C ++ ve Java programcısının bu kitapta sahip olabileceği kavramları ve farklılıkları ortaya koyuyor. Amazon'da Temiz Kod yorumu
Marlon

8

Tüm kodunuz için bir ana ad alanınız olmalıdır. Bu, isim alanları bakımından onu harici kodlardan ayırır.

Ana ad alanınızda, boyut ve karmaşıklığa bağlı olarak, alt ad alanları açabilirsiniz. Bu, adların bir bağlam içinde açıkça bir anlam ifade ettiği ve aynı adların farklı bir bağlamda kullanılabileceği yerdir.

Özellikle, bir bağlam içinde özel bir şey ifade eden FileInfo gibi genel bir sondaj adınız varsa, onu bir ad alanına koyun.

Bir sınıf genişletilebilir olmasa da, bunun için bir sınıf da kullanabilirsiniz, bu nedenle başlığını değiştirmeden sınıfa yeni bildirimler ekleyemezsiniz.


3

Ad alanları bir Modül kavramı değil, onları yalnızca ad çakışmalarının yaşanabileceği yerlerde kullanırdım.


4
Ne demek istediğinden emin değilim. Neden bir ad alanına sarılmış bir dizi ilgili sınıf modül olmasın?
Dima

İsim alanı içerisinde herhangi bir kısıtlama yoktur. Bir modülde verilen bir sınıfa, işleve veya değişkene yalnızca modülün içinden erişilebildiğini söyleyebilirsiniz. Bir ad alanında bu mümkün değildir, adın önekidir.
Brainlag

3
Bir modülün tanımına katılmıyoruz gibi görünüyor . Bana göre, ilişkili varlıkları birlikte gruplayan ve açıklayıcı bir adı olan herhangi bir şey, kapsülleme sağlayıp yapmadığına bakılmaksızın bir modüldür.
Dima

3
Erişim kısıtlaması modüllere diktir. Aslında, Python's gibi, C ++ 'ın ad alanlarından kesinlikle “modül benzeri” olan ancak erişim kısıtlaması getirmeyen başarılı sistemleriniz var.
Fred Nurk

Bunun Scott Meyer'in kitaplarında listelenen en iyi uygulamalardan biri olduğuna inanıyorum
Raphael,

1

Java'nın ad alanları var, sadece buna gerçekten denmiyorlar. İçinde javax.swing.* javaxbir ad alanı ve swingbir alt ad alanıdır. Java paketleri hakkında ne yazdığını bilmek için kitabı okumamıştım, ancak aynı prensipler herhangi bir dildeki ad alanlarına doğrudan uygulanacaktı.

İyi bir sezgisel, tekrar tekrar sınıflar için aynı öneki yazmak istediğinizde, bir ad alanı kullanmanızdır. Örneğin, yakın zamanda OmciAttribute, OmciAlarm, OmciMe, vb. Denilen bazı sınıfları yazdım ve Omci'yi kendi ad alanına bölmem gerektiğini anladım.


1

Derin ad alanlarını severim (bu genellikle üç seviye anlamına gelir).

  • Şirket ismim var.
  • Uygulama / Util / lib / etc
  • Proje Adı / veya Paketi uygun

Duruma bağlı olarak bir seviye daha olabilir

  • detaylar (Platforma özel uygulama detayları)
  • utils (henüz genel hizmet programına taşınmamış yardımcı program nesnesi).
  • neye ihtiyacım varsa.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.