すごろくゲームのクラス設計について
「完成した!」といいつつ、ここ最近はすごろくゲームのリファクタリングをちまちまと繰り返しています。
変数名やメソッド名なんかのわかりやすいところを直しただけでも、ソースコードが読みやすくなった気がして、けっこう楽しいです。
ですがそんな中で、どのように直したらよいかわからないものもあり、悩んでいたりもします。
それが「すごろくゲームのクラス設計」です。
私の作ったすごろくゲームは、4つのクラスで動作しています。
それが「プレイヤークラス」、「サイコロクラス」、「ランキングクラス」、「すごろくクラス」です
それぞれの役割は以下の通りです。
プレイヤークラス
- プレイヤー情報の保持(名前、現在地、ゴールしたかどうか等)
サイコロクラス
- initializeメソッドでサイコロの面数を設定
- サイコロを振ってランダムに数字を出す
ランキングクラス
- ゴールしたプレイヤーのランキング算出
- プレイ中のプレイヤーのランキング算出
- ランキングの表示
すごろくクラス
- サイコロクラスのインスタンス保持(6面ダイス)
- プレイヤー数のカウント
- プレイヤー名の登録
- すごろくのプレイ(サイコロを振って、駒を進める)
- 各プレイヤーがゴールしたかの判定
- ゴールしたプレイヤーとゴールしていないプレイヤーを分ける
- 全員がゴールしたかの判定
このように、すごろくクラスの役割だけ、ものすごく多いです。
これを適切なクラスに分けられないものかと、最近は頭を悩ませております。
名は体を表すと言いますか、すごろくクラスはその名前がアプリ全体を表せるような名前になってしまったがゆえに、必要な処理を全部突っ込んでしまった感があります。
クラスの命名がよくないと、後から見たとき何のクラスかわかりにくいだけでなく、そもそもクラス設計がうまくいかないということなのかなと思います。
作成中はどんな処理が必要なのかを全部見通せていたわけではないので、なんでも突っ込めるクラスを作ってしまったとも言えるかもしれません。
名前が悪いから設計が悪いのか、設計が悪いから名前が悪いのか……どちらにせよ問題ですね。
では改めて、すごろくクラスが持っている処理を整理し、どのように分ければよいかを考えてみようと思います。
すごろくクラスは、以下のように実装されています。
お見せするのも恥ずかしいくらい、色々な処理が乱雑に収められています。
ここから私なりに、このクラスの何が悪いのかを考えてみたところ、以下のような結論が出ました。
- 処理が意味のある単位でまとめられていない。
- プレイヤークラスのインスタンス変数を直接いじってしまっている。
1番目は何度も言ったとおり、 必要な処理をすべて突っ込んでしまったため、何のクラスかよくわからないという点です。
player_countメソッドとentryメソッドは意味的にまとめてしまっても良さそうですが、playメソッドは分けてもいいのではないかなーという気がします。
check_each_players_finishedメソッド、screening_finished_playersメソッド、everybody_finished?メソッドなんかも、終了判定として意味的にまとめられそうですね。
これらの処理を新規のクラスにまとめるか、既存のクラスの何処かに入れ込むのは、ちょっと悩みどころです。
ただすごろく程度の単純なゲームの単純な処理を、あまり細分化しすぎてもそれはそれで読みにくいのかなーとかも思ってしまったりします。
2番目については、何やってるかわからないクラスでプレイヤーのインスタンス変数をいじるのはよろしくないかなーという気がしたので挙げてみました。
プレイヤーのインスタンス変数をプレイヤー以外のクラスでいじるなら、それ専用のクラスがあってもいい気がします。
……などと改善点を挙げてみたものの、基本的に独学なので、有識者にレビューしてもらえないのがつらいところですね。
自分なりに考えながら改善するのは楽しいのですが、正しい改善点に気付けてなさそうなのが気になるところです。
あまりはっきりとした結論が出せてない……。
とにかくすごろくクラスの雑多さは多分あまりいい設計ではなさそうなので、なんとかかんとか良い設計を目指したいものです。
一時停止していたデザインパターンの勉強を再開してもいいかなあ……。