読者です 読者をやめる 読者になる 読者になる

JavaScript勉強会

JavaScriptの学習日記

リファクタリング=読みやすいプログラムを書こう!

JavaScript学習に役立つお話がありました。

リファクタリング」でプログラムを改善する練習について紹介されています。

 

www.webprofessional.jp

 

前回に引き続き、今回もこのお話から学んでみたいと思います。)

 

jsstudy.hatenablog.com

 

アプリ作成の進め方として、以下の手順が紹介されています。

  1. 最初に基本を身に着けよう
  2. 計画を立てる
  3. コード無しで書いていく
  4. 小さな部分に分けて製作する
  5. 各パーツを結合する
  6. 実験とテスト
  7. 外部の助けを求める
  8. コードのリファクタリング(再構築)

 

リファクタリングとは?

reの意味 - 英和辞典 Weblio辞書

re‐ 【接頭辞】

「相互,反,後,退,秘; 離,去,下,,否,不」などの意.

 接頭辞の「re」は、再びという意味

 

factorの意味 - 英和辞典 Weblio辞書

factorとは

(ある現象・結果を生ずる)要因、要素、原因、代理商、問屋、仲買人、因数、因子

「factor」は、要素という意味

 

→ re(再)+factor(要素)=プログラムの構成要素を見直す、という意味?

 

リファクタリング (プログラミング) - Wikipedia

リファクタリング (refactoring) とは、コンピュータプログラミングにおいて、プログラムの外部から見た動作を変えずにソースコードの内部構造を整理することである。

 

特集・現場で役立つリファクタリング:そのソフトウェア資産、ずっと使い続けられますか? (1/2) - MONOist

リファクタリングの定義と目的

外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェアの内部構造を変化させること

ソースコードの理解度を向上させること”がリファクタリングの目的です。

 

f:id:jsstudy:20170409005850j:plain

 

リファクタリングに関する本もいろいろあるので参考になります。

 

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

 

 

リファクタリングのチェックポイント

プログラムの構成を見直すとき、どこを見れば良いでしょうか?

 

プロジェクトを完成する前に、コードのリファクタリング(見直し・再構築)を検討してください。

以下は、改良のために自分自身に問いかけたい質問です。

 

  1. コードは簡潔で読みやすいか?
  2. コードは効率的か?
  3. 関数や変数の名前は分かりやすいものになっているか?
  4. 名前の衝突の可能性はないか?
  5. 編集過程でエラー原因を生んでいないか?
  6. 表示は適切になっているか?
  7. コードが無駄に冗長になっていないか?
  8. プロジェクトを新鮮な目で見るとどう見えるか?

 

グチャグチャで汚いコードは、「スパゲッティーコード」などと呼ばれており、その特徴は「コードの臭い」と呼ばれています。

 

スパゲティプログラム - Wikipedia

スパゲティプログラムまたはスパゲティコードとは、プログラムのソースコードがそれを制作したプログラマ以外にとって解読困難である事を表す俗語。

名称の由来は、皿に盛られたスパゲッティのようにロジックが絡み合っていることから。

 

コードの臭い - Wikipedia

コードの臭い(Code smell)とは、コンピュータプログラミングにおいてプログラムのソースコード深刻な問題が存在することを示す何らかの兆候のことを言う。

リファクタリングを実施するプログラマの視点からは、コードの臭いはいつリファクタリングするか、どのリファクタリング手法を用いるか、発見するための方法である。

 

一般的なコードの臭い

  • 重複したコード
    同一あるいは同様のコードが複数箇所に存在。
  • 長すぎるメソッド
    メソッド、関数、手続きが長くなりすぎている。
  • 巨大なクラス
    大きくなりすぎたクラス。神オブジェクト参照。
  • 機能の横恋慕
    他クラスのメソッドを過度に用いるクラス。
  • 不適切な関係
    他のクラスの実装の詳細に依存しているクラス。
  • 相続拒否
    基底クラスの規約が尊重されない形でのメソッドオーバーライド。リスコフの置換原則参照。
  • 怠け者クラス
    行うことが少なすぎるクラス。
  • 重複メソッド
    同一あるいは同様のメソッドが複数箇所に存在。
  • 不自然な複雑さ
    簡潔な設計で十分なところに、過剰に複雑なデザインパターンの使用を強制する。

 

先人の工夫によって、リファクタリングのノウハウがまとめられています。

 

d.hatena.ne.jp

 

リファクタリングの事例

上記のお話では、リファクタリングの見本として、重複の解消などを紹介していました。

 

コードが無駄に冗長になっていないか?

本来なら関数やループでまとめられるところを、繰り返し同じコードを書いてはいませんか? 先の処理では、出力にゼロを追加するコードは単独の関数にまとめられます。これで重複が減り、コードも読みやすくなります。

 

●Before

const seconds = ('0' + Math.floor((remainingTime/1000) % 60)).slice(-2);
const minutes = ('0' + Math.floor((remainingTime/(60*1000)) % 60)).slice(-2);
const hours = ('0' + Math.floor((remainingTime/(60*60*1000)) % 24)).slice(-2);
const days = ('0' + Math.floor(remainingTime/(24*60*60*1000))).slice(-2);

「ゼロ詰め」(ゼロ埋め、ゼロを付ける処理)が、個別に何回も出てきます。

↓↓↓

●After

function pad(value){
  return ('0' + Math.floor(value)).slice(-2);
}

const seconds = pad((remainingTime/1000) % 60);

「ゼロ詰め」の関数pad()を用意すれば、同じようなコードの繰り返しを減らせます。

 

個人的には、

なんか面倒くさいな~

と感じたら、リファクタリングが必要なサインだと思います。(笑)

 

コードゴルフ

コードゴルフ」という、リファクタリングのような遊びがあります。

 

コードゴルフ - Wikipedia

コードゴルフ はコンピュータプログラミング・コンテストの一種である。

参加者は与えられたアルゴリズムを、可能な限りもっとも短いソースコードで記述することを競う。

ショートコーディング、コードパズル等とも呼ばれる。

 

プログラマのためのコードパズル ~JavaScriptで挑むコードゴルフとアルゴリズム

プログラマのためのコードパズル ~JavaScriptで挑むコードゴルフとアルゴリズム

 

 

コードゴルフは、ゴルフがカップインまでの打数を競うように、プログラムのソースコードの文字数を削って、なるべく短く書く遊びです。

 

1行だけのプログラム「ワンライナー」(One-Liner)

文字数を削る遊びだけでなく、行数を削る遊びもあります。

 

ワンライナーとは - はてなキーワード

ワンライナー」とは、たった1行だけのプログラムです。

プログラムを書きたいが、エディタを起動するほどの手間はかけたくない、というときに威力を発揮します。

達人ともなると、ちょっとした文字置換や計算をするワンライナーを、即興で作って使い捨てることもあります。

 

プログラミングが速い人によると、

プログラミングはパズルと同じ

だそうです。

 

(知り合いのプログラマーで、「知恵の輪」を数秒眺めただけで解ける人がいました!!!)

 

 

  • 小さいコード(コード断片)は、パズルのピースのようなもの
  • 小さいコードを組み合わせて、大きなコードを組み立てる
  • 頭の中ではパズルを解くように、コード断片をいろいろ組み合わせている
  • 似たような機能を何度も作っていると、必要なコード断片をすぐに揃えられる

 

プログラミングが速い人は、何か特別なことをやっているわけではなく、必要な部品が何かを考えて、思い出すのが早いだけ!?

 

プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問

プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問

 

 

念力デバッグ!?

仕事でプログラミングをやると、納期に追われて大変なときもあります。

=大量のテストやデバッグを短期間でやらなければいけないときは、面倒くさい?

 

プログラミングテクニック番外編

念力デバッグ

経験を積んだプログラマの特技.デバッグ用のコードやデバッガなしに,気合いのみでデバッグを行う.理論的な考察は不可能だが,納期後の現場デバッグ状況でよく見られる.

 

サーバ管理者日誌 続・クロールとDoSの違いと業務妨害罪と

「念力デバッグ」という仕事があって、ごく稀にお仕事を頂く。

念力デバッグというのは、安楽椅子探偵に似たようなデバッグで、デバッガやデバッグ用のコードを使わずに、直観と論理に基づく推理だけでバグを探すデバッグだ。

通常のデバッグでは、デバッガを用いたり、デバッグ用のコードを走らせたりできるので、念力デバッグの出番はあまりないのだが、既に仕様書やソースコードが存在しなかったり、実機に触れることができなかったり、その全てがなくて、バグレポートだけでバグ解析して運用回避手段を見つける必要があったりという状況があって、そういう場合に、念力デバッグの登場となる様だ。

念力デバッグの結果は、材料が少ないときは特に占いめいていて、「午前2時に、おにぎりを大量に買ってみて下さい。日配品の集計モジュールを書いた人が、コードを書いた当時に経験が浅かったとしたら、集計タイミングに売上が発生する可能性を考慮しておらず、一貫性が保てなくなった可能性があります。推理が正しければ、件の現象が再現すると思われます。」といったレポートを書いて、推理が当たれば一件落着となる訳だ。

 

安楽椅子探偵 - Wikipedia

安楽椅子探偵(アームチェア・ディテクティブ、Armchair Detective)とは、ミステリの分野で用いられる呼称で、部屋から出ることなく、あるいは現場に赴くことなく事件を推理する探偵、あるいはそのような趣旨の作品を指す。

 

達人になると、コードを見なくてもどこにエラーの原因があるのか?見つけることができるようになりますw

 

f:id:jsstudy:20170409125226p:plain

 

まとめ

 

プログラミングが面倒・退屈だと感じたときは、パズルのようにリファクタリングで遊びましょう!

プログラミングは本来「創造的で楽しい遊び」であり、経験を積むと楽になっていく、ということを忘れないようにしたいです。(原点回帰、初心忘るべからず)