まずはリファクタリングの基本の「定数化」です。
これは当たり前っちゃ当たり前ですよね。
以下のようなソースが合った場合は、リファクタリングのチャンスとなります。
public static void main(String[] args) { //入力値 String inputName="test"; if(inputName.length() > 30){ } }
1 |
こんな感じで、数字でべた書きで「30」と書いてある部分を定数化して書き直しましょう。 |
//定数化 public static final int MAX_LENGTH = 30; public static void main(String[] args) { //入力値 String inputName="test"; if(inputName.length() > MAX_LENGTH){ } }
これも、当たり前ですが、定数には「public static final」とつけましょう。
publicとすることで、他のクラスからも、呼び出すことができるようになりますし、staticとして静的にすることで、クラスをインスタンス化しなくても呼び出すことができます。
また、finalは「不変」という意味になります。これを指定しておけば、誤って代入されるということがなくなりますね。
定数化の3つのメリット
定数化のメリットとしては下記です。
ソースコードが理解しやすくなる。
単に数字で「30」と書かれているよりは、「MAX_LENGTH」と書かれてある方が人間にとって明らかに理解しやすいですよね。
ソースコードに無駄に コメントを書かなくてよくなる。
「理解しやすくなる」に付随する理由ですが、「MAX_LENGTH」と書かれているだけで、「最大の長さのチェックをしているんだな」とソースを読んでいる人が容易に想像ができますので、「最大長の入力チェック」などとコメントをする必要がなくなります。
置換(置き換え)がしやすい。
これが最大のメリットといえるでしょう。
一箇所ならまだいいですが、ソースコードのあちこちで、「30」という数字が出てきたら置き換えが非常に大変です。
単純に、一括置換だと、MAX_LENGTH以外の意味の「定数」とか「数字」があった場合に、誤って置き換えが行われてしまう可能性があります。
定数の命名規則
でも、命名規則ってどうなのって感じですよね?意外と普通にコーディングしていて命名で時間を食ってしまいがちだと思いますので、よくあるコーディング規約をまとめておきます。
- 全て大文字にする。
- 複合文字の場合は区切りをアンダースコア "_" で結合する。(スネーク記法というらしいです。)
例:FILE_PATH、DATABASE_NAME等
また、よくある定数名の英単語は下記でまとめていますので、よろしければご覧下さい。
列挙型を使う。
定数が以下のように複数まとまってある場合は、単純なデータ型ではなく、「列挙型」を使いましょう。
以下のようなコードの場合はどうでしょうか。
同じ画面から複数データが入力されていると仮定したソースです。
public static void main(String[] args) { //入力画面:名前 String inputName="太郎"; //入力画面:年齢 String inputAge="23"; //入力画面:住所 String inputAddress="東京都練馬区"; //名前:入力チェック if(inputName.length() > 30){ } //年齢:入力チェック if(inputAge.length() > 3){ } //住所:入力チェック if(inputAddress.length() > 100){ } }
前回と同じように、「public static final」で固定値として外出ししてもよいかもしれませんね。ただ、それだと固定値が増えすぎた場合に、「データとしてのまとまり」を把握しずらくなってしまいます。
そこで、今回のような「同じ画面からの入力というデータのまとまり」が明確な場合は、列挙型を使うようにしましょう。
列挙型の使い方
上記の例の「最大値のまとまり」を列挙型として宣言するのであれば、下記のような列挙型を宣言することができます。「enum(イーナム型と読みます。エナムではありません 笑)」といいます。
public enum InputMaxLength { NAME(30), AGE(3), ADDRESS(100); private final int maxLength; private InputMaxLength(final int maxLength) { this.maxLength = maxLength; } public int getMaxLength() { return this.maxLength; } }
実装としては下記になります。
public enum InputMaxLength { NAME(30), AGE(3), ADDRESS(100); private final int maxLength; private InputMaxLength(final int maxLength) { this.maxLength = maxLength; } public int getMaxLength() { return this.maxLength; } } public static void main(String[] args) { //入力画面:名前 String inputName="太郎"; //入力画面:年齢 String inputAge="23"; //入力画面:住所 String inputAddress="東京都練馬区"; //名前:入力チェック if(inputName.length() > InputMaxLength.NAME.getMaxLength()){ } //年齢:入力チェック if(inputAge.length() > InputMaxLength.AGE.getMaxLength()){ } //住所:入力チェック if(inputAddress.length() > InputMaxLength.ADDRESS.getMaxLength()){ } }
単純に、「public static final」のような固定値を使った書き方よりも、すっきりしてプロっぽくなりましたよね。
注意点としては、列挙型はカプセル化されていて、フィールドに直アクセスができませんので、アクセスする場合は、必ずgettterメソッド経由にしましょう。
また、「固定値のまとまり」を見つけたらどんどん「列挙型」にリファクタリングしていくようにしましょう。
ただ、例えば2個しか固定値のまとまりがない場合でも列挙型を使うというのは、記述コード量の方が多くなってしまうので、3個以上のまとまりがある場合のみ使いましょう。
この記事へのコメントはありません。