2

現在、Java 用の小さな引数チェック ライブラリを作成しています。チェックは、次のような流暢なインターフェイス方法で記述されます。

Check.that(name).matches("hello .*!").hasLenghtBetween(0, 20);
Check.that(list).isNullOr().hasSize(0);
Check.that(args).named("arguments").isNotEmpty();

これまでのところ、これらのチェックのセマンティクスは、引数が null ではないことも暗黙的にアサートするというものです。null を許可するisNullOr()には、2 番目の例のように修飾子メソッドを使用できます。

次に追加したいのは、次のようなチェック反転のサポートです。

Check.that(name).not().matches("hello .*!");

しかし今では、デフォルトの nullness 処理が奇妙で直感的ではなくなっていると感じています。テストを逆にする正しい方法は、null を許可することです。null を禁止するには、isNotNull()チェックを明示的に追加する必要があります。

Check.that(name).isNotNull().not().matches("hello .*!");

このため、null 性を常に明示的にチェックする必要があるようにセマンティクスを変更することを考えています。私はこれを行う 1 つのプロジェクトを知っています: Bean Validation。ただし、null は無効な引数であることが多いため、これによりおそらくチェックの約 90% が 12 文字長くなるという欠点があります。

では、長い話を簡単に言うと、暗黙の null チェックの賛成意見と反対意見は何ですか? たぶん、これまたは他の方法でそれを行う他のライブラリまたは標準がありますか?

4

2 に答える 2

2

私はAPIをかなりシンプルに保ち、メソッド呼び出しの順序に敏感ではありません-基本的には流暢な ビルダーパターンです。これを行うには、次の変更を行います。

  • ステートフルにする(静的メソッドではなくインスタンスを使用する)
  • 最後のメソッド呼び出しを実際にチェックします

各メソッド呼び出しは、実行される基準を構築し、最後にチェックを実行します。

このような:

new Check().matches("hello .*!").hasLengthBetween(0, 20).check(name);

これにより、インスタンスの再利用も可能になります。これはCheck、ステートレス(static)バージョンでは実行できないことです。

さらに、メソッド呼び出しの順序が重要でない場合は、「論理演算子」メソッドの使用を完全に回避します。これは、悲しみにつながるだけであり、どこで停止しますか。このばかげたシナリオを考えてみましょう。

new Check().matches("hello .*!").hasLengthBetween(0, 20)
    .and().openBracket().isLowerCase().or().containsNumbers().closeBracket();
于 2012-09-23T14:02:09.367 に答える
1

私は甘い妥協点を見つけたと思います。すべてのチェック暗黙のnullチェックを実行します not()、実際のチェックを反転するだけで、nullチェックは反転しません。このように、私は書くことができます

Check.that(message).not().containsAny(badWords);

また、メッセージがnull以外であり、不適切な単語が含まれていないと想定します。これはユースケースの90%以上をキャプチャしていると思います。

そしてもちろん、私はまだ明示的にnullを許可することができます

Check.that(message).isNullOr().not().containsAny(badWords);

2番目の利点は、この設計がnullnessの懸念を残りのチェックから分離することです。これは、おそらくより直感的でもあります。

于 2012-09-24T15:44:37.823 に答える