システムのJava部分の外で列挙型を参照するには、文字列またはintを使用する方が良いですか?


10

私はJavaでの列挙型の使用について私の仕事で議論をしていました。

同僚は、サーバー側で列挙型を使用する場合、必要に応じてそれを参照するために文字列を使用する必要があると主張していました(たとえば、JSからサーバーにデータを送信するとき、またはデータベースに格納するとき)、これははるかに明確であると主張しました開発者にとって、またタイプミスの場合にはすぐに失敗するだろうと主張しました。

これらの場合、列挙型を識別するために常に整数を使用しました。それは不変の識別子であり、大文字と小文字の違いやタイプミスの問題がないためです(開発者が1ではなく2を使用するというミスを犯したとしても、すぐには失敗しません)。

これらの引数について非常に分析的であるので、文字列を使用する方が良いと思いますが、私はそれについて不思議な気持ちになります(まるで良いアプローチではなかったかのように)。

この議論に関して私を導くことができるベストプラクティスはありますか?

編集:可能な場合は常に列挙型自体を使用するため、すべてのJavaコードは列挙型を使用します。「enumへの参照」とは、JavaScriptからサーバーにデータを交換するとき、またはデータベースにデータを格納するときに、enumの値を参照することを意味します


1
あなたにとって「列挙型への参照」とは何ですか?ソースコード内での通常の使用?データベースに保存するためのシリアル化?ユーザードキュメントで使用する式?技術文書で使用する表現?答えはそれらすべてでかなり異なります。
Kilian Foth 14

私は質問を編集し、それがより明確になることを願っています。「enumへの参照」とは、JavaScriptからサーバーにデータを交換するとき、またはデータベースに値を格納または保存するときに値を参照することを意味します
JSBach

JavaScript APIでは、確かに文字列を使用します。DBでは両方に利点があります。一部のデータベースには、列挙型サポートが組み込まれています。
CodesInChaos

回答:


15

良い質問。Javaでの列挙型の使用は、本質的にややカテゴリー的な情報を処理することを主な目的としています。列挙型を使用してカードが持つことができる4種類のスーツを処理する典型的な例。これは、整数を使用することによるパフォーマンス上の利点をすべて提供し、プログラムでも明らかです。

では、Java以外では、なぜ整数を使い続けないのでしょうか。おそらくJavaの外部に列挙型がないのですが、パフォーマンスの目的で整数を使い続けることができないというわけではありませんよね?はい、それは完全に本当ですが、新しい列挙値を追加するとどうなるかを検討してください。最後に追加しない場合、新しい値の後の他のすべての列挙値は1ずつ増加します。変更できないように番号を指定するか、常に最後に追加します。あなたの同僚はいつもそれによって正しいと確信していますか?え?多分?うまくいけば?たぶん、あなたはそれについて100%ではない。少しの間それを覚えておいてください。

上司は、最後の更新後にソフトウェアを使用しているクライアントに混乱があると言います。これで、すべてのエンティティXは、実際にZが割り当てられている場合でも、列挙値Yが割り当てられているように機能します。リポジトリを確認すると、誰かが新しい列挙値を追加し、要求されたガイドラインに従っていませんでした。これで、データベースに4と書かれているという複雑さが追加されました。更新前に挿入された実際 4であるレコードを除いて、実際には3である必要があります。とにかく4に関係する列挙値何ですか?Yさんじゃないですか?思い出せない。確認するには、プログラムをチェックする必要があります。簡単に言えば、それは混乱です。

代わりに、データベースが「HEARTS」、「DIAMONDS」、「SPADES」、「CLUBS」を書き込んだ場合、スペースの点でほとんど損失せず、多くを獲得しています。パフォーマンスのマイナーヒットについて話しているのは事実ですが、違いをもたらすために頻繁にデータベースにアクセスするべきではありません。スペースに関しては、システム管理者に任せてください(問題ではありません)。

変更が簡単な単純なプログラムを作成した場合、長期的には自分自身を支持したことになります。信頼してください。それのこの面は私の謙虚な意見で違いはありません。


2
良い点、しかし、あなたは、誰かが(列挙型エンティティの1つの名前に変更することを決定した場合について忘れているHEARTSHeart、再びあなたの例ではか何かを)と、突然すべてブレイク。
スコットウィットロック

1
@ScottWhitlock完全に名前を変更することを決定することはできますが、それを考慮に入れる必要はありません。彼らは誤ってデータベースを削除し、プロジェクトも削除する可能性がありますが、ここでは起こり得るすべてのインシデントを説明することはできません。
Neil

5
@ニール-本当ですが、オッズをここでプレイしようとしています。Java列挙型については詳しくありませんが、C#では、値がプログラムの外部(データベースなど)で意味を持つ必要がある場合(たとえば、Hearts = 1、Diamonds = 2など)、列挙型の値を明示的に設定します。 。これは列挙型を使用するデフォルトの方法ではないため、後でエディターを一時停止する必要があります。加えて、これらがどこで使用されているかを示すコメントは便利です。
スコットホイットロック2014

1
@ScottWhitlockそれは間違いなくそのような問題を回避するためにそれについて行くより良い方法です。仮にそうしたとしても、データベースにはまだ1、2、3、4が表示されているか、ファイルにシリアル化されています。保守の観点からは、スライスする方法は理想的ではありません。
Neil、

2
追加する場合、列挙型が文字列としてシリアル化され、誰かが列挙型の名前を変更すると、逆シリアル化中にエラーが解析中に発生します。列挙型がintで、誰かが定義を変更した場合、エラーは処理中にさらに下になり、診断が難しくなります。CC @ScottWhitlock。
Endy Tjahjono

1

私はニールの答えに同意しますが、追加だけです:

Javaの列挙型はオブジェクトなので、フィールドとメソッドを持つことができます。したがって、各列挙型に手動で指定された値を与えることができ、それを外部の作業で参照する場合は、代わりにその値を使用します。

列挙インスタンスの名前の追加/削除/並べ替えと変更の両方に耐えます。しかし、多くのツールで利用可能なautomagicを使用する代わりに、列挙型フィールドのシリアライゼーション/デシリアライゼーションロジックを記述する必要があります。(それは簡単ですが、その追加作業です)。

そして、これらの値を手動で一意に保つ必要があります(ただし、Cスタイルの列挙型では同じです)。それをテストするテストを作成できます。


はい、このパスをたどりましたが、hibernateを使用しており、データベースとの間の値を解析できるようにいくつかの追加コードを追加する必要がありました。列挙型名を使用します。
JSBach 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.