yumeの日記: C#学習 13 Console Adventure#4 3
コメントありがとうございます。頭痛で変な時間に寝起きしてしまった。
前回より:
クラスの考え方を読み、プログラム全体の大まかな処理の流れを再考する。
現在の流れは:
・txtファイルを読み込む。改行で区切り、string配列 bodyTextにする。
・bodyTextの各要素を読み取り、
>それが命令なら、命令を実行する
>インライン命令があるなら、インライン命令を実行し、テキストを出力する
>そのどちらでもないなら、ただテキストを出力する
これは料理の工程に例えれば、切る、煮る、焼くそれぞれの工程担当者が、提供まで兼任しているような状態かもしれない。
まぁ別に動いているので今のところ問題はないのだが、これが仮に
「提供の段階で必ず水を追加する」とかそういう処理を入れると、面倒なことになるのかな。
例えば以下のような構造にすることが考えられる。というかそうした。
SelectAdventureクラス
・Main関数を動かす。Main関数はタイトル画面などを呼び出す(予定)。
・GameRunnerクラスをもとにした「myGame」インスタンスを持つ。
GameRunnerクラス
・PageGeneratorクラスをもとにしたインスタンス「myPageGen」を持つ。
・myPageGenが持っている、整形されたテキストをコンソールに表示する。
・プレイヤーの入力を受け取る。
・次に整形が必要なテキストページ番号をmyPageGenに知らせて、新たなテキストを生成させる。
PageGeneratorクラス
・テキストファイルから生成したページテキスト「myText」を持つ。
・命令されたら、テキストファイルを読み出し、string配列「myText」を作る・更新する。
・string中にある命令文を読み、命令文に応じてテキストを整形する(名前を置き換えたり、改行を追加したり)
……ということをやっているうちに、なんとなく「クラス」「インスタンス」「static」の概要がつかめてきたかもしれない。
初めのうちは、次のようなところでひっかかった(ひっかかり方が意味不明かもしれない)。
・staticじゃないと、クラス間でメソッドが呼び出せないじゃないか
・インスタン生成すればいい? でもメソッドを呼び出すたびにインスタンスを作っていてはかなわん
・というかそもそも、staticの使い分けはどうすべきなんだろう
・GameRunnerをインスタンス化して、myTextを持たせたはいいが、myTextをPageGeneratorに渡す方法がわからん
・refで変数を参照しまくればいけるか、でもなんか怖いコードな気がする
などなど。この辺りはそもそも、クラスやインスタンスの使い方がおかしいことから生じる混乱だったと思う。そもそもそういう概念無で作ったプログラムだったのもあるか。
ぼんやりとわかってきたこと:
・staticは「クラスのもの」
・staticでないものは「インスタンスのもの」
・インスタンスの変数をいじるなら「インスタンス.変数」を触る。
・変数に触れるかどうかはアクセス修飾子で決まる。
>基本的には触れない方向で決めておいて、触る必要が出てきたら考える、という手順。
・(当たり前だが)クラスが受け持つ変数は、そのクラスが受け持つべきかどうかをちゃんと考える。
>今回の場合、GameRunnerは(ほぼ)テキストを読むだけのクラスなので、myTextを持つのはmyTextをいじるPageGeneratorの方がよい。
・今回はstaticなメソッドをほぼ使ってない(GameEndだけ)。static変数も使ってない。
>やっぱり使い分けできてるか怪しい。メソッドはほとんどstaticでもいいんじゃないか?
>「ここはインスタンスメソッド! ここはstatic!」みたいに意識をもって決めてない。
>次新たにメソッドを作るとしたらどうしようか。インスタンス変数をいじるときはstaticではダメなのかな。というくらいぼんやりしている。
参照したドキュメント:公式、++C++;、dobon.net、なんかの掲示板、ほかいろいろ。
いじったはいいものの、全体のコードを見るとやはり何かちょっと怪しい臭いがする……気のせいかもしれないけど。
そもそもGameRunnerをインスタンス化している意味があるのか。
でもちゃんと動くようなのでいったんよしとする。
ストーリーテキストを少し追加・修正(語り手の人称統一とかいろいろ)。
どっちかというと (スコア:0)
普通のクラスの場合、ほとんどは非staticメソッドになると思います。
「あるもののデータ」と「それの動作/それに対する操作」をまとめたものがクラスというイメージですので、「あるもののデータ(=インスタンス変数)」を触らないのであればそのメソッドがクラスに属する理由があまりないことになるので。
> インスタンス変数をいじるときはstaticではダメ
この認識でよいかと思います。
すると大体非staticになるかと
下回り(なんかの計算とか)関数はインスタンス変数使わない(static)こともあると思いますが
イメージ的にはmain関数はすべてを代表するアプリケーションクラス、今回だとSelectAdventureですかね、のインスタンスを作成してstartを呼ぶだけ、ってな感じになります。
クラス名に***erが多いのは非常によくわかりますが、
クラスは「もの」で名詞、メソッドは「やること」で動詞になるのがそれっぽいつくりとなります。
SelectAdventureクラス -> Application
GameRunnerクラス -> Game
PageGeneratorクラス -> Scene
みたいな名前のほうが「それっぽい」
Re: (スコア:0)
> クラスは「もの」で名詞、
クラスは「型」で
インスタンスが「もの(=オブジェクト)」だと思います
逆に考えよう (スコア:0)
逆に考えましょう。インスタンス化しないで使えるようにすることに意味があるのか、ってね。static変数なんてグローバル変数みたいなもの。別に何とかなるんだろうけど、ライフサイクルが分かりにくいし、スコープが広いから、間違えやすく、間違えても見つけづらい。