読者です 読者をやめる 読者になる 読者になる

わたしが出会った変なコード

最近は他の人が途中まで書いたプログラムを修正したり、完成させたり、といったことばかりやってます。で、まあやはり「これは・・ムムム」というコードに出会うこともよくあります。こりゃだめだというコードから、別に悪くはないんだけど、もうすこしこうしたほうがいいのにというコードまで色々です。VBしか知らない人が書いたJavaのコード、ベトナム人が書いたコード、中国人が書いたコード、コード、コード・・・。と言う感じで、いままでに私が出会ったコードを今後書き綴っていくことにしよう。ちなみ以下に書く内容は、どれも相当に基礎的で低レベルな話です。あしからず。

定数は全部グローバル

プログラムで使用するファイルやフォルダの名前、UIに表示する文字列、ログメッセージ、コネクションタイムアウトの秒数などは、グローバルな定数として宣言することが多々あります。Javaでいえば、public static final Stringな変数、VBで言えばPublic constな変数ですかね。で、そういう定数をまとめたクラスやモジュールを作ることもわりとあります。

public class HogeConst{
  public static final String FILE_NAME_AAA = "..."
  public static final String FILE_NAME_BBB = "..."
  public static final int CONNECTION_TIME_OUT = "..."
  public static final String LOG_MSG_001 = "..."
  ...

上のような感じ。とりあえずここでは「定数クラス」と呼ぶことにする。で、この定数クラスにどんな定数を定義するか、ってことが問題になるんですが、今日出会った定数クラスは以下のような感じ。

  1. あるクラスでしか使用しない文字列を、グローバル定数として定義している
  2. ログメッセージやUI文字列は全てグローバル定数
  3. 定数名が「LM001」のように、通番で構成されている(文字としての意味はない)
  4. 定数クラスはひとつだけ。ひとつの定数クラスにプログラム中の全ての定数が詰め込まれている

1.については、あるクラスでしか使用しないような定数はグローバル定数として定義すべきではない。まあ、ログメッセージとかUIのメッセージとかは別だけど。たとえばExcelのVBAだと、ワークシート中のあるセルを特定するための行番号、列番号なんていう具体的な情報はグローバル化する必要はまったくなく、ワークシートごとに値の読み書きを行う管理クラスを用意しておき、そのクラスのPrivateな定数値として行番号、列番号を持てばよい。他のクラスがそのワークシートの値を参照したい場合は、管理クラスに対し値を要求するようにする。
2.たしかに国際化・局所化という観点から見れば、UIの文字列などは一箇所にまとめて定義しておくというのはセオリーなんだけれども。でも、今作っているアプリ、ホントに国際化対応する可能性はあるのかな?または、UI文字列ってそんなに頻繁に変わるかな?仮に変わるとしてもIDEの機能使えば簡単に変更できないかな?個人的な意見としては、初期の段階では国際化に関しては気にせずガシガシ作って、もし仮に国際化対応の必要がでてきたら、IDEの力を借りるなりして一括で文字列外だしにする、っていう程度でいいんでないかな、と思う。文字列の外だし作業をその都度やるのって、結構面倒だし。
3.については、たしかに大規模な業務アプリとかだと、ログメッセージにあらかじめ通番でIDを振っておいて、それを変数名に使う、ということはよくある。しかし規模が小さいものであれば、普通に「UI_MSG_HELLO_DIALOG_TITILE」みたいに意味がぱっと見でわかるものにしたほうが良い。また規模に関係なく「LM001」というまったく意味がわからないIDよりも、せめて「LOG_MSG_001」のように「キーワード」+「通番」くらいにしておいてほしい。まー、変数名にはわかりやすい名前を使おうぜという話。
4.については一言、別けろよ、と。

以上、かなり個人の趣味的な話でした。そんなに変、っていうほどではないんだけど、ついついツッこんでしまうのは何故だろうか。