この記事はモチベーションクラウドシリーズアドベントカレンダー2020の3日目の記事です。
自己紹介
初めまして!こんにちは!19年新卒の小宮と申します!
エンジニア歴は約1年程度で、バックエンドやQAも関わりつつ、
現在メインはフロントエンドエンジニアとして日々開発業務に勤しんでおります!
この記事を書こうと思った背景
この話は本当にあった怖い話です...
上のキャプチャは自分が初めて出した大きめのPRです。ご覧いただけますでしょうか?
Conversation 73
という恐ろしい文字列が・・・
自分がこの73コメント分(一部CodeCovなどの自動コメントも含まれますが)、
先輩エンジニアの時間を奪っているんだと勝手に責任感を感じて、
いそいそといただいたコメントに対応していたのが1年前だと思うと、時の流れを早く感じます。
上記のような現象、「自分も同じ経験をしたことがあるなあ・・・」という方も
一定数いらっしゃるのではないでしょうか?
この現象が起きる理由として、パッと思いつくだけでも
- その開発現場のコードのお作法を知らない
- 動けばいいや!という精神でコーディングしてしまう
- ここまで考慮できてますよ!というアピールで不必要なコードを書いてしまう
などと、他にもいっぱいあるんじゃないかなあと思っております。
今回、アドベントカレンダーで執筆の機会をいただけたので、一年前の自分のように
先輩の時間を奪って申し訳ねえ!というやるせない気持ちになる駆け出しエンジニアが
少しでも減る一助になれれば良いなあと思い、本記事を執筆しました!
具体的なセルフチェックチェック観点
言語共通
命名
コードというのは**「書くこと」より「読む/読まれること」の方が圧倒的に多い**のです!
命名に関してチェックするべき観点のほんの一例を紹介します!
// 略語について
number // Good! なるべく略語は使わない!
no // More! 「いいえ」のNoと勘違いする可能性も0じゃないですね
// 真偽値について
isParent // isで始めたり、
hasChild // 動詞で始めたり、
alreadyAppeared // 副詞+動詞の形だと真偽値を返してくれることが察しやすいですね!
// メソッドや変数名について(例えばECサイトでカートへ追加するメソッド名)
const add = function() { return ** } // 何をどこに加えるのかが分かりにくい。
const addToCart = function() { return ** } // ToCartを入れるだけでも何やっているか分かりやすくなったですね!
本当はまだまだあると思いますが、いったんこれくらいで!
ちなみに僕のエンジニアの師匠のさらにその師匠が
「エンジニアは、名前をつけるのがお仕事です。」と言っていたようです。
あと、命名の際はDeepL(Google翻訳よりも精度高い気がします)を使って、
日本語で何をしたいメソッドなのか言語化してから翻訳かけたりしています!
まとめられる箇所をまとめられていない
コピペを何度も繰り返しているところはメソッドに切り出してまとめましょう!
よくDRY(Don't Repeat Yourself)
って言われたりしますね!
console.log('hi! taro')
console.log('hi! hanako')
console.log('hi! hiroshi') // こんな風にいちいち呼び出さずに
const nameCall = function(name) { console.log(`hi! ${name}`) } // メソッドでくくっちゃいましょう!
nameCall('taro')
nameCall('hanako')
nameCall('hiroshi')
DRYを徹底することのメリットとして、
- コード量が減る
- 上記の例だと実感しづらいかもしれませんが、これは本当!笑
- 後から修正が入った時に修正が必要な箇所が少なくなる
- 上記の例だと「hi!」と挨拶していたのが、「hello!」になった時、nameCallだけ編集すればOK!
- コードが読みやすくなる
- 上記の例だと「あ、これは名前を呼んでいるんだな!」とメソッド名から推察しやすくなりますね!
不必要なコードも書いてしまう
よほどのことがない限り、今後これを使うことになるだろうから、今やっちゃおう!と
今必要ないコードを加えることはお節介になる可能性が高いです!
よくYAGNI(You ain't gonna need it)
って言われたりしますね!
// 例えば多言語対応することになり、先に英語版からリリースして、来年に中国版をリリースしよう!となったとき、
// 先んじて中国語の定数も定義しようというのはお節介になる可能性が高いです!!
export const LANGUAGE_TYPES = {
JA: {
KEY: 'ja',
TEXT: '日本語'
},
EN: {
KEY: 'en',
TEXT: '英語'
},
// ZH: { いらない!!
// KEY: 'zh',
// TEXT: '中国語'
// },
}
YAGNIを徹底することのメリットとして、
- 負債になる可能性のあるコードを残さない
- 上記の例だと中国語版のリリースが白紙になった場合、完全に負債になりますね!
- 読み手の「?」を減らす
- 上記の例だと中国語版のリリースが白紙になってから1年ぐらい経ち、あなたがそのプロジェクトを外れていた場合、「え、これって必要なコードなんですか?」と後から読む人の混乱を招く可能性がありますね!
- 後から実装する人がバグを出してしまう可能性を減らす
- 上記の例だと違う人が中国語を担当したときに、「あ、中国語も一緒にやってくれたんだ!」と安心してしまい、対応するべき箇所全てに対応するのを失念してしまう可能性がありますね!
スコープを意識しましょう
スコープとは、あなたが定義した変数や関数が参照される範囲のことです!
無駄に広いスコープで変数を定義すると、読み手に不親切な上に、不具合の温床になったりするので要注意です!
const scope = "Wide Scope"
function getNarrowScope() {
const scope = "Narrow Scope"
return scope
}
function getWideScope() {
return scope
}
console.log(getNarrowScope()) // Narrow Scope
console.log(getWideScope()) // Wide Scope
スコープを意識することのメリットとしては、
- コードを疎結合に保てる
- 上記の例だと"Wide Scope"の値を持つ方の変数scopeとgetWideScopeが相互に依存関係にありますね!コードは疎結合に保つことが正義です!
- 読みやすくなる
- 上記の例だとまだ読めますが、これが数百行のコードになった時、"Wide Scope"の値を持つ方の変数scopeを100行下で呼び出していたりしたら、読み手にかける負担が大きくなりますね!
- 書きやすくなる
- 実際にコードを書くときも、意識するべきことが減るので、実装する際においても考えることが減ると思われます!
マジックナンバー
マジックナンバーとは、意味を持つ数字を、直接書いて、読み手が
「なんだこれ?」となってしまうような数字のことです。
// 例えば100円ショップでお買い物をする時
const price = 100 * 1.10 // 1.10が何のことだか分からない!
const tax = 1.10
const price = 100 * tax
マジックナンバーを撲滅することのメリットとしては、DRYの説明で書いたのと同じで、
- コード量が減る
- 上記の例でも実感しづらいかもしれませんが、これは本当!笑
- 後から修正が入った時に修正が必要な箇所が少なくなる
- 上記の例だと消費税が20%になった時(やだなぁ...)、taxだけ編集すればOK!
- コードが読みやすくなる
- 上記の例だと「あ、これは消費税のことだな!」と定数名から推察しやすくなりますね!
インデントやtypo
これらは基本的なことでかつ、すぐ見つけられることなので、もう一度見直しましょう!
インデントを見やすくしたり、typoらしきものを色付けしてくれる拡張機能も多くのエディターで備えてくれているので、
それらも是非活用しましょう!(以下例はVSCodeのCode Spell Checker
)
JavaScript
console.logの消し忘れ
開発中に書いていたconsole.logを消し忘れていないかは要チェックですね!
これをやったときはだいぶ死にたくなりました!
変数の定義
こちらはES6で新しくできるようになったことですが、変数の宣言にvar
以外が使えるようになりました
→参考 : var/let/constの使い分けのメモ
(良書でも古いものだと未だにvarが使われたりしますが、今やvarは使わない!と言っても過言ではないです)
他にもES6は便利なので、極力活用しましょう!(ここで書くとボリューミーなので、今回は省略)
var name = "taro" // varは使わない!!!
const name = "taro" // 真っ先に使うべきはconst
// 名前が「田中ジェイソン太郎」というミドルネーム持ちの人がいて、海外ではジェイソンと呼ばれていて、
// どうしても再代入が必要な場合だけletを使いましょう!
let name
if (country === "japan") {
name = "taro"
} else {
name = "Jason"
}
変数定義にこだわることで、以下のメリットがあります!
- ファイル内で変数にスコープを持たせられる
- 読み手にとって親切
- 例えばletで変数が定義されていた場合、読み手は「あ、これはどこかで再代入されるのか!」と予測しながら読み進められる
CSS
カラーパレット
文字の色や、背景色を定義するとき、
カラーパレットを使える場合はそちらを活用しましょう!!
background-color: #bf2926; // 直接カラーコードを書かない!
$PASSIONATE_RED: #bf2926; // 共通で使えるカラーパレットがどこかで定義されているかどうか確認して
background-color: $PASSIONATE_RED; // ある場合はそのカラーパレットに割り当てられた定数を使いましょう!
カラーパレットを一貫して使うことのメリットとしては以下が挙げられると思います
- プロダクトに使われているそれぞれの色に役割を持たせやすくなる
- レッドはエラー、グリーンは成功、オレンジは注意などと、命名と共に定義すると色に役割を割り当てやすくなりますね!
- どんな色だかイメージしやすくなる
- 例えば
#bf2926;
が何の色だかぱっと見で判るほど記憶力の良い人はいないと思いますが、$PASSIONATE_RED
なら「情熱的な赤い色なんだろうな〜」とイメージできやすくなりますね!
- 例えば
8の倍数ルール
marginやheight、font-sizeなどの大きさを8や4の倍数で統一している可能性があります!
メリット等は以下の記事などを読むとわかりやすいので、是非ご一読を!
→参考 : 8の倍数ルールでデザインする理由とメリット・デメリット
最後に
夢中で思いつく限りのことを書いてみました。
(本当はvue.js特有のことなども書こうと思ったんですが、力尽きましたw)
コードレビューに出す内容って相手への敬意の現れだなと思っていて、
正直、上記の内容を一回指摘されるぐらいなら全然OKだと思う(新人だし仕方ないよ!ってなると思う)んですが、
一度指摘されたことは次のPRでは絶対指摘されないぞ!という心意気が一番大事かなと思います!!
ではみなさん良い12月を!!
僕は月末までに彼女を作ります!!!
おまけ(参考資料)
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
これは自分がエンジニアになったときに職場の先輩から真っ先に読め!と言われた本です。
当時は「はいはい、なるほどね〜」くらいだったんですが、今改めて読み返すと、
「当時の自分全然わかってなかったんやな...」と奥の深さを知れるエンジニアの登竜門的な本
プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則
一番最初にあげたリーダブルコードより新しいもので、今回自分が挙げたYAGNIとかDRYとか、
そのほかにもエンジニアの道標?心得?的なのがたくさん載ってます。
リーダブルコードと違って、具体的なコードが一切載っていなかったり、
日本人が書いたものなので、初心者にも読みやすいのかなと思います。
改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで
そもそものJavaScriptへの入門として、こちらの教材は少し難解な部分もあるのですが、
一通りしっかりやると、かなりの実力がつくのではないかなあと思います。
JavaScriptの古い記法から、新しいES6の記法までをさらっているため、
よりES6のメリットが分かったり、現場によっては割と古い記法で書かれているところもあるので、
そういった方にもお勧めできますね!
やっぱりプログラミング(今回はvue)の学習といえばアプリ作成!ということでカレンダー!
学習のために、最初の方は色々と教材を買ってやってみたのですが、
やっぱり自分でアプリを作るのが一番学習になります。
ということで私はこちらの記事を参考に、カレンダー的なものを作りました!
追加機能として例えばモーダルを自作してみたりしてもいいかもしれませんね!