CodeIQ MAGAZINECodeIQ MAGAZINE

綺麗なコードと汚いコード。どちらのプログラマと一緒に働きたい?~可読性を意識したプログラム言語はRuby, CoffeeScript, Elixir #Ruby #CoffeeScript #Elixir

2014.02.04 Category:技術コラム Tag: , ,

  • 153
  • このエントリーをはてなブックマークに追加
HTML web code

CodeIQの出題者である@tbpgrさんからの寄稿記事です!どうして汚いコードができてしまうのか、どうやったら綺麗なコードが書けるのかをわかりやすくポイントで解説しています。
また、綺麗なコードを書くには、言語の特性も関係するということで、可読性を意識したプログラム言語として、Ruby、CoffeeScript、Elixirを挙げています。
これであなたのコードも綺麗になる!?
by CodeIQ運営事務局

プログラムの可読性について

CodeIQでRubyやCoffeeScript問題を出題している@tbpgrです。

今回は、開発の現場にいるからこそ見えてくる「綺麗なコードと汚いコード」をテーマに書いてみます。

あなたのコードは綺麗ですか?それとも汚いですか?

綺麗なコードを書く人は、他の開発者から

「○○さんのコードって本当に綺麗ですね」  

と言われたことがあるのではないでしょうか?

逆に汚いコードを書く人は

「××さんのコードは汚くて読めないよ」

など言われることがあるかもしれません。

ひっそり

「あいつのコードひどいんだよ」

などと噂されているのに、本人の耳に入らないこともあるかと思います。

もしかしたら、リファクタリング中毒の開発者が
リファクタリングの帽子をかぶりながら

「また俺にリファクタリングして欲しくてそんな汚いコードを書いてくれたんだ。
いつもいつも本当にありがとう」

と嬉しそうにお礼を言ってくれるかもしれません。

しかし、大抵の同僚は綺麗なコードを書く開発者と仕事をしたいと思っています。

汚いコードは百害あって一理なし。

長期的にはシステム開発会社・顧客双方の利益を損なう時限爆弾となるのです。

コードの可読性については、国、組織、言語等それぞれが所属するコンテキストによって、ある程度の揺れ幅があります。

当記事では一般的に良い、悪いと言われる内容に絞って説明させていただきます。

まずは汚いコードとはどんなものか、そしてどのような影響があるか。
どうやって綺麗なコードを書くかについてです。

汚いコードは技術的負債

汚いコードとはどのようなものか?

汚いコードの厳密な定義は難しいですが、例えば下記のようなものが代表的な例でしょう。

  • 命名が不適切(クラス名、関数名、メソッド名、変数名、定数名等)
  • 1つの関数やメソッドの処理が非常に長い
  • コメントで補足しないと意味がわからない
  • メソッド内の処理の抽象度が統一されていない
  • スペーシングやインデントなどコーディングスタイルが統一されていない
  • コピペコード

汚いコードはどのような影響をもたらすのか?

汚いコードがあると主担当者以外が内容を読み解くことが困難になります
それどころか主担当者自身も時間が経つと内容を読み解くことが困難になります

  • 汚いコードは誤解やミスを生みやすく、バグの混入確率を押し上げる
  • 汚いコードは共通化やリファクタリングが可能なコードの臭いを察知しにくくする
  • 汚いコードは理解して手を動かし始めるまで時間がかかる
  • 汚いコードは仕様追加・バグの調査/修正が困難である

システム開発において時間はコストであり、顧客にとってはビジネスチャンスでもあります。
開発会社は残業や増員や売上増の伴わない納期の延長でコストが増え、利益が減っていきます。
顧客は競合に遅れをとりビジネスのチャンスを逃すかもしれません。

最終的にはシステムの要件追加・改修・バグ対応の難易度がどんどん高くなり
開発のペースが落ち、開発のコストを押し上げます。

このようなものは技術的負債(Technical debt)と呼ばれます。

過去の個人的な経験から見ても、綺麗なコードを書く人はバグが少ない上に
仕事が早く、汚いコードを書く人はバグが多い上に、仕事が遅い傾向にあります。

可読性の高いコードは保守性が高く、バグを生みにくいと言えますし、
可読性の高いコードを書ける人は能力が高いケースが多い、とも言えます。

綺麗なコード VS 汚いコード

とあるJavaの開発現場でのお話。

自他共に認める圧倒的なソースコードの汚さに悩む開発者Oさんがいました。
彼はソースコードが汚いもののコーディング自体は早く、
類似プロジェクトの経験により対象業務に詳しかったため
比較的重要な箇所をいくつも担当していました。
また非常に明るい性格でプロジェクトのムードメーカーでもあったため、
なんとなく許してあげたくなる雰囲気を持つ人物でした。

彼が作成したかなり大きめのクラスがありました。

  • 命名が不適切
  • 各メソッドは非常に長い
  • メソッドの引数の数が過剰に多い
  • 各メソッドの依存度が高く、1箇所の修正が複数の箇所に影響する
  • あちこちに同じようなif文が散らばっている
  • チームのコーディング規約を守らない
  • FindBugsやCheckStyleの警告を無視する
  • 引数に渡した値に副作用を与えるメソッドが多数ある。
    またメソッドコメントやメソッド名からはそのことが読み取れない。

他にも…

  • 嘘のコメントがある
  • そもそもJavaはほぼ未経験
  • コピペの残骸があちらこちらにある
  • コメントアウトしたままのロジックが散在している
  • 誤った作法の指摘をしても中々直らなかったり、自分のこだわりを貫いたりする
  • 綺麗なコードを書ける担当者が一部のコードを綺麗に直しても
    自分好みの記述に書き直してしまう

アンチパターンの宝石箱です。
それはもう壮絶なソースコードでした。

当然のように、このクラスのバグがいつまでも出続けていました。

私:「Oさん!またあのクラスバグったよ!」

Oさん:「もう自分でも何書いてあるかわからないんだよ!」(大声)

チーム一同:爆笑

プロマネ:(怒)

コードの中身は複雑過ぎて、本人以外は理解が困難です。
いや、本人ですら理解困難です。

幸いテストコードがあったため、デグレード確認は可能。
当時開発チームのリーダーをしていた私は、リプレイス担当者にHさんをアサインしました。
Hさんは綺麗なコードを書けてチームで最も優秀な開発者です。
ついでに若くて背が高くて明るく自信に満ち溢れ、私服がおしゃれでモデルのようなイケメンでした。
さらに非常に頭の回転が早く、こちらが半分ぐらい説明すると
説明の後半を推測して把握してしまいます。
その場の状況次第では話しかけようと彼の顔を見た瞬間に
「あの件ですね。それはもうやっておきました」などと返してくる超人です。
※実話です

修正後のクラスについて私とHさんの二人でペア設計をしました。
サンプルコードを書きつつ、相談して設計方針を決めました。
そして元のプロダクトコードは破棄して、テストクラスをパスするように
プログラムを作成し直してもらいました。
でき上がったコードは元のコードの半分以下のシンプルなクラスになりました。
各メソッドは適切に分割され、汎用的な機能はユーティリティに移動しました。

作り直した直後は数件のバグは出たものの、その後はバグもでなくなり、
要件の追加も円滑に行うことができるようになりました。

またバグが発生した場合も、コードが簡潔で各処理の依存度も低かったため
大抵5分から30分の間には解決していました。

なぜ汚いコードを書くのか?

  • 綺麗なコードの書き方がわからない

所属組織や技術系の友人の中に良い作法を知っている技術者がいればよいが、いないケースもある。
自ら学ぶことはしないため運よく教えてくれる人がいなければそういった作法を覚える機会がない。

  • 技術への情熱がない

プログラムはただ仕様通りに動けばいいと考えている。
自宅では一切プログラミングをしない。
業務外で学習もしない。
新卒後の研修やOJTで最低限身に付けた動くコードを書くだけのスキルレベルで一生停滞している。
それでもSIで多数の下請が参入する現場など開発の仕事は一定量あるため
仕事を失う恐れはあまりない。

  • 本当は学習したいが業務が激務過ぎる

本来は勉強するモチベーションを持つ人物でも過剰な稼働により学習意欲・体力を失ってしまう。

  • 技術の停滞と頑固さの強化

ベテランエンジニアで業務ドメインの知識や管理業務には強くなったが、
技術力や知識は昔のまま止まっているような人間も汚いソースコードを書くことがある。
自身の経験へのこだわりが強くプライドも高いため一般に良いとされている
最新の技術や作法に関して説明をしても受け入れてもらえない。

自身はコードを書かないがレビューや教育を行う立場にあり、
好ましくない古い作法を伝承してしまうケースもある。

この種の組織に所属してしまうと、業務で綺麗なコードを書くことは困難になり
間違った手法を常識として覚えてしまうため危険である。
教える方は善意から教えていますし、教えられる方は何が間違っているかまだ分からない上に、丁寧に教えてくれる上司を尊敬しています。

どうやって綺麗なコードを書くか?

  • とにかくコードを書く

野球の練習をしないプロ野球選手はいません。
医学の勉強をしないお医者さんはいません。
しかしプログラムを学ばないプログラマはなぜかたくさんいます。
よいプログラムを書くには、まずはたくさん練習する=コードを書く必要があります。

業務以外でコードを書く習慣をつける。(できれば毎日)
定期的にメンテナンスを行うプロダクトなり私的ツールがあると良い。
使い続けるプロダクトを持つことで綺麗なコードを書いて
保守性を高めるためのモチベーションが上がる。

  • 良書を読み、手を動かして身につける

良いコードを書く作法については様々な書籍がある。
最低一冊は通読し、実際にコードを書いて身に付けること。
コードを書く際は写経も良いが、自分で考えた仕様に基づいて
サンプルコードを作ってみるとより理解が深まる。
写経は「分かったつもり」になり、充実感を得るだけ得て終わるケースがある。
ただしコードを書かずに書籍を読むだけで済ませるよりは、写経をしたほうが良い。

前述した内容と重なるが私的プロダクト、ツールなどを持ち、それに対して実際に
良い作法を適用することで一つ一つ吸収していくと、実益も兼ね記憶への定着も強化する。

綺麗なコードを書くための個別のプラクティスのサンプルを作り、
技術ブログにまとめ上げていくのも良い。
技術についてまとめることは理解を深めることになる。
ブログにまとめておくと仕事中にWebから確認できるという利点もある。

  • 師匠を見つける

良い師匠を見つける。身近にいない場合は、勉強会を利用する。
どうしてもうまく見つからない場合や
一人で学習するほうがやりやすいなら書籍やWebから情報を得る。

  • 弟子を持つ

人に教えることは自分が深く理解してから説明する必要があるため良い学習機会となります。

  • オープンソースのコードを読む

業務で良いコードに出会えないならオープンソースのコードを読んでみる。
GitHubの登場以降、オープンコードを見るための敷居が下がった。

  • コードレビュー

所属組織内や友人に良いコードを書ける技術者がいるなら有効です。

  • ペアプログラミング

こちらも所属組織や参加する勉強会内に、良いコードを書ける技術者がいるなら有効です。
わざわざ勉強会に参加するぐらいなので、いい技術者はたくさんいるでしょう。

  • TDD、BDDを学ぶ

TDD、BDDを実践続けることで、テストしやすいコードを意識して記述するようになります。
結果として、実践前に比べて良いコードを書けるようになるでしょう。

  • オブジェクト指向エクササイズを実践する

タフでハードなプラクティスで縛りを加えてコードを書くことにより、
良いコードを書く作法を身に付ける。
詳細が気になる方は情報収集してみてください。

  • 各種解析ツールを利用する

言語ごとに様々なツールが存在します。

・コードの作法やバグを生む可能性のあるコードを抽出するツール
・規約のチェックを行うツール、  
・コードのメトリクス測定を行うツール、  
・コードフォーマッター  

など、種類は様々です。

有名どころとしてはJavaのFindBugsやCheckStyleやEclipseのコードフォーマッタなど。
RubyではRuboCopやmetric_fuなどがあります。

これらのツールは、良くない作法の検出や記法の統一を支援してくれます。

  • 転職をする

良いコードを書く習慣のある企業へ転職する。
そういった企業はオープンソースや企業のブログでアピールしていることが多く、
また所属社員が個人的にGitHub等でコードを公開していることも多いので
その辺を目安に情報収集を行う。
勉強会などで直接知り合いを作ってもいい。

複数の技術書でも言われていることですが
「一番の下手なメンバーでい続けること」
は自分の成長を促します。
すばらしい同僚と仕事をして、技術を吸収するのは良い選択肢です。

  • 可読性を重視した言語を選択する

これは短期的な解決策としては利用できませんが
長期的にはよい解決策になるでしょう。
可読性を重視した言語には、可読性を重視した開発者が集まることもあり
「外れのチームメイト」と仕事をする可能性も幾分か減るでしょう。

可読性を意識したプログラム言語

Ruby

Rubyはまつもとゆきひろ氏作の日本発のオブジェクト指向言語です。
Rubyは

  • 適切に命名された標準ライブラリ
  • 豊富なシンタックスシュガー
  • 全てがオブジェクト
  • 標準ライブラリを拡張することが可能

などの特徴により、人が理解しやすいコードを短いコード量で記述することができます。

また、強力な動的機能によりメタプログラミングと相性がよく
特定ドメインに特化したDSLを作るのに向いています。

Rubyを利用していると、

こんな名前の機能があるといいな

という名前のメソッドを試しに実行してみると
本当にメソッドが存在して想定通りの動作をすることが多々あります。

静的な言語では行うことができないようなクラス、メソッド定義レベルの大胆な共通化も可能です。
そのような手法を極限まで利用したのがRuby on Railsであり、Rubyの人気の火付け役となりました。

そういった言語特性から、

Martin Fowler氏
Dave Thomas氏
Andy Hunt氏
Chad Fowler氏
DHH氏

など著名な開発者がRubyを好んで利用しています。

近年重要性を増してきているDSLの記述にもRubyは適しています。
これも強力な動的機能と言語自体の持つ可読性の高さや柔軟な文法によるものと考えられます。

  • DevOpsを盛り上げている、ChefやVagrant
  • デプロイの自動化ツールのcapistrano
  • ビルドツールのRake(その他の用途にも使えますが)

など、どのプロダクトもRubyによるDSLの記述を有効活用し、
実際に中で行っている複雑な処理を隠蔽しつつ、ユーザーにやさしい形式で
インターフェースを提供します。

また、Rubyの内部DSLはただのRubyのコードに過ぎないため
DSLの中にRubyのロジックを用いて、共通化やループなどを記述することができます。

CoffeeScript

CoffeeScriptはRuby, Python等から良いところを集めて作られたJavaScriptの代替言語です。
JavaScriptはAjaxの普及などもあり、その需要が高まってきています。
しかし、JavaScript自体は綺麗に書くのが難しい言語としても有名です。
そこでCoffeeScriptの登場です。

CoffeeScriptによるコード量はJavaScriptの1/3程度になるとも言われます。
またコンパイル結果は整形されたJavaScriptとして出力されるため、
CoffeeScript導入前のシステムとの互換性を気にする必要もありません。
JavaScriptの各種ライブラリもそのまま利用できます。

習熟に必要なコストも低いとされ、JavaScriptを知っていれば特に問題なく習得でき、さらにRubyかPythonに慣れ親しんでいればより容易になります。

Elixir

人々が扱うデータの肥大化、マルチコアCPUの発達などの要因により
関数型言語が注目を集めています。
関数型言語はImmutableで状態を持たないため、並列処理と相性が良いためです。
様々な関数型言語がありますが、その中でもErlangベースの関数型言語Elixirは
Rubyライクな人間に優しい文法、強力な動的機能をその特徴として挙げています。

まとめ

  • 汚いコードのもたらす技術的負債
  • 綺麗なコードを書くための方法
  • 可読性に配慮した言語

について触れてきました。

プログラマは綺麗なコードを書くスキルを持つべきですし、
企業は本来そのような開発者を優先して採用すべきです。
しかし従来の履歴書+職務経歴書と面接が主の採用では本当に技術力があり
綺麗なコードを書ける技術者を採用することは難しいです。

CodeIQの出題をはじめてから執筆時点で約50名の採点を行ってきましたが、
SIの下請け現場で見るような汚いコードを書く解答者は一人もいませんでした。
実際の現場で綺麗なコードを書ける開発者に遭遇する確率が1/10程度であることと
比較すると大きな差があります。

できる開発者は知的好奇心旺盛であり、業務時間外にCodeIQで問題を解いたり
趣味の開発や、オープンソースプロジェクトに貢献したりしているのでしょう。

ちなみに「綺麗なコード VS 汚いコード」で紹介したHさんは
当時のチームで私を除き、業務外でプログラミングを行っている
たった2人の内の1人であったことを付け加えておきます。

草野球の選手とプロ野球の選手が、野球を知らないスカウト担当者にスカウトされて
書類審査と面接だけで一切プレーを見ずに同じ年俸で契約する。

そんなおかしな事態がずっと続いていたのが日本のシステム開発の現場ではないでしょうか。

ここにきてCodeIQや各企業のコーディング採用など技術力による
評価が見直されてきているのはとてもよい流れだと思います。
ちなみに私も、ペア・プログラミングで即興の課題をこなす、
という採用試験にて今の会社に入社しました。
(TwitterAPIを利用したちょっとしたJavaアプリケーションを数時間のペアプロで
仕様と設計を相談しながら作りました)

CodeIQに参加しておられる解答者の皆さんは技術力重視の採用や評価という
システム開発の本来あるべき姿への大きな流れを作っている一人として
重要な役割を担っているのではないでしょうか。

参考文献

Ruby公式サイト
CoffeeScript公式サイト
Elixir公式サイト

CodeIQ運営事務局より

CodeIQではスキルチェックにぴったりの実力判定問題を出題中!
ぜひ挑戦してみてくださいね!

  • 153
  • このエントリーをはてなブックマークに追加

■関連記事

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

CodeIQ(コードアイキュー)とは、自分の実力を知りたいITエンジニア向けの、実務スキル評価サービスです。

CodeIQご利用にあたって
関連サイト
codeiq

リクルートグループサイトへ