SlideShare a Scribd company logo
可読性について Part3
コードの再構築
前回のおさらい
- 制御フローを読みやすくする
- 条件式の引数の並び順
- 早期returnでネストを浅くする
- 巨大な式を分割する
- 説明変数/要約変数の活用
- 複雑なロジックと格闘する
- 変数と読みやすさ
- スコープを意識しよう
コードの再構築
- Part3では、コードを大きく変更する技法
- 「無関係の下位問題」を抽出する
- 一度に1つのことをする
- コードを言葉で説明する
- 短いコードを書く
1 「無関係の下位問題」を抽出する
- 関数やコードブロックを見て「高レベルの目標は何か?」と探る
- コードの各行に対して「高レベルの目標に直接的に効果があるか?」と探る
- 無関係の下位問題を解決しているコードが相当量あれば、それらを抽出して
別の関数にする
1-1-1 実例 其の壱
1-1-2 実例 其の壱
1-2 やりすぎ禁物
- 無意味で小さな関数を作りすぎると、逆に読みにくくなってしまう
2 一度に1つのことを
- 関数は1度に1つのことを行うべき
- 手順
1. コードが行っているタスクを全て列挙する
2. タスクをできるだけ異なる関数に分割する
2-1 タスクは小さくできる
3 コードを言葉で説明する
おばあちゃんがわかるように説明できなければ、本当に理解したとは言えない。
(アルバート・アインシュタイン)
3-1 コードをより明確にする手順
1. コードの動作を簡単な言葉で同僚にもわかるように説明する
2. その説明の中で使っているキーワードやフレーズに注目する
3. その説明に合わせてコードを書zく
3-1-1 ロジックを明確に説明する
3-1-2 ロジックを明確に説明する
3-1-3 ロジックを明確に説明する
- 動作や仕様を言語化できない = 明確に理解できていない
- 「簡単な言葉で説明する」手法は開発以外にも使用できる
- 今回取り上げきれなかった解決例もあったのでぜひ書籍も
4 短いコードを書く
- 最も読みやすいコードは、何も書かれていないコードである
- 実現するには、要求を正しく理解していること
- 未使用のコードは削除する
- 身近なライブラリに親しむ
まとめ
- 「無関係の下位問題」を抽出する
- メソッドと関係のない処理を抽出する
- 一度に1つのことをする/手順
- コードが行っているタスクを全て列挙する
- タスクをできるだけ異なる関数に分割する
- コードを言葉で説明する
- コードの動作を簡単な言葉で説明できるように
- 短いコードを書く
- 将来使うだろうは10%しか使われない
- 未使用のコードは削除
- ライブラリの活用

More Related Content

More from tak

TypeScriptのdecoratorについて
TypeScriptのdecoratorについてTypeScriptのdecoratorについて
TypeScriptのdecoratorについて
tak
 
Rust + web assemblyやってみた
Rust + web assemblyやってみたRust + web assemblyやってみた
Rust + web assemblyやってみた
tak
 
第ⅴ部:clean architecture アーキテクチャ Part8
第ⅴ部:clean architecture アーキテクチャ Part8第ⅴ部:clean architecture アーキテクチャ Part8
第ⅴ部:clean architecture アーキテクチャ Part8
tak
 
第ⅴ部:clean architecture アーキテクチャ Part7
第ⅴ部:clean architecture アーキテクチャ Part7第ⅴ部:clean architecture アーキテクチャ Part7
第ⅴ部:clean architecture アーキテクチャ Part7
tak
 
第ⅴ部:clean architecture アーキテクチャ Part6
第ⅴ部:clean architecture アーキテクチャ Part6第ⅴ部:clean architecture アーキテクチャ Part6
第ⅴ部:clean architecture アーキテクチャ Part6
tak
 
第ⅴ部:clean architecture アーキテクチャ Part5
第ⅴ部:clean architecture アーキテクチャ Part5第ⅴ部:clean architecture アーキテクチャ Part5
第ⅴ部:clean architecture アーキテクチャ Part5
tak
 
第ⅴ部:clean architecture アーキテクチャ Part4
第ⅴ部:clean architecture アーキテクチャ Part4第ⅴ部:clean architecture アーキテクチャ Part4
第ⅴ部:clean architecture アーキテクチャ Part4
tak
 
第ⅴ部:clean architecture アーキテクチャ Part3
第ⅴ部:clean architecture アーキテクチャ Part3第ⅴ部:clean architecture アーキテクチャ Part3
第ⅴ部:clean architecture アーキテクチャ Part3
tak
 
第ⅴ部:clean architecture アーキテクチャ Part2
第ⅴ部:clean architecture アーキテクチャ Part2第ⅴ部:clean architecture アーキテクチャ Part2
第ⅴ部:clean architecture アーキテクチャ Part2
tak
 
第ⅴ部:clean architecture アーキテクチャ Part1
第ⅴ部:clean architecture アーキテクチャ Part1第ⅴ部:clean architecture アーキテクチャ Part1
第ⅴ部:clean architecture アーキテクチャ Part1
tak
 
第ⅳ部:Clean architecture コンポーネントの原則
第ⅳ部:Clean architecture コンポーネントの原則第ⅳ部:Clean architecture コンポーネントの原則
第ⅳ部:Clean architecture コンポーネントの原則
tak
 
第ⅲ部:Clean architecture 設計の原則
第ⅲ部:Clean architecture 設計の原則第ⅲ部:Clean architecture 設計の原則
第ⅲ部:Clean architecture 設計の原則
tak
 
第ⅱ部:Clean architecture 構成要素から始めよ
第ⅱ部:Clean architecture 構成要素から始めよ第ⅱ部:Clean architecture 構成要素から始めよ
第ⅱ部:Clean architecture 構成要素から始めよ
tak
 
第ⅰ部:Clean Architecture イントロダクション
第ⅰ部:Clean Architecture イントロダクション第ⅰ部:Clean Architecture イントロダクション
第ⅰ部:Clean Architecture イントロダクション
tak
 

More from tak (14)

TypeScriptのdecoratorについて
TypeScriptのdecoratorについてTypeScriptのdecoratorについて
TypeScriptのdecoratorについて
 
Rust + web assemblyやってみた
Rust + web assemblyやってみたRust + web assemblyやってみた
Rust + web assemblyやってみた
 
第ⅴ部:clean architecture アーキテクチャ Part8
第ⅴ部:clean architecture アーキテクチャ Part8第ⅴ部:clean architecture アーキテクチャ Part8
第ⅴ部:clean architecture アーキテクチャ Part8
 
第ⅴ部:clean architecture アーキテクチャ Part7
第ⅴ部:clean architecture アーキテクチャ Part7第ⅴ部:clean architecture アーキテクチャ Part7
第ⅴ部:clean architecture アーキテクチャ Part7
 
第ⅴ部:clean architecture アーキテクチャ Part6
第ⅴ部:clean architecture アーキテクチャ Part6第ⅴ部:clean architecture アーキテクチャ Part6
第ⅴ部:clean architecture アーキテクチャ Part6
 
第ⅴ部:clean architecture アーキテクチャ Part5
第ⅴ部:clean architecture アーキテクチャ Part5第ⅴ部:clean architecture アーキテクチャ Part5
第ⅴ部:clean architecture アーキテクチャ Part5
 
第ⅴ部:clean architecture アーキテクチャ Part4
第ⅴ部:clean architecture アーキテクチャ Part4第ⅴ部:clean architecture アーキテクチャ Part4
第ⅴ部:clean architecture アーキテクチャ Part4
 
第ⅴ部:clean architecture アーキテクチャ Part3
第ⅴ部:clean architecture アーキテクチャ Part3第ⅴ部:clean architecture アーキテクチャ Part3
第ⅴ部:clean architecture アーキテクチャ Part3
 
第ⅴ部:clean architecture アーキテクチャ Part2
第ⅴ部:clean architecture アーキテクチャ Part2第ⅴ部:clean architecture アーキテクチャ Part2
第ⅴ部:clean architecture アーキテクチャ Part2
 
第ⅴ部:clean architecture アーキテクチャ Part1
第ⅴ部:clean architecture アーキテクチャ Part1第ⅴ部:clean architecture アーキテクチャ Part1
第ⅴ部:clean architecture アーキテクチャ Part1
 
第ⅳ部:Clean architecture コンポーネントの原則
第ⅳ部:Clean architecture コンポーネントの原則第ⅳ部:Clean architecture コンポーネントの原則
第ⅳ部:Clean architecture コンポーネントの原則
 
第ⅲ部:Clean architecture 設計の原則
第ⅲ部:Clean architecture 設計の原則第ⅲ部:Clean architecture 設計の原則
第ⅲ部:Clean architecture 設計の原則
 
第ⅱ部:Clean architecture 構成要素から始めよ
第ⅱ部:Clean architecture 構成要素から始めよ第ⅱ部:Clean architecture 構成要素から始めよ
第ⅱ部:Clean architecture 構成要素から始めよ
 
第ⅰ部:Clean Architecture イントロダクション
第ⅰ部:Clean Architecture イントロダクション第ⅰ部:Clean Architecture イントロダクション
第ⅰ部:Clean Architecture イントロダクション
 

可読性について リーダブルコード Part3(コードの再構築)

Editor's Notes

  1. 今回ページ数としては少ないですが、内容としてはかなり凝縮されたPartになっております。
  2. これらを書籍に書かれていたこと+普段茶谷さんなどから教えて頂いている事や実務を通して学んだことを織り交ぜながら進めて行きたいと思います。
  3. まず最初に「無関係の下位問題を抽出する」についてです。要するに単一責任の原則で、1メソッド1責任で命名以上のことをしないように、メソッドがファットにならないようにです。もし命名以上の処理をしていたらそれは、別メソッドで切り出すべきです。
  4. こちらは実例になり、画像のコードは原文ままのメソッドになります。メソッドで行われていることといたしましては、与えられた緯度経度に最も近いarrayの要素を返すというというメソッドなのですが、それに対して、「2つの地点をラジアンに変換する」というタスクが混ざっており責務が2つ発生してしまっています。こちらを別メソッドとして抽出することができます。
  5. 左側が新しくメソッドとして切り出したもの、右側が残ったコードになります。コードを別メソッドで切り出し、残ったコードは本来の責務1つのみとなります。こうすることで、可読性も高まり修正をする時も、このメソッドは一つの理由だけで修正されることになります。メソッドは小さくて独立したものになっていれば、機能追加・読みやすさの向上につながります。これらを抽出するポイントとしては、メソッドの事前処理や事後処理などの本質とは関係のない処理、いわゆるグルーコードを積極的に抽出することです。また抽出したメソッドが汎用性の高い場合は、utilsなどへ置いてプロジェクト内部で読み込めるようにしておくと便利です。
  6. 良い例がなく自作してみてすごく難しかったんですが、画像のようにobjの中にあるnameがあれば取ってくる、なければ空文字を返すという処理です。一旦obj.nameがあるか確認するメソッドを作って、その真偽値によって空文字を返すメソッドを作って、値があればobj.nameを返すというだけですが、やりすぎてしまうと逆に変わり辛く、修正も困難になってしまいます。
  7. 続いては「一度に1つの事を」です。一度に複数のことをするコードは理解しにくく、責務が複数あるとテストも書きづらくなってしまいます。大きな関数は責務を分けて小さく分割すべきです。では具体的な手順ですが、コードが行っているタスクを全て列挙して、それらをできるだけ異なる関数に分割していきます。この「タスク」という定義はケースバイケースになると思うので、適宜判断しましょう。一つの基準として関数の命名に悩むようであれば、「複数のことをしている関数だ」といえますので一つの基準として覚えておきましょう。
  8. こちらは例題として「賛成、upで+1」と「反対、downで-1」をユーザーが投票できる左側のメソッドがあったとします。左側のコードはスコアを更新するという1つのタスク以外にも「old_voteとnew_voteを数値にパースする」というタスクが含まれています。これらのタスクを別々に切り出したコードが右側になります。最小のタスクに切り出したことで可読性が増し、コードを「楽に理解できる」ようになったと言えます。
  9. 続いては「コードを言葉で説明する」です。コードの動作を説明する時に、自分よりも知識が少ない人でも「誰にでもわかるように」簡単な言葉で説明できないと本当に理解してコードを書いているとは言えません。それには自分の考えを凝縮して、最も大切な概念にすることが必要です。そして、普段からソースコードに触れているプログラマにとっては、コードそのものがプログラムの動作を説明する大切な手段になります。つまり、コードも「簡単な言葉」で書くべきです。この第三章ではコードをより明確にする手順を使っていきます。
  10. コードをより明確にする手順は以下の通りです。1〜〜〜。では次から具体例を見て行きましょう。
  11. では具体例ですが、左側はPHPのコードの一部で、ユーザにページを閲覧する権限があるかどうかを確認して、もし権限がなければ、権限がないことをユーザに知らせるページへ戻すというコードです。左側にはロジックが多くあり可読性が低くなっています。このコードを一旦誰にでもわかるような簡単な言葉に置き換えてからコードを書き直したのが右側になります。ロジックそのものも否定形がなくなったりネストが浅くなったり単純化されたため可読性も増しました。
  12. 次の例は、ユーザがページを訪問するとヒントがランダムに表示され残りは隠された状態だが、「その他ヒントをみる」をクリックすると、次のヒントが表示されるというjQueryコードです。同じく「誰にでもわかるように」一度コードの動作を簡単な言葉にしてみます。その説明を元に書き直したのが左側になります。コードは短くなり、数値を直接操作する必要もなくなり、人間がどのように考えるかを重視した読みやすいコードになりました。
  13. このように動作や設計/仕様をうまく言葉でできないのであれば何かを見落としているか、そもそも詳細が明確になっていないと言えます。また、「簡単な言葉で説明する」手法は、開発以外でも適用できて、例えばデバッグの際にパソコンの横にアヒルのおもちゃを置いて、そのおもちゃに向かって語りかけることで、問題を解決するとう「ラバーダッキング」技法というものが存在します。あと、リーダブルコードには先ほどの例よりももっと巨大なコードを改善する例があったのですが、こちらでは取り上げれるような大きさではなかったため、ぜひ書籍を読んでみて頂ければと思います。それと、これらロジックの整理ということでは、サンプルのように実際にやりたいことを先に言語化してみるのと、個人的にはテスト技法のデシジョンテーブルや直交表、状態遷移表のNスイッチカバレッジを活用すれば、ロジックを整理するのにはとても有効だと感じました。テスト技法については今回のLTでは省きます。
  14. 続いては「短いコードを書く」です。このタイトルだけだとワンライン=正義のような誤解を生みそうなので、そうではないことを先に申し上げておきます。リーダブルコードで一貫していることは「読みやすいコードが優れたコード」であるということです。ではここで言われている「短いコードを書く」とはなんなのか?ですが、リーダブルコードでは「最も読みやすいコードは、何も書かれていないコードである」と記述されています。これはつまり「YAGNIの原則」にあたり、「後で使うだろうという予測の元に作ったものは、実際には10%程度しか使われないので、それに費やした時間の90%は無駄になる」という原則です。そしてコードがないのであればバグが生まれることもありません。ただし、YAGNIの原則を実現させるにはクライアントの要求を正しく理解している必要があります。「何を実現させたいのか?何を解決させたいのか?」をしっかり把握することが「短いコードを書く」ことの第一歩になります。また、規模が大きくなるにつれて、未使用のコードが生まれてきてしまいますが、これはあえて言うまでもなく削除していきましょう。そして、ライブラリの活用も有効です。これに関しては自作していった方がブラックボックス化されなくて良い、という意見もありそうですが、ライブラリの機能を熟知して実際に活用するのは有効な手段であると記載されています。理由としては、成熟したライブラリのコードの裏側には、膨大な設計・デバッグ・修正・ドキュメント・最適化・テストが存在しており、現在まで生き延びてきたライブラリコードには大きな価値があるため、それを再利用すると時間とコード記述の節約になるためであると書かれています。よく使われる統計では、平均的なエンジニアが1日に書く出荷用のコードは10行である」という統計があり、このことを考えるとライブラリの再利用の意義がわかる気がします。
  15. では最後にまとめです。〜〜〜。今回可読性についてPart3までやらさせて頂きましたが、次回Part4で最終回になります。ご静聴有難うございました。