SE業務中で、こんな風に書いたら読みやすい!と発見したことをまとめていきます。
あくまで一個人の意見ですので、良いと思ったらご自身のポリシーに採用してみてください。
リーダブルコードが未読だったら、こんな記事読んでないで、まずそっちを買いましょう笑
https://job-draft.jp/articles/434
1.条件分岐
1.1 if
左辺に変数(値が変わる)、右辺に定数(値が変わらない)
int score = 80;
// 獲得点数が60点以上だったら、合格 → 直感的に理解できる
if (score >= 60) {
System.out.println("合格");
}
// 60以上の点数を獲得したら、合格 → 同じ意味だが、やや直感的でない
if (60 <= score){
System.out.println("合格");
}
参考:「リーダブルコード」を読む (第7章「制御フローを読みやすくする」
マジックナンバーや文字リテラルで、明らかに定数だとミスは起こりにくいが、
両方とも変数名だとうっかり左右を間違えるので気をつける。
int[] array = { 1, 2, 3, 4, 5 };
int search = 3;
for (int val : array) {
// 好みでない書き方(左辺に固定値)
if( search == val ){ // 右辺に固定値が来る方(val == search)が理解しやすい
break;
}
}
定数を左辺に書くの(ヨーダ記法)は、NullPointerExceptionを回避する意味もあるので、
メリット・デメリットを考慮するのが大事。
参考:【Java】Stringのequalsで定数を左側にする理由
複雑になるようなら、説明変数を用意する
// ありがちな書き方
if( !("認証アクション".equals(action)
&& ("ログイン画面を開く".equals(command)
|| "ログインを実行中".equals(command)))) { // 最後の4重閉じかっこなんて、誰が読みたいの
hogehoge();
}
// 説明変数を用意するとロジックを理解しやすくなる。()の数も減る。
boolean loginAction = action .equals("認証アクション");
boolean loginCommand = command.equals("ログイン画面を開く")
|| command.equals("ログインを実行中"); // ヨーダ記法も解消。ただし、ぬるぽ考慮は必要。
// ログインに関するページ以外を表示しようとした場合
if ( !( loginAction && loginCommand ) ) {
hogehoge();
}
1.2 switch文
// よくある記法1(インデントを2段にする)
switch (intVal) {
case 1:
// ifで書いたときと比べて、インデントが1段余計に深くなってしまう
foo();
break;
default:
break;
}
// よくある記法2(case, default節の始まりでインデントしない)
switch (intVal) {
// case, default節が、なんとなく詰まって見える
case 1:
foo();
break;
default:
break;
}
参考:Qiita - 皆さん、なんでswitch文のcaseをインデントするんですか?
オススメしたい記法
switch (intVal) {
case 1: // case, default節のときだけはスペース2つでインデントするのはどうだろう
foo();
break;
default:
break;
}
余談
switch禁止!という過激な意見もありますが、自分はむしろ使えるときは積極的に使います。
ifでも書けるのにわざわざswitch文で書く= switch文が適用できるくらい簡単な分岐だから、
気負わず読んでね、というメッセージを込めています。
1.3 三項演算子
読みやすい方を採用する。FizzBuzz問題、どちらが見やすい?
for(int i = 1; i <= 100; i++){
String str = "";
if(i % 3 == 0){
str += "Fizz";
}
if(i % 5 == 0){
str += "Buzz";
}
if(str.equals("")){
str = i.toString();
}
System.out.println(str);
}
自分はこれくらい単純なプログラムなら、三項演算子使う派です。
でも可読性でいうとif使った方がいいかも。
for(int i = 1; i <= 100; i++){
// 表示する文字列を組み立てる
// 3の倍数ならFizz、5の倍数ならBuzz、15の倍数ならFizzBuzz
String str = (i % 3 == 0 ? "Fizz": "")
+ (i % 5 == 0 ? "Buzz": "");
// それ以外の数字はそのまま表示
System.out.println(str.equals("") ? i : str);
}
参考:「リーダブルコード」を読む (第7章「制御フローを読みやすくする」7.3 参考演算子
2.垂直インデント
終わらないテーマですが、自分はする派です。
https://softantenna.com/wp/software/vertically-align-my-code/
// 「=」の位置で揃えない
int robert_age = 32; // ロバート
int anna_age = 25; // アンナ
// 「=」と//」の位置で縦を揃える
int robert_age = 32; // ロバート
int anna_age = 25; // アンナ
// だって長い名前の変数が増えたら修正が大変じゃん( ← わかる)
int Aristoteles_age = 62; // アリストテレス
プロトタイプで作成中のプログラムにまで適用するのはコストが割高という気もします。笑
垂直インデント読みやすくてええやん!派の同志は、
手前味噌で恐縮ですが、拙作のサポートツールの利用も検討ください。
(この宣伝のためにQiita書いてるまである笑)
http://www.vector.co.jp/soft/winnt/prog/se523105.html
2.1 SQL
-- 予約語は大文字かつ右揃え
-- ↓ ここに必ず半角スペースが来る。右辺(予約語)と左辺(値)の区切りをわかりやすくする。
SELECT Id
, Name -- SELECT項目の改行についてはどちらでも。読みやすければOK。
, CorporateStatus
--, Country -- コメントアウトもやりやすい
FROM Account
WHERE Name = 'AAA株式会社'
AND ( CorporateStatus = '法人'
OR Country = '日本'
) -- WHERE句にかっこが必要なときの記述は難しいが、自分はこんな感じで書いてる
ORDER BY Id
--GROUP BY Id
LIMIT 1
; --セミコロンだけの行で、SQLの終わりを分かりやすくしたい。
ここまで厳密にインデントする必要がないシンプルなSQLもありますし、そのときは多少崩して書いてもOKかと思います。
よくある記法
SELECT -- 否定はしませんが、SELET, FROMに2行も使う必要ある?って思います。
*
FROM
tab1
WHERE
col1='01' --ここの条件の開始位置が揃っていないのも気になる
AND col2 ='AAAAA'
AND col3 =10000;
副問合せやCASE句などもありますが、経験が少ないので割愛させてください。てへぺろ
2.2 カンマの位置
Account acc = new Account(
Name = 'AAA株式会社'
, CorporateStatus = '法人'
//, Country = '日本' // 区切り文字が文頭にあると、コメントアウトもやりやすい
);
よくある記法
Account acc = new Account(
Name = 'AAA株式会社',
CorporateStatus = '法人'//, ← ここもコメントアウトしないとなのがイヤ
//Country = '日本'
);
以上です。Happy Coding!