Dahili uygulamalar için neden dahili kütüphaneler geliştirilmeli?


10

Yalnızca dahili uygulamaları geliştirmek için kullanılacak iç kütüphaneleri neden geliştirmeniz gerektiğini anlamakta güçlük çekiyorum. Kuruluş dışından birinin yazdığı bir yazılımı kullanmak istersem bana başlık dosyalarını ve .a veya .so dosyalarını gönderebileceklerini ve projeme bağlayabileceğimi (aynı ortamda derlenmiş olduklarını varsayarak) takdir ediyorum. .

Ancak üstbilgiye ve uygulama dosyalarına erişebildiğimde ve bunları kaynak ağacıma dahil edip hepsini bir araya getirebildiğimde neden bir dahili kütüphane dahili bir uygulamaya bağlanacak şekilde geliştirilmeli?

Başka bir deyişle: bazı kaynak kodları yazılırsa, bunların bir ikili kitaplığa derlenip uygulamanızla bağlantılı mı yoksa sadece projenin kaynak dosyalarına dahil edilip düzenli olarak mı derleneceğine nasıl karar verirsiniz?

Her projeye 'dahil et' dediğimde, her dosyayı kopyalayıp şu anda geliştirilmekte olan projenin kaynak ağacına yapıştırmak istemiyorum. Yani, bir projenin dosyalarına her zamanki gibi dahil edilebilecek ortak kaynak kodu içeren bazı dizin / kütüphane (herhangi bir projeden ayrı) geliştirme demek, yani #include.

ps Birden fazla masaüstü uygulaması için burada c / c ++ geliştirme hakkında konuşuyorum.


Yanıtlar:


25

Dahili kullanım için bile kitaplıklar ve paylaşılan kitaplıklar (.dll veya .so dosyalarında) oluşturmanın çeşitli nedenleri vardır :

  1. Projeler arasında yeniden kullanım çok daha temiz
  2. Sorumlulukların ayrılması - kodunuzun bir kısmı farklı geliştiriciler veya ekipler daha uygun olabilir
  3. Belirli bir kodu bulmak zorunda kalmadan diğer ekiplerin yaptığı kitaplıklardaki iyileştirmelerden yararlanabilirsiniz
  4. Daha hızlı derleme süreleri, kütüphane kararlıysa yeniden inşa edilmesine gerek yoktur.
  5. Disk Alanı - projedeki yalnızca kütüphaneye ve başlıklara sahip olabilirsiniz
  6. Paylaşılan kitaplıklar kullanıyorsanız, birkaç program kullanıyor olsa bile RAM'e yalnızca bir kopya yüklenmiş olarak bellek tasarrufu yapabilirsiniz
  7. Genellikle kütüphanelerin daha iyi belgelenmesi ve test edilmesi ile sonuçlanırsınız
  8. Temizleyici tasarımı ve kod - kütüphaneler içine yapılandırma şeyleri düşünme her kütüphanede işlevsellik ilgili gruplar neden olmalı ve sen jenerik kodunu ayırmak eğiliminde kütüphaneler içine , uygulama özelliğinden, app .
  9. Kütüphanelerde özel algoritmalarınız varsa, kaynağa erişimi kısıtlayabilirsiniz, örneğin yüklenicilerin veya dışarıdan gelen ekiplerin kaynağa erişmesine izin vermemek.
  10. Kütüphane kodu, başlangıçta bir parçası olarak yazılan Uygulamaya farklı bir lisans altına yerleştirilebilir, bazı şirketler Açık Kaynak kütüphanelerinde gurur duydukları bile bilinir - Açık Kaynak topluluğunda büyük kudoslar kazanırlar ve bazen önemli geliştirmeler katkıda bulunurlar geri.

Bazı şirketler, kütüphane oluşturan projelerin her yeniden kullanımda geri ödeme aldığı bir muhasebe uygulamasına bile sahiptir.


1
Veya 9 numaralı bir varyasyonda, kitaplığı ana uygulama kodundan farklı bir lisans altında serbest bırakabilirsiniz.
Michael Borgwardt

@MichaelBorgwardt - Yukarıda 10. maddeyi yönlendiren iyi bir nokta.
Steve Barnes

Ayrıca, ayrı bir kütüphane olarak bazı kodlara sahip olmak, programlama sırasında kısayollardan kaçınmaya yardımcı olur, örneğin "Bu ekstra parametreyi buraya ekleyeceğim .." ve gerekli özellikleri uygulamanın daha iyi yollarını bulmaya yardımcı olur.
Valdas

11

Daha büyük, önemsiz projeler için geçerli olabilecek diğer olası nedenler:

  • Derleme süreleri: Binlerce dosya, binlerce sınıf, işlev vb.İle büyük monolitik C ++ projelerinin derlenmesi çok uzun zaman alabilir (birkaç kod satırını her değiştirdiğinizde yeniden derlemek istiyorsanız üretkenlik zarar verir). Statik olarak bağlanmış ve dinamik olarak bağlanmış kitaplıklar bağımsız olarak derlenir ve kaynakları değişmediyse yeniden derlenmeleri gerekmez.

  • Farklı modüllerin veya alt sistemlerin mantıksal olarak ayrılması : Farklı işlev alanlarının ayrı modüllere yerleştirilmesi durumunda büyük sistemlerin yönetimi genellikle daha kolaydır ve geliştiriciler binlerce dosya / sınıf içeren muazzam klasörlerde / projelerde arama yapmakla karşılaşmazlar.

  • Geliştiriciler / ekipler arasındaki sınırlar : Aynı anda ayrı yeni işlevsellik oluşturan geliştiriciler, her geliştiricinin farklı modüllerde çalışmasını sağlamak için birleştirme çakışmaları olasılığını azaltabilir.

  • Canlı bir ortama bırakılmaması gereken kod : Örneğin, canlı sistem bileşeninin (donanım, API'ler, uzak sistemler, veritabanları vb.) Yerine geliştirici sınaması için kullanılan birim sınama kitaplıkları veya 'sahte' kitaplıklar.

  • Derleyici bayrakları : Kendinizi, garip bir derleyici bayrağı bekleyen bazı 3. taraf API'sı ile entegrasyon konusunda çok talihsiz bir konumda bulursanız, kütüphane, 3. taraf API ile uygulamanın geri kalanı arasında oturan bir "dekontaminasyon katmanı" olabilir.

  • İsteğe bağlı özellikler / Optimizasyon : Büyük sistemlerde, bir uygulama dinamik olarak bağlı belirli modülleri uygulamanın temel işlevselliği için kritik değilse çalışma zamanında belleğe yüklemeden önce bekleyebilir.


Genel olarak, birçok iç proje genellikle ayrı kütüphanelere bölünmekten fayda sağlamayan küçük mikro uygulamalardır. Yalnız bir geliştirici olarak küçük bir proje üzerinde çalışıyorsanız, kodunuzu kütüphanelere bölme konusunda endişelenmenize gerek olmayabilir (henüz ...). YAGNI prensibini unutmayın .


3
@downvoter - downvote'un nedenini açıklayabilir misiniz? Yanıtlarla ilgili geri bildirim, bu sitenin kalitesini herkes için iyileştirmek için yararlıdır.
Ben Cottrell

4

Orijinal sorunuz diğer yanıtların çoğu için burada yanlış anlaşılmaya neden olmuş olabilir. Mevcut kodu projeler arasında kopyalamak değil , aynı kaynak dosyalarını farklı projelerden referans olarak dahil etmek istediğiniz için, "yinelenen kod" bağımsız değişkenleri ve sunulan diğer birçok bağımsız değişken anlamsız hale gelir.

Bunun bazen (- her zaman değil -) mantıklı bir teknik olduğuna dikkat edin . Aslında, projeler arasında yeniden kullanmak istediğiniz tüm kaynak dosyalarını tek bir içerme klasörüne koyduğunuzda, zaten bir libary de oluşturdunuz - ikili bir lib değil bir kaynak kodu kütüphanesi. Özellikle C ++ 'da, şablonlarla genel kütüphaneler oluştururken, sadece basit bir içerme gerektiren ve ayrı bir bağlantı hazırlığı gerektirmeyen sadece başlık kütüphanelerine sahip olmak olağandışı değildir.

Yani asıl soru - kaynak kod kütüphaneleri ne zaman inşa edilmeli, ya da önceden derlenmiş ikili kütüphaneleri ne zaman tercih etmeliyim? Bu sitedeki bu eski cevapta, sadece başlık libs'lerinin bazı artılarını ve eksilerini tartıştım, belki size yardımcı olabilir. Kaynak kodu kütüphanelerinin ana avantajı, bunları kullanan uygulama ile aynı çalışma zamanı ve / veya uyumlu derleyici / bağlayıcı bayrakları ile derlenmeleri gerekmemesidir. Dezavantajları, ek derleme süreleri ve kaynak koduna erişim sağlama gereksinimidir (bu, aklınızdaki "dahili" projeler için bir sorun değildir).


Sadece tipik #include yönergesi ile ihtiyacınız olan dosyalara başvurduğunuz birden fazla projede ortak olan bir kaynak kodu kütüphanesi demek istediğim doğru - bunu söyleyene kadar terimi bilmiyordum ve şimdi soru. Bağlantılı cevabınız da çok faydalı.
Andrew Murtagh

@AndrewMurtagh: MichaelBorgwardt'ın cevabını çok hızlı bir şekilde kabul ettiğiniz gerçeği beni şaşırttı, çünkü yazdığı şey ya onun ya da benimkinin yanlış anlaşılması gibi görünüyor.
Doc Brown

Peki o zaman birden fazla proje için ortak olacak kodu tek bir pakette (ikili kütüphaneler veya kaynak kodu kütüphanelerinde olsun) gruplamak hakkında ne vardı ilk karışıklık açıklığa kavuşturdu ama verdim, ben kaynak tek bir dizin olması hakkında konuşuyordu Projeler arasında paylaşılabilecek ve her dosyayı her projeye kopyalayıp yapıştıramayacağım kodlar.
Andrew Murtagh

2

Kod kopyalamamanız gerektiğini yazarken diğer yorumcularla aynı fikirdeyim. Senin durumunda, ancak siz (veya birlikte çalıştığınız kişi) kodu kütüphaneleri oluşturmak gibi görünüyor değil başka yerde çoğaltılamaz.

Bu durumda, erken genellemeye karşı uyarıyorum . Kişinin bir kod parçasının yeniden kullanılabilir olacağını hissettiği zamanlar vardır . Bununla birlikte, ikinci kullanım durumunun bu kodu nasıl kullanacağına dair ayrıntılı bilgileri bilmeden, ek durumlarda gerçekten yararlı olmayacak "yeniden kullanılabilirlik" özellikleri için ekstra zaman harcamak veya yanlış kanıtlayan varsayımlar yapmak çok kolaydır. İkinci dava.

Bir kullanım vakası için bir "kütüphane" yazmak, herhangi bir kazanç olmadan çok pahalı bir egzersize dönüşebilir --- Bunu birkaç kez ısırdım.

Örnek maliyetler:

  1. "Genel" kullanım durumlarını değerlendirmek için harcanan zaman / enerji
  2. "Kütüphaneyi" "müşterinize" (kendi kodunuza) dağıtılabilir hale getirmek için harcanan zaman
  3. Bir sonraki kullanım örneğiyle tam olarak eşleşmese bile "kütüphane" yi kullanmak için gelecekteki baskı

Genel kuralım: Kodun gerekli olduğu en az 2 ayrı yerim olmadıkça kodu kitaplığa dönüştürmeyin.


2
Bazı geliştiriciler tarafından kullanılan kodların neden tek bir> 20k satır kaynak dosyasında olduğu gibi hemen hemen aynı nedenleri gördüm. İlginç adlandırma ve zayıf yorumlar ile birleştirildiğinde, yakında yeniden yazmanın korumaktan daha hızlı olduğu bir kodunuz olacaktır.
Steve Barnes

Harika bir nokta: Kesinlikle korunabilir, okunabilir kod yazmaya karşı tartışmıyorum. Ayrı dosyalar, iyi adlandırılmış yöntemler / sınıflar ve paket yapısı, sürdürülebilirliğin önemli bileşenleridir. Demek istediğim, sadece bir kütüphane yazma ve dağıtma maliyetinin "kütüphane" için tek bir kullanım durumu olduğunda ortaya çıkmasıdır.
Sam

1
Tersine, her durumda bir kütüphaneyi paketlemeniz ve dağıtmanız gerektiğini savunmuyorum, sadece kodunuzun bir gün kütüphane haline gelmesi gibi yazma ve yapılandırma genellikle biraz çaba sarf etmeye değer ve kod asla olmazsa bile genellikle temettü ödüyor kütüphane olarak dağıtılır.
Steve Barnes

1

üstbilgiye ve uygulama dosyalarına erişebildiğimde ve bunları kaynak ağacıma ekleyip hepsini bir araya getirebileceğimde neden bir dahili kütüphane dahili bir uygulamaya bağlanacak şekilde geliştirilmeli?

Çünkü "sadece kaynak ağacıma eklerseniz" kodu çoğaltırsınız .

Buradaki sorun, kodu kopyaladığınız proje tarafından yapılan herhangi bir iyileştirmeden (kritik hata düzeltmeleri dahil) ve sizin yaptığınız iyileştirmelerden yararlanamayacağınızdır.

Bu sorunu, kodun en yeni sürümünü düzenli olarak kaynak ağacınıza kopyalayarak, belki de git'de bir alt modül veya benzeri bir şey kullanarak otomatik olarak kopyalayarak çözebileceğinizi düşünebilirsiniz. Ancak, uyumsuz API değişiklikleri nedeniyle derleme sürenizi sürekli olarak alırsınız. Diğer yandan bir kütüphane, geliştiricilerinin müşterileriyle koordinasyon olmadan değiştirilemeyeceğini bildikleri "resmi" bir ortak API'ya sahiptir.

Son olarak, teknik nedenler olabilir - kodun bir kısmını bir kütüphane olarak tutmak gerekli olabilir;


1
Anladığım kadarıyla, bir kütüphaneye kod parçası yapmanın ana nedeni, kodun çoğaltılmaması, güncellenmemesi, sürdürülmemesi için farklı projelerde (hepsi dahili olarak geliştirilse bile) kullanılacak olmasıdır. ayrı ayrı? Ve sadece tek bir proje geliştirecekseniz, daha sonra başka bir projede kullanmayı düşünmüyorsanız, kütüphaneye bir şey yapmaya gerek yoktur.
Andrew Murtagh

@AndrewMurtagh: Evet, tam da böyle koydum. Teknik nedenler olsa da; Ben C / C ++ geliştirme aşina değilim - belki isteğe bağlı olarak yüklenebilir, hatta isteğe bağlı olarak yüklenebilir ve talep üzerine boşaltılabilir ve böylece işlevsellik gerekli olmadığında bellek kullanımını azaltmak böylece kodun bir parçası olarak kütüphane tutmak gerekli?
Michael Borgwardt

Bunun paylaşılan kütüphaneler aracılığıyla mümkün olabileceğine inanıyorum. Açıkladığınız için teşekkürler, cevabınızı kabul edilmiş olarak işaretleyeceğim.
Andrew Murtagh

Son on yıldaki neredeyse her VCS harici referansları veya alt modülleri desteklemektedir. Bu, yinelenen kod ve hata düzeltme sorunu kaldırıldı. Geçerli sorun olduğuna hala inanıyorsanız, bunların neden uygun bir çözüm olmadığı hakkında daha fazla bilgi içerebilir.
Sirisian

Bakımda da düşünün. 1) Lib bağımsız ve paralel olarak muhafaza edilebilir. 2) Kodun değiştirilmesi kolaydır. 3) Küçük kod tabanının küçük takımlar için yönetilmesi ve herkes için anlaşılması daha kolaydır. 4) pazara sunma süresi kritikse, daha hızlı inşa etmeyi tercih edersiniz. Libs olarak kod, boru hattında (IMO) tekrar tekrar derlemediğiniz koddur. 5) Güvenilir yeniden kullanılabilir kod ...
Başardınız

1

Çözümünüzün daha uzun vadede sahip olduğu maliyetler üzerinde durmak istiyorum.

Açıkçası, bir projeye kütüphane eklenmesi bazı yükleri vardır, her şeyden önce ilkse: iş akışları değiştirilmelidir, bazen altyapı bile ve bazı ekip üyeleri onu sevmeyebilir (ilk başta). Daha az maliyetler getirdiği için yüzden çözümün avantajları ortada şimdi .

Ancak, projeniz büyüdükçe "sözde kütüphane" maliyeti de olacaktır. ABir uygulama ve birim test cihazı tarafından kullanılan bir "sözde kitaplığınız" olduğunu varsayın . Her cpp Aeklediğinizde, bunu her iki projeye de eklemeniz gerekir, aksi takdirde bağlantı oluşturmazlar.

"Sözde kitaplığınız" başka bir "sözde kitaplık" tarafından kullanılıyorsa ne olur B? Daha fazla projeye yeni cpp'nizi eklemelisiniz. Ve Bbaşka bir kütüphane kullanmak için geçiş yaparsanız ? Sadece Abağlı olarak tüm projelerde cpps silmek zorunda kalacak B.

Gerçek bir kütüphane kullanılacaksa bunların hepsi ücretsiz olacaktır. Yani soru şu ki, gerçek bir kütüphaneye taşınmayı haklı çıkarmak için kaç cpp'ye ihtiyaç var?

Ancak bekleyin, daha da fazla teminat var: Bir geliştirici, yeni cpp'ye ihtiyaç duyan tüm projeleri avlamaktan bu aptalca işi sevmiyor ve kodunu / sınıflarını zaten mevcut olan dosyalara bir yere ekleyecek, ki bu iyi bir şey değil. uzun koşu.

Bu nedenle, "sözde kitaplığı" kullanmak, yekpare bir projeyi kırmak için ilk adım olabilir, ancak avantajlarını kullanabilmek için gerçek bir kitaplık yapmak için çok uzun süre beklememelisiniz.


0

Ancak üstbilgiye ve uygulama dosyalarına erişebildiğimde ve bunları kaynak ağacıma dahil edip hepsini bir araya getirebildiğimde neden bir dahili kütüphane dahili bir uygulamaya bağlanacak şekilde geliştirilmeli?

Kitaplık yalnızca bir uygulama tarafından kullanılıyorsa, muhtemelen ayrı bir kitaplık olarak ihtiyacınız yoktur .

Kütüphane 3500 uygulamalar tarafından kullanılırsa o zaman mutlaka yapmak ayrı bir kitaplık olarak buna ihtiyacım var.

Kütüphanede bir hata varsa ve düzeltmeniz gerekiyorsa ne olur? Veya bazı yasal veya düzenleyici değişim söz konusu araçlarla birlikte geliyor olması yolu kütüphane çalışmaları değiştirilir?

Ayrı bir kütüphanedeyse, kütüphaneyi (potansiyel olarak) düzeltebilir, yeniden test edebilir ve yeniden dağıtabilirsiniz ve her uygulama düzeltmeden yararlanır.

Her uygulama için yalnızca "yerel" olan kaynak kodundaysa, her uygulamayı ayrı ayrı değiştirmeniz, yeniden oluşturmanız, yeniden test etmeniz ve yeniden dağıtmanız gerekir . Bu çok daha büyük (yani daha pahalı) bir egzersiz.

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.