C(または一般的な手続き型プログラミング)の設計原則、ベストプラクティス、および設計パターン?[閉まっている]


91

Cプロジェクトの設計中に従うことができる既知の設計原則、ベストプラクティス、および設計パターンはありますか?それとも、手続き型(命令型)プログラミング全般に役立つ設計原則ですか?

(私は「オブジェクト指向世代」の子であり、初めて大規模なCプロジェクトを設計する必要があります)


1
この質問へのanwsersに興味がすることができる。stackoverflow.com/questions/661307/...
mouviciel

7
質問を投稿する前に、インターネットと大学図書館の調査を行いましたが、Cのソフトウェア設計に関する本に圧倒されませんでした。お気に入り(一般的なCの本ではなく、意味のある変数などのコーディング規約については話していない)をお聞きします名前ですが、より高い抽象、ソフトウェアアーキテクチャレベルについてです)。さらに、あなたの「他の人に頼る」という非難には同意しません。あなたは、各プログラマーがベストプラクティスと優れたデザインパターンについて自分で調べる必要があるということですか これは確かに、他人の経験をどのように使用する必要があるかという質問です。
Dimi

2
申し訳ありません、ディミ、それは特にあなたのことではありませんでした。このことは、他の方法と同じように口頭の伝統によって受け継がれていました。公的な「パターン」の名目上のセットはなく、ジョナソンの答えはあなたが本で見つけるものでしたが、誰もが情報の隠蔽について知っていました。口承の伝統は失われているようで、多くの若いプログラマーはOOPがカプセル化と分離を発明したと考えています。このコミュニティは自分の歴史について、私が見たいと思っているよりも意識が低いようです。したがって、私は不機嫌そうな老人の領土にいることを認めます。
dmckee ---元モデレーターの子猫2010

1
フィールドで私の足を見つけるだけなので、私はあなたの回顧的見解を共有することはできませんが、あなたの提案を受け入れます。経験豊富な人の見解を読むために、常に非常に価値のある自分をより明確に表現していただきありがとうございます。本当にありがとうございました。
Dimi

SEI CERT Cコーディング標準は、一連のルールと一般的なグッドプラクティス、および使用を避けるべきものを提供します。
Rami

回答:


65

情報の隠蔽-Parnas(Software Fundamentals)によって支持されています。

ヘッダーと可視性の注意深い管理:

  • 外部の世界から隠すことができるソースファイル内のすべてのものでなければなりません。文書化された外部インターフェースのみを公開する必要があります。
  • 公開されるものはすべてヘッダーで宣言されます。
  • そのヘッダーは、機能が必要な場合(および定義されている場合)に使用されます。
  • ヘッダーは自己完結型です-必要なときに使用し、「他のヘッダーにも含める必要があるもの」について心配する必要はありません。ヘッダーは、ヘッダーを作成するために必要なものをすべて含めることで機能するためです。作業。
  • ヘッダーは自己保護されているため、複数回インクルードされていても問題ありません。

    #ifndef HEADER_H_INCLUDED
    #define HEADER_H_INCLUDED
    ...rest of header contents, including other #include lines if necessary
    #endif /* HEADER_H_INCLUDED */
    
  • 「オブジェクト」(通常は構造)を処理する関数のセットを設計し、それを使用しているコードで構造の内部をあちこち動かすのではなく、それらの関数を使用します。それを自主的なカプセル化と考えてください。


良い点、ありがとう、ジョナサン。抽象データ型は、使用法と実装(既知の外部インターフェイスと未知の内部実装)を明確に分離して情報を隠す別の良い例です。
Dimi

23

私の3つのアドバイス:

  • 単体テストを記述します。彼らはあなたがあなたが進むにつれてあなたの問題に適したデザインに焦点を合わせるのを助けます。事前に瞑想された思考に(単独で)依存するよりもはるかに優れています。
  • メモリーリークディテクターをインストールし(あらゆる種類のライブラリがそこにあります)、インストールして1日目から実行します。プログラム/テストが終了したらすぐに、このライブラリにすべてのリークを出力させます。これにより、リークを導入するとすぐにキャッチできるため、修正がはるかに簡単になります。
  • CでOOPコードを記述します。それほど難しくありません。メソッドのオーバーライドをエミュレートすることは可能ですが、単純なオブジェクトのエミュレーションから始めることをお勧めします。この単純なメカニズムでさえ、あなたに大きなマイレージを与えることができます。

次に例を示します。

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

ありがとう、イタイ。あなたのアドバイスに従います。
Dimi

1
4.の結果をキャストしないでくださいmalloc
SSアン

22

良い、無料、オンラインブック、というタイトルがあるANSI-Cでオブジェクト指向プログラミング C. Aにオブジェクト指向のコードを書くのトピックをカバーし、検索グーグル、「オブジェクト指向C」のためにも、他の財の数を生成するには、例とリソース。

プロジェクトが安全性を重視する場合は、MISRA-Cが適切なルールセットです。これは主に組み込みcを対象としていますが、他の領域でも役立つ場合があります。

私はオブジェクト指向のコーダーであり、組み込みCで多くの作業を行っています。特に大規模なプロジェクトの場合、私ができる最善のアドバイスは、やりすぎないことです。ANSI Cの上に完全なOOフレームワークを作成することは非常に魅力的ですが、それを正しく行うにはかなりの時間と労力が必要です。手の込んだほうが、実際のプロジェクトに取り組む代わりにフレームワークのデバッグに費やす時間が増えます。明確な頭とYAGNIをしっかりと把握して、作業に取り組みます。がんばって!


ありがとう、e.James。ANSI Cの上にオブジェクト指向のフレームワークを作成したくないのですが、特別で適切な手続き型プログラミングの設計原則を探しています。MISRA-Cヒントは、特に実際に組み込みプロジェクトであるため、非常に役立ちます。それを詳しく見ていきます。
Dimi

ああ、組み込みCの喜びです。変数を関数の上部(または{ }ブロックの上部)で宣言する必要があることを忘れないでください。その一つは、常に一度か二度私を噛む:)
e.James

7

OOPは技術ではなく方法論です。だから私の最初のアドバイスは、それを手続き型プログラミングと考えるのをやめることです。

e.Jamesの要点として、オブジェクト指向言語を再作成したり、その機能を持っているように見せたりしたくはありません。いくつかの単純な原則に固執することで、すべての正しいことを行うことができます。

  1. すべてを試運転します。
  2. 変化するものを見つけ、それをカプセル化します。
  3. インターフェイスに合わせて設計します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.