多くの定数を持つアプリケーションに取り組んでいます。最後のコードレビューで、定数があまりにも散在しており、すべてを単一の「マスター」定数ファイルに編成する必要があることがわかりました。意見の相違は、それらをどのように整理するかについてです。大多数は定数名を使用することで十分であると感じていますが、これは次のようなコードになります:
public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";
このタイプの命名規則は扱いにくいと思います。ネストされたパブリッククラスを使用する方が簡単かもしれないと思いました。
public class IntegrationSystemConstants
{
public class CreditCard
{
public static final String UI_EXPIRY_MONTH = "3524";
public static final String UI_ACCOUNT_ID = "3524";
...
}
public class BankAccount
{
public static final String UI_ACCOUNT_ID = "9987";
...
}
}
「あまりにも複雑」だったため、このアイデアはあまり受け入れられませんでした(なぜこれについてはあまり複雑ではありません)。これにより、関連する定数のグループ間の分割が改善され、オートコンプリートにより、これらも簡単に見つけられるようになると思います。私はこれが行われるのを見たことがないので、これが受け入れられた慣習なのか、それを行わないほうがよい理由があるのか疑問に思っています。
2つの提案のどちらにも同意しません。
定数は適切なクラス、すべて定数クラスではないである必要があります2つの形式のいずれかが提案されます。
定数のみのクラス/インターフェイスであってはなりません。
クラスCreditCard
(内部クラスではない)が存在する必要があります。このクラス/インターフェイスには、クレジットカードに関連するメソッドと、定数UI_EXPIRY_MONTH
およびUI_ACCOUNT_ID
があります。
クラス/インターフェースBankAccount
が存在する必要があります(内部クラスではありません)。このクラス/インターフェースには、銀行口座に関連するメソッドと定数UI_ACCOUNT_ID
があります。
たとえば、Java APIでは、すべてのクラス/インターフェイスに定数があります。それらは、内部クラスにグループ化されているかどうかに関係なく、何百もの定数を持つ定数クラス/インターフェイスにはありません。
たとえば、結果セットに関連するこれらの定数は、インターフェイスResultSet
にあります。
static int CLOSE_CURSORS_AT_COMMIT
static int CONCUR_READ_ONLY
static int CONCUR_UPDATABLE
static int FETCH_FORWARD
static int FETCH_REVERSE
static int FETCH_UNKNOWN
static int HOLD_CURSORS_OVER_COMMIT
static int TYPE_FORWARD_ONLY
static int TYPE_SCROLL_INSENSITIVE
static int TYPE_SCROLL_SENSITIVE
このインターフェイスには結果セットに関連するメソッドシグネチャがあり、実装クラスはその動作を実装します。それらは単なる定数保有者ではありません。
UIアクションに関連するこれらの定数は、インターフェースjavax.swing.Action
にあります。
static String ACCELERATOR_KEY
static String ACTION_COMMAND_KEY
static String DEFAULT
static String LONG_DESCRIPTION
static String MNEMONIC_KEY
static String NAME
static String SHORT_DESCRIPTION
static String SMALL_ICON
実装クラスには、UIアクションに関連する動作があり、単なる定数ホルダーではありません。
メソッドのない「定数」インターフェース(SwingConstants
)は少なくとも1つは知っていますが、数百の定数はなく、ほんの数個しかありません。これらはすべて、UI要素の方向と位置に関連しています。
static int BOTTOM
static int CENTER
static int EAST
static int HORIZONTAL
static int LEADING
static int LEFT
static int NEXT
static int NORTH
static int NORTH_EAST
static int NORTH_WEST
static int PREVIOUS
static int RIGHT
static int SOUTH
static int SOUTH_EAST
static int SOUTH_WEST
static int TOP
static int TRAILING
static int VERTICAL
static int WEST
クラスのみの定数は良くないと思いますOOデザイン。
定数が散在しすぎて、すべてを単一の「マスター」定数ファイルに編成する必要があることがわかりました。
これは、定数が「見つけるのが難しい」という問題の100%間違った解決策です。定数、列挙型、インターフェイスなどの技術的な基準で物事をグループ化することは、基本的なエラーです(残念ながら、プログラマーが一般的に犯しすぎます)。
レイヤーアーキテクチャを除いて、物はドメインによってグループ化される必要があります、そして定数は非常に低レベルの要素であるため、さらにそうです。定数は、それらをAPIの一部として使用するクラスまたはインターフェースの一部である必要があります。彼らが住むための自然な場所が見つからない場合は、API設計をクリーンアップする必要があります。
さらに、-単一の巨大な定数ファイルはJavaの開発速度を低下させます定数はコンパイル時にそれらを使用するクラスにインライン化されるため、変更を加えると、それらすべてのファイルとそれらに依存するすべてのファイルが強制的に再コンパイルされます。どこでも使用される定数を持つ1つのファイルがある場合、インクリメンタルコンパイルのメリットはほとんど失われます。Eclipseが15分間ロックして、そのファイルに変更が加えられるたびにプロジェクト全体が再コンパイルされるのを観察してください。また、そのファイルにはどこでも使用されるすべての定数が含まれているため、頻繁に変更することになります。はい、私は個人的な経験から話しています。
あなたが正しいです。あなたの提案により、プログラマはimport static Constants.BankAccount.*
そして、 'BANKACCOUNT_'の無数の繰り返しを排除します。連結は、実際のスコープの代替としては不十分です。とは言っても、チームカルチャーを変えてほしいという希望はあまりありません。彼らは適切な実践の概念を持っており、彼らが間違っていると言っている100人の専門家を彼らに見せても変わらないでしょう。
また、なぜ「Constants」ファイルが1つしか存在しないのかと思います。これらの定数が何らかの形で関連し、非常に安定していない限り、これは非常に悪い習慣です。より一般的には、常に変化し、すべてに依存する一種のキッチンシンククラスになります。
どちらのアプローチも機能しますが、それが結局のところ重要なことです。
とは言っても、あなたのアプローチはパターンと見なすのに十分一般的であり、より正確には 定数インターフェイス アンチパターンよりも十分に優れています。何が複雑なのかはわかりませんが、それはあなたがチームと持つべき議論です。
定数の長いリストでの課題の1つは、使用する「正しい」定数を見つけることです。常に、誰かが所属するグループに定数を追加するのではなく、行の最後に定数を追加します。
これは、チームと話し合う別のポイントを提示します-定数の名前による事実上の分類はすでにあります。ですから、彼らにとって、それは現在の状態からあなたが提案しているものへの大きなシフトであってはなりません。オートコンプリートを使用すると、一定のルックアップがさらに簡単になります。
どちらかと言えば、あなたの提案は、それが特定の状況に適合するかもしれないとしても、「間違った」定数の使用を思いとどまらせるのに役立ちます。定数を代表的なクラスでラップすることにより、開発者が定数を使用する必要があるかどうかを検討するよう促します。たとえば、一般的な使用法のためにCreditCard.SomeConstant
をプルする場合、そのような状況のためにGeneral.SomeConstant
がないのはなぜかと疑問に思うはずです。
私は定数のモンスター量でプロジェクトに取り組んできました、そしてあなたが提案している方法を持っていることを望みました。クリーンで、より直接的で、不注意な使用を避けるのに役立ちます。
特にC#でこれをときどき行います。特に、既知の固定されたXML構造または同様にネストされ、文字列が重いものに対してプログラム/パースする必要がある場合は、たとえばカスタム構成ブロックパーサーを使用します。
XMLの階層構造と一致するネストされたクラス構造を構築します。const文字列の「ElementName」プロパティと各属性(存在する場合)に対応する同様のプロパティを含む要素に対応するクラス名が含まれます。
対応するXmlに対して非常に簡単にプログラミングできます。