20201011_アウトプット(オブジェクト指向)
学んだこと
オブジェクト指向を踏まえたクラスの扱いについて
クラスに含まれる値や処理のまとまり(=オブジェクト)を意識しながら、実装することを「オブジェクト指向」という。あくまで設計思想の1つなので「これ」という一つの正解はない。実装のしやすさ・改変のしやすさを考えて意識して設計していくことが大事。
反対に、オブジェクト指向を意識しないがために分かりづらいコードのことを「スパゲッティコード」という。
●オブジェクト内に様々な役割が入り組んでいて、どこに何があるのかわからない。
●1つの機能を変えた途端、その変更とは関係ないはずの機能が動かなくなる。
というような問題がある。単一責任の原則とは、それぞれのクラスに明確な役割が1つだけ与えられることを指す。 (例えば、自動販売機のマシーンを作るのであれば、①販売する飲み物の種類のクラス、②自販機のクラス、③購入する人のクラス、④スロットマシーンのクラスといったように分ける。)
メソッド | 役割 | 備考 |
---|---|---|
ゲッター | ローカル変数を他のクラスでも使えるようにインスタンス変数として定義する時に使う | イニシャライズメソッドの下に続けて書くことが多い |
セッター | ゲッターで定義したインスタンス変数の中身の値をを更新する時に使う | 「def インスタンス変数名=」となる(=が名前に含まれているのがポイント) |
自分なりの覚え方:他のクラスでも受け取れるようにするのがゲッター、それをセットし直すのがセッター
なるほどと思ったこと
書き換えられたくない時に、プライベートメソッドに書くのかなと思ったけれど、プライベートメソッドは「いよいよデータベースにインスタンス変数の中身を保存するよ、内容を確定させるよ」の意味合いが強いことをメンターさんに学ぶ。
なので、インスタンス変数の中身を書き換えられたくないときは、プライベートメソッドに書くというよりも、ローカル変数のままにしたり、フリーズさせたりする方が適している。(もちろん、更新の意味を持つセッターは使わないことになる。)
全体の理解として、
●インスタンス変数とは‥戻り値に個性があること(色・重さ)
●クラス変数とは‥戻り値がクラス全体の共通事項であること(乗る・走る)
それを踏まえて、
●他のクラスでもインスタンス変数を使いたい場合にはゲッターを設ける
●ゲッターのインスタンス変数を更新したい場合にはセッターを設ける
●インスタンス変数の戻り値の結果を使って、クラス全体の振る舞いを定義したい時は、selfをつけたクラスメソッドを使う(赤い車に乗る)
●インスタンス変数の戻り値を使わない場合や、そのメソッド内でしか使わない場合はローカル変数を使う
と頭の中を整理できた。
読み込む時に使う「require」について
読み込み方について頭を整理できていなかったため、まとめる。
# その1:ライブラリを読み込む時👉ライブラリ名だけでOK! require 'ライブラリ名'
# その2:自作のRubyファイルを読み込む時👉ファイルまでの相対パスが必要! # 補足:「./」はカレントディレクトリを示している。 require './slot_game.rb' # 拡張子は省略可能 require './slot_game'
★requireは、Rubyを実行しているディレクトリがパスの起点になる。
その他(load)
読み込むメソッドには「require」の他に「load」もある。
違いは、
①読み込むファイル元に変更があった場合に、それが反映されること。(反対に言えば、requireの場合には、1回しか読み込まない。)
②その分、読み込みに時間はかかる。
③拡張子は省略できない。
load './slot_game.rb'
その他(require_relative)
★require_relativeは、自分のファイルが存在する(呼び出したい側の)ディレクトリが起点となり、探したいファイルを指定しにいく。
「==」と「&&」について
if result[0] == result[1] && result[0] == result[2]
- 「==」と「&&」を組み合わせて、a=b 、a=c、つまりb=cという状況を作り出しているのが上記コードとなる。(3つ以上のものが等しいか見る時に使える。)
積み残し(復習したいところ)
devise rollback方法
カラム追加の方法
Rails勉強会
感想
プログラミング勉強を初めて約2ヶ月が経ったが、パズルに例えると全体像(Rubyの大枠)ついては理解が深まった。
まだまだ足りないところとしては「どこまで分解していけばメソッド等を作れるか」と細かいピースの組み合わせを想像できるレベルには到達していないということ。
例えば、今回の課題図書で、「スロットを作ろう」というのがあった。なんとなく配列を使いそうだなと想像したものの、細かく分解する工程が浮かばなかった。
上記回答例としては、①配列という箱を作る。②timeメソッドとrandメソッドを使いその箱に3回のランダムな数字をいれる。③その配列の箱に入れた数字を横並びにするためにjoinメソッドを使う。④if文を使い一致しているか否かでメッセージを設定するといった工程に分解してコードを書いた。
def play_slot result = [] 3.times do result << rand(0..9) end puts "スロットゲームの結果は#{result.join}です!" if result[0] == result[1] && result[0] == result[2] puts "おめでとうございます!" else puts "残念でした〜" end end
- 細かいピースの組み合わせを浮かぶようにするために「抽象化⇆具体化」の視点を意識しながら学ぶ。