何のためにコードを書くの?
ソースコードは動かすために書くんじゃないよ。
人に読んでもらう為に書くんだよ。
- 今後入ってくるエンジニアへ
- 1年後、そのシステムのメンテナンスをする自分にむけて
汚いコードとは?
見た目が汚い
読む速度が落ちる
- ネストしすぎ
- なんかぎゅっとしてる(スペース・改行全然空いてないとか)
- 絵として汚い
何をしてるのかわからない
理解する速度が落ちる
- 名前以上の事を行う関数 (getXXX()がDBに書き込みとか)
- 読み手の記憶力に頼る
- 関数が長い
- 変数多い
- 変数名の使い回し
- 名前が適当(クラス・メソッド・変数)
コメントが嘘
間違った理解をする
実例
その1: 見た目が汚い
ダメなコード
function main() {
$endValue=30;
for ($i=1;$i<$endValue+1;$i++){
if($i%15==0){echo 'FizzBuzz';}
elseif($i%5==0){echo 'Buzz';}
elseif($i%3==0){echo 'Fiz';}
else{echo $i;}
echo '<br>';
}}
システムリニューアル案件の既存コードの調査とかでよく見る。
そもそも読む気にならない。
良いコード
function main() {
$endValue = 30;
for ($i = 1; $i <= $endValue; $i++) {
echo getAnswer($i) . '<br>';
}
}
function getAnswer($value) {
switch (true) {
case isFizzBuzz($value): return 'FizzBuzz';
case isFizz($value): return 'Fiz';
case isBuzz($value): return 'Buzz';
default: return $value;
}
}
function isFizzBuzz($value) { return $value % 15 == 0; }
function isFizz($value) { return $value % 3 == 0; }
function isBuzz($value) { return $value % 5 == 0; }
- インデント、適切な改行・スペースは当たり前。
- 処理を関数化するほど情報量は増えていく。
- 処理の粒度が大きい方から書くと読みやすい。
- 上から下へ読める
- 不要な定義を読む必要がない
- if文などの条件には
式
じゃなく文
が書いてあった方が読みやすい。
その2: 名前が適当
ダメなコード
def main():
data = get_data()
value = get_value(data)
return value
なにやってるのかさっぱりわからない。。
def main():
# モデルの一覧を取得します
data = get_data()
# タスクタイプ毎の件数をカウントします
value = get_value(data)
return value
コメントを書くぐらいなら、適切な名前をつけよう
良いコード
def main():
models = get_model_list()
count_per_task_type = get_count_per_task_type(models)
return count_per_task_type
その3: 名前以上の事をしてる
ダメなコード
def main():
models = get_model_list()
count_per_task_type = get_count_per_task_type(models)
return count_per_task_type
def get_count_per_task_type(models):
count_per_task_type = ...
save_count('classification', count_per_task_type['classification'])
save_count('object_detection', count_per_task_type['object_detection'])
気軽に呼んでたらガンガンDBに書き込んでる件。
良いコード
def main():
models = get_model_list()
count_per_task_type = get_count_per_task_type(models)
save_count('classification', count_per_task_type['classification'])
save_count('object_detection', count_per_task_type['object_detection'])
return count_per_task_type
def get_count_per_task_type(models):
count_per_task_type = ...
return count_per_task_type
名前以上のことはしない!
その4: カッコつけない
ダメなコード
# 内包表記の方が速度的には早いらしいが。。
model_images = {
model: flatten([
[
image
for image in dataset.images
if image.filepath.exists()
]
for dataset in model.datasets
])
for model in models
if model.is_archived is False
}
競技プログラミングとかでやってくださいませ!
良いコード
model_images = {}
for model in models:
if model.is_archived is True:
continue
if model not in model_images:
model_images[model] = []
for dataset in model.datasets:
for image in dataset.images
if not image.filepath.exists():
continue
model_images[model].append(image)
ネストは深いけど、こっちのほうが理解はしやすい。
綺麗に書くテクニック
コントローラ部分に処理の流れをコメントとして書く
def main():
# モデルの一覧を取得します
pass
# タスクタイプ毎の件数をカウントします
pass
# テンプレートをレンダリングします
pass
# レスポンスを返します
pass
このコメントがそのまま関数になります。
(簡単な処理は関数化しなくてOKです)
呼び出し側だけ先に書く
def main():
# モデルの一覧を取得します
models = get_model_list(order='-creation_date', limit=30);
# タスクタイプ毎の件数をカウントします
count_per_task_type = get_count_per_task_type()
# テンプレートをレンダリングします
html = render_template(
template_path='./path/to/template.html',
models=models,
count_per_task_type=count_per_task_type,
)
# レスポンスを返します
return Response(200, html)
クラスや関数を作る際に先に呼び出し側を先に書く。
こうするとInput/Outputが決まるので、作るものが明確になる。
テストを先に書くと TDD
になるよ!
できるだけ関数を小さく書く
def main():
data = get_model_list()
value = get_count_per_task_type(data)
save_count('classification', value['classification'])
save_count('object_detection', value['object_detection'])
return value
def get_count_per_task_type(data):
value = # Get count per task type
return value
def save_count(name, value):
obj = ModelCount.objects.get(name=name)
obj.count = value
return obj.save()
関数が小さいと変数名が適当でも意味が通じる。
長い変数名を定義しないと意味が通じない場合は、関数が大きすぎる。
10〜30行ぐらいが目安。
同じパターンで書く
def get_model_list():
# Check parameters
...
# Get data from db
...
# Response
...
def get_model_detail():
# Check parameters
...
# Get data from db
...
# Response
...
WEBサーバーのエンドポイントとか、Reactコンポーネントとか、
大量に似たようなものを作る場合は、書き方(書く順番)を統一すると読みやすい。