C için Tasarım İlkeleri, En İyi Uygulamalar ve Tasarım Modelleri (veya genel olarak Prosedürel Programlama)? [kapalı]


93

Bir C projesi tasarlarken izlenebilecek bilinen tasarım ilkeleri, en iyi uygulamalar ve tasarım modelleri var mı? Veya genel olarak prosedürel (zorunlu) programlama için faydalı tasarım ilkeleri?

(Ben 'nesne yönelimli neslin çocuğuyum ve ilk kez büyük bir C projesi tasarlamak zorundayım)


1
Bu sorunun cevapları ilginizi çekebilir: stackoverflow.com/questions/661307/…
mouviciel

7
Sorumu göndermeden önce biraz internet ve üniversite kütüphanesi araştırması yaptım ve kesinlikle C için yazılım tasarımıyla ilgili kitaplarla boğulmadım.Sizden en sevdiğiniz şeyi soruyorum (genel C kitaplarından bahsetmiyorum, anlamlı değişken gibi kodlama kurallarından bahsetmiyorum) isimler, ancak daha yüksek bir soyutlama, yazılım mimarisi seviyesi hakkında). Dahası, 'başkalarına bağımlı olma' suçlamanıza da katılmıyorum. Her programcının en iyi uygulamaları ve iyi tasarım modellerini kendi başına öğrenmesi gerektiğini mi söylüyorsunuz? Bu, kesinlikle başkalarının deneyimlerinin kullanılması gereken bir sorudur.
Dimi

2
Üzgünüm Dimi, bu özellikle seninle ilgili değildi ve ben pek net değildim. Bu şeyler sözlü gelenek tarafından diğer yollardan olduğu kadar aktarılırdı: nominal bir resmi "Kalıplar" kümesi yoktu, Jonathon'un cevabı kitaplarda bulacağın şeydi ama herkes bilgi gizlemeyi biliyordu. Görünüşe göre sözlü gelenek kayboluyor ve birçok genç programcı kapsülleme ve ayırmayı OOP'nin icat ettiğini düşünüyor. Bu topluluk benim görmek istediğimden daha az kendi tarihine sahip görünüyor. Böylelikle huysuz yaşlı adam bölgesinde olduğumu kabul ediyorum.
dmckee --- eski moderatör yavru kedi

1
Ayaklarımı sahada bulduğum için geçmişe dönük görüşünüzü paylaşamam, ama önerinizi kabul ediyorum. Kendinizi daha net ifade ettiğiniz için teşekkür ederiz, deneyimli bir kişinin görüşünü okumak için her zaman çok değerli. Katkınızı gerçekten takdir ediyorum.
Dimi

SEI CERT C Kodlama Standardı, Kullanmaktan kaçınmanız gereken şeylerin yanı sıra İyi Kurallar ve Ortak iyi uygulamalar sunar .
Rami

Yanıtlar:


66

Bilgi gizleme - Parnas'ın ( Yazılım Temelleri ) benimsediği gibi .

Başlıklar ve görünürlüğün dikkatli yönetimi:

  • Dış dünyadan gizlenebilecek bir kaynak dosyadaki her şey; yalnızca belgelenmiş harici arayüz açığa çıkarılmalıdır.
  • Açığa çıkan her şey bir başlıkta bildirilir.
  • Bu başlık, işlevselliğin gerekli olduğu (ve tanımlandığı) yerde kullanılır.
  • Başlık bağımsızdır - ihtiyacınız olduğunda onu kullanırsınız ve 'başka hangi başlıkları da eklemek zorundayım' konusunda endişelenmenize gerek yok çünkü başlık, onu yapmak için ihtiyaç duyduğu her şeyi ekleyerek çalışmasını sağlar iş.
  • Başlık kendinden korumalıdır - bu nedenle birden çok kez dahil edilmiş olması önemli değildir.

    #ifndef HEADER_H_INCLUDED
    #define HEADER_H_INCLUDED
    ...rest of header contents, including other #include lines if necessary
    #endif /* HEADER_H_INCLUDED */
    
  • 'Nesneler' (genellikle yapılar) üzerinde çalışmak için işlev kümeleri tasarlayın ve onu kullanan koddaki yapının iç kısımlarını araştırmak yerine bu işlevleri kullanın. Bunu kendi kendine empoze edilen bir kapsülleme olarak düşünün.


İyi nokta, teşekkürler Jonathan. Soyut veri türleri, temiz bir kullanım ve uygulama ayrımı (bilinen harici arayüz ve bilinmeyen dahili uygulama) ile bilgi gizlemenin başka bir iyi örneğidir.
Dimi

23

Üç tavsiyem:

  • Birim testleri yazın. İlerledikçe sorununuza uygun bir tasarıma odaklanmanıza yardımcı olacaklar. (Yalnızca) önceden meditasyon yapılmış düşünceye güvenmekten çok daha iyi.
  • İlk günden itibaren kurulu ve çalışan bir bellek sızıntı detektörü (orada her tür kitaplık var) bulundurun. Program / testler çıkar çıkmaz bu kitaplığın tüm sızıntıları yazdırmasını sağlayın. Bu, bir sızıntıyı ortaya çıkarır koymaz yakalamanıza izin verecek ve böylece düzeltilmesini çok daha az acı verici hale getirecektir.
  • OOP kodunu C'de yazın. O kadar zor değil. Yöntemin geçersiz kılınmasını taklit etmek mümkün olsa da, basit nesnelerin öykünmesiyle başlamanızı öneririm. Bu basit mekanizma bile size büyük bir kilometre katabilir.

İşte bir örnek:

typedef struct Vector {
  int size;
  int limit;
  int* ints; 
} Vector;

Vector* Vector_new() {
  Vector* res = (Vector*) malloc(sizeof(Vector));
  res->limit = 10;
  res->size = 0;
  res->ints = (int*) malloc(sizeof(int) * res.limit);

  return res;
}


void Vector_destroy(Vector* v) {
  free(v->ints);
  free(v);
}

void Vector_add(Vector* v, int n) {
  if(v->size == v->limit) {
    v->limit = v->limit * 2 + 10;
    v->ints = realloc(v->ints, v->limit);     
  }

  v->ints[v->size] = n;
  ++v->size;
}

int Vector_get(Vector* v, int index) {
  if(index >= 0 && index < v->size)
    return v->ints[index];

  assert false;
}

Teşekkür ederim Itay. Tavsiyelerinizi takip edeceğim.
Dimi

1
4. sonucunu atmayın malloc.
SS Anne

22

C dilinde nesne yönelimli kod yazma konusunu kapsayan Object-Oriented Programming With ANSI-C başlıklı iyi, ücretsiz bir çevrimiçi kitap var . Google'da "nesne yönelimli C" araması da bir dizi başka ürün ortaya çıkarıyor. örnekler ve kaynaklar.

Projeniz güvenlik açısından kritikse, MISRA-C iyi bir kurallar dizisidir. Çoğunlukla gömülü c için tasarlanmıştır, ancak diğer alanlarda da yararlı olabilir.

Kendimi bir OO kodlayıcı olarak görüyorum ve gömülü-C ile çok iş yapıyorum. Özellikle büyük projeler için verebileceğim en iyi tavsiye, aşırıya kaçmamaktır. ANSI C'nin üstünde eksiksiz bir OO çerçevesi oluşturmak çok cazip olabilir, ancak bunu doğru yapmak için çok fazla zaman ve çaba gerekir. Ne kadar meraklı olursanız, gerçek proje üzerinde çalışmak yerine çerçevenizde hata ayıklamak için o kadar çok zaman harcarsınız . Göreve net bir kafa ve iyi, sağlam bir YAGNI kavrayışı ile yaklaşın . İyi şanslar!


Teşekkür ederim e.James. ANSI C'nin üstünde nesne yönelimli bir çerçeve oluşturmak istemiyorum, ancak özel ve uygun yordamsal programlama tasarım ilkeleri arıyorum. MISRA-C ipucu çok kullanışlıdır, özellikle de aslında gömülü bir proje olduğu için. Ona daha yakından bakacağım.
Dimi

Ah, gömülü C'nin eğlenceleri Değişkenlerinizi fonksiyonunuzun tepesinde (veya herhangi bir { }bloğun üstünde) belirtmeniz gerektiğini unutmayın . Bu beni her zaman bir veya iki kez ısırır:)
James

6

OOP bir teknoloji değil, bir metodolojidir. Bu yüzden ilk tavsiyem, bunu prosedürel programlama olarak düşünmeyi bırakmanız.

Örneğin James'e göre, nesne yönelimli bir dili denemek ve yeniden yaratmak ya da onun yeteneklerine sahip olduğunuzu iddia etmek istemezsiniz. Yine de birkaç basit ilkeye bağlı kalarak tüm doğru şeyleri yapabilirsiniz:

  1. Her şeyi test edin.
  2. Neyin değiştiğini bulun ve onu özetleyin.
  3. Arayüzlere tasarım.
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.