リーダブルコーザ あとがき

総コンAdvent Calendar 1日目です。
トップバッター&言い出しっぺとして責任は重いなあ…というわけで当日に頑張って書いてます。

今回は私が所属する総コンというサークルで開催した リーダブルコーザ という講座のお話です。
この講座を開催するにあたってどういう目標を持ってどういう構成で開いたのかということと、自分なりにリーダブルに書くTipsをまとめて、最後に反省点を洗い出してみます。 また講座の中で深く触れなかったことについても掘り下げます。

リーダブルコードについて

リーダブルコードとは読みやすいソースコードのことで、オライリーの「リーダブルコード」は相当売れた技術書の一つです。
この本はコードをいかに読みやすくするかという方法がひたすら論述されています。 私はHICHAINの開発をしたり、誰かのコードを読んだり、グループワークをする上で、可読性、拡張性の高いコードがいかに開発効率を高められるか実感しました。
この感動を分かち合いたいのでこの講座を開いたというわけです。このように毎回私は定期的になにかブームが来て布教したいという一心で講座を開いています。

講座の目標

  • 可読性を高める
  • 拡張性を高める

全学年を対象としたかったので、3回に分けて全学年向けと2年生以上向けx2に分けました。
1年生はまだクラスを習っていなかったので、初回はクラスを使わず可読性を高めることを重視しました。

講座の構成

  • アンリーダブルなババ抜きを可読性・拡張性を高めていき、それを元に大富豪を作る

扱うゲームはそれを元に別のゲームに派生できてルールが簡単なババ抜きにしました。

  • 言語: Processing

授業で学ぶ言語なのでこれにしました。

  • 初級編 (全学年向け)
    • アンリーダブルなババ抜きのコードを読みやすい書き方を教わりつつ綺麗にする
  • 中級編 (2年生以上向け)
    • 初級編で綺麗にしたコードを、クラスを取り入れてより可読性、拡張性を高める
    • オブジェクト指向を意識したコードを目指す
  • 上級編 (2年生以上向け)
    • リーダブルババ抜きを元にリーダブル大富豪を作る
    • いくつか条件を指定して各自大富豪を作ってもらう

また参考にしたかったので普段みんなが書いているコードを集めました。

初級編 概要

スライド

友人に汚いババ抜きのコードを書いてもらいました。
最初にアンリーダブルババ抜きを配布し、可読性を高める方法を学んだ後、各自コードの掃除をするという感じです。

掃除の工程は5段階に分けて、自分で掃除したコードをサンプルとして載せました。
インデントやスペースを空けるなど表面上の改善をしたコードから始めることにしました。

名前付けTips

個人的に心がけていることをまとめました

  • 表記を統一する
    • discard = throw, select = chooseなど
  • 番号 = number, 数 = count と使い分ける
    • 本来どちらもnumber
  • あえて冗長に名前付けする
    • hand = 手札だがhandCardとしてカードであることを示唆する
  • 単語の重複を避ける
    • drawは「描く」意味で使用しているのでカードを引く意味の「draw」は使わない
  • 意味の多い単語は避ける (take, makeなど)
  • やけに単語を省略しない
    • image = imgは多用されているのでよいが、player = pはやりすぎ

ProcessingのIDEは貧弱なのであまり当てはまりませんが、長い名前が悪という訳ではありません。
だいたいのIDEは補完機能が優れているので、意味を理解する上で必要なら長くても問題ないと思います。

ゲームに限ったコーディング方針

ゲームは複雑なものでもルールを分解して体系化できます。

  • 構成要素
  • 初期状態
  • ターンあたりの行動
  • 終了条件
  • 勝利条件

構成要素とは例えばババ抜きならトランプ、プレイヤー(手札)、捨て場のことです。
トランプは53枚使用し、ハートやダイヤなどのマークと、A~Kの数字、そして表裏の画像で構成されています。
このようにゲームで使われているものを列挙して各要素に分解することが、後々クラスわけをするときに役立ちます。
コードを書きながら分解するより、最初に分解しておくことが理想です。

初期状態とはゲームを開始する前の状態のことです。 終了条件と勝利条件は混同しやすいですが、必ず終了条件の後に勝利条件を判定します。
ババ抜きではプレイヤーの1人を除いた全員の手札がなくなることでゲームが終了し、手札にジョーカーがないプレイヤーが勝利します。 ゲーム中のフェーズを明確に分けることも必要です。

アルゴリズム問題

ゲームを作る上で切っても切り離せないのがアルゴリズムです。
ババ抜きではトランプをシャッフルしてプレイヤーに配るときや、ペアを捨てるときに当たります。

例えばアンリーダブルババ抜きではトランプを配分するときこうやってました。

  1. 配るプレイヤーを選ぶ
  2. カードをランダムに1枚選ぶ (ジョーカー以外)
  3. そのカードをそのプレイヤーに既に配ってなければ配る
  4. 次に配るプレイヤーを選ぶ
  5. 2~4を全て配り終わるまで繰り返す
  6. ジョーカーをどちらかのプレイヤーに配る

私はこうやります。

  1. 全てのカードをシャッフルする
  2. 交互にプレイヤーに配る

明らかに工程が減り単純になりました。しかし後者のアルゴリズムは現実でする行動を書いただけのことです。

後者の工程1ではJavaCollections.shuffle(array) を使いました。
これはこういうメソッドがあるということを知らなければ使えませんが、別に一から実装しても問題ありません。
一行で済まそうが数行使おうが、カードをシャッフルすると一言コメントを書いてあれば理解する上で同じです。
「こういう便利なメソッドがありそうだな」と気づくこともリーダブルにする第一歩だと思います。

現実の行動に即したアルゴリズムは直感的で分かりやすくなります。
効率がいいアルゴリズム = よいアルゴリズムという訳でもありません。
アルゴリズムの効率と可読性はトレードオフになることがあるので、そこまで速度を必要としない場合は可読性を取ってもいいと思います。

また読者がアルゴリズムを理解できなくても、何をやっているかが分かれば中身を見る必要がありません。
アルゴリズムの全てをコメントで解説することはしばし冗長になります。深い部分は読まないことも時には必要です。

初級編 反省点

  • コードを解読する段階が最も難しかった
    • アンリーダブルババ抜きが予想以上にアンリーダブルだった
    • 講座の本質ではない部分に時間がかかってしまった

中級編 概要

スライド

初級編である程度リーダブルにしたババ抜きを、クラスを用いて拡張性の向上を図ります。
クラスを使わない掃除では多くのグローバル変数が残り、箱に詰めただけの状態です。

まず先ほどの構成要素を元に一からクラス構築し、それに初級編で掃除したコードを入れていきます。

中級編 反省点

  • 準備不足
  • 課題が重い
  • 受講者1人
    • 夏休み中の開催は人が来なかった

上級編 概要

ババ抜きを元にリーダブル大富豪を作ります。コードの結合性を下げることで再利用が可能になります。
上級編はまだ開講していないので、今回はここまでです。

今後の予定

初級編からもう1度開催する予定です。
ただ人のコードを読む工程で苦戦するので、もっと簡単なゲームにするなど何か対策する必要がありそうです。

おまけ

今回スライドの作成に Reveal.js というフレームワークを用いて公開にはGitHub Pagesを利用しました。
一度環境構築をしてしまえば、Markdownでスライドが作れるので非常に便利です。
またCSSでデザインをいじれるのでカスタマイズ性に優れています。

参考文献

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

良いコードを書く技術 ?読みやすく保守しやすいプログラミング作法 (WEB+DB PRESS plus)

良いコードを書く技術 ?読みやすく保守しやすいプログラミング作法 (WEB+DB PRESS plus)