2

正しく使いやすく、間違って使いにくいAPIを作成しようとしています。

"bool MyObject_SetLocalDateTime(MyObject *pMyObject, params...)"クライアントが日付と時刻を次のYYYY MM DD HH MM SS形式で設定できる関数があるとします。

MyObject *pMyObject = MyObject_Create();
...
MyObject_SetLocalDateTime(pMyObject, params...);
...
MyObject_Destroy(&pMyObject);

関数の良いインターフェースは何でしょうか?ANSI C(C ++ではない)でインターフェイスを正しく使いやすく、正しく使いにくいようにするためのヒントをいただければ幸いです。

4

4 に答える 4

2

私は最初に「正しく」何であるかを決定すると言います。真剣に。

入力を最も正確にしますか?関数が失敗しないようにしますか?入力できるものの値を制限しますか?作成するものの要件を検討することをお勧めします。

この関数が呼び出された時点で、データはどの形式になっていますか?ユーザーが「YYYYMMDDHH MM SS」と入力した文字列に含まれている可能性があります。その場合は、1つの文字列を取得して、自分で値を解析するのが最も賢明です。もちろん、それはあなたの関数内でもっと多くの仕事です。

また、自分で関数を作成している場合は、何が期待されるかをおそらく知っているので、入力値とテストについてより寛大になる可能性があります。何十万人もの人々がそれらのAPIを使用するオペレーティングシステム用の関数を作成している場合は、許可されているものをより明確にし、関数内でそれらをテストする必要があります。

状況に最も「正しい」ものに応じて、参照する単純な関数でさえ指定する方法がいくつかあります。

bool MyObject_SetLocalDateTime(pMyObject、int YYYY、unsigned int MM、unsigned int DD、int HH、int MM、int SS); //戻り値は成功または失敗を示します。

しかし、消費者がMMにゼロを渡した場合はどうなるでしょうか。消費者が13を通過した場合はどうなりますか?月を参照する数値(jan-dec)には、base-0(通常はCが使用するもの)または通常の1-12を使用しますか?これは、人間の月の観点からはより理にかなっていますが、 Cプログラマーの考え方は?

日付と時刻のようなものについては、Cライブラリにこれの定義があります。これにより簡単になります。また、Cライブラリはすでにそのように実行しているため、関数を使用している他のユーザーにとってはより自然に見えるかもしれません。

また、「誤って使用するのが難しい」とはどういう意味かを定義する必要があります。繰り返しますが、私は真剣です。たぶん、月(および日)の列挙型を作成し、intの代わりにそれを渡したいと思うでしょう。これにより、コンパイラによるAPIの追加の型チェックが可能になりますが、APIの巧妙なコンシューマーが別の値にキャストする可能性があるため、有効な入力のテストをスキップできるとは思わないでください。

関数内では、渡された形式に関係なく、入力値を検証して、それらが有効であることを確認し、2月に30日を許可せず、2月に29日を許可することを確認します。たった4年ごと。日付と時刻には多くの隠れた複雑さがあり、OSですでに開発されているルーチンまたはランタイムライブラリに依存するのが賢明です。

于 2012-08-30T22:07:22.460 に答える
1

なぜあなたは単に使用しないのですかtime_t、そして/またはstruct tm

次のようなもので問題ありません。

time_t my_local_time ;

MyObject_SetLocalDateTime(pMyObject, my_local_time ) ;

また

struct tm my_local_time ;

MyObject_SetLocalDateTime(pMyObject, my_local_time ) ;
于 2012-08-30T21:57:09.230 に答える
0

名前にヒントを与えることができます:MyObject_SetLocalDateTime_YMDHMS

于 2012-08-30T21:59:07.420 に答える
0

ではC、次のルールに従います。

  1. リターンタイプとして適切なエラーコードを返します。
  2. struct const* struct_paramそのAPI内でポインター値を変更できないように、非常に可変の入出力パラメーターを使用してください。

  3. 不変の入力パラメータに使用struct const * const structParamして、そのAPI内でポインタ値と内容を変更できないようにします。

C ++では、ポインターの代わりに参照を使用します。つまり、C ++は参照による受け渡しを明示的に提供するため、ポインターの値による受け渡しを減らすことができます。

于 2012-08-30T22:07:15.947 に答える