自転車の画像を見ながら読むことをおすすめする。
2章
コードの理想形
- 見通しが良い(Transparent)
- 変更するコードにおいても、そのコードに依存する別の場所のコードにおいても、変更がもたらす影響が明白である
- 合理的(Reasonable)
- どんな変更であっても、かかるコストは変更がもたらす利益にふさわしい
- 利用性が高い(Usable)
- 新しい環境、予期していなかった環境でも再利用できる
- 模範的(Exemplary)
- コードに変更を加える人が、上記の品質を自然と保つようなコードになっている
単一責任の法則(SRP)
責任駆動開発(RDD)に由来する。
凝集度(ぎょうしゅうど)
クラス内のすべてがそのクラスの中心的な目的に関連している→凝集度が高い
=単一責任である
good!!
- クラスに「あなたの〇〇を教えて下さい」と聞くことに違和感がないか
- 〇〇はメソッド
- ギアのクラスなのにタイヤが絡んだらだめー。
- 1文でクラスを説明できるか
- そのメソッド、本当にそのクラスについてのことなの??
カプセル化
値はアクセサメソッドで包み、直接参照しないようにする。
1
2
3
4
5
6
7
8
|
def initialize(chainring, cog)
@chainring = chairning
@cog = cog
end
def ratio
@chainring / @cog.to_f
end
|
もし@cog
を示す値が変わったとき、setterでしか変更できないので、一つ一つ変更する必要がある><
なのでcog
を使うことで、メソッドで値を管理するようにする。
データに直接アクセスせず、送信メッセージ(メソッド呼び出し・引数)の戻り値としてアクセスする。
Structクラス
よくわからんので割愛。
(追記)8章でわかった。
class Struct (Ruby 2.7.0 リファレンスマニュアル)
コード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
class Gear
attr_reader :chainring, :cog, :wheel
# chainring チェーンリング ペダルの根本がつながっているところ。一回転の歯数
# cog コグ 後輪を動かすやつ。一回転の歯数
def initialize(chainring, cog, wheel=nil)
@chainring = chairning
@cog = cog
@wheel = wheel
end
def ratio # ギア比。ペダルを一周漕ぐと○回転する
# ペダル1回転に対する進み具合
# ちなみにこれが大きいほど漕ぐ力が大きくなる
chainring / cog.to_f
end
def gear_inches # 車輪の大きさも加味した、ペダル一回転に対する進み具合?
ratio * wheel.diameter
end
end
class Wheel # タイヤ全体
attr_reader :rim, :tire
# rim リム 枠のホイール部分
# tire タイヤ タイヤ部分の厚み
# どちらも単位はインチ
def initialize(rim, tire)
@rim = rim
@tire = tire
end
def diameter # 車輪の直径を計算する
rim + (tire * 2)
end
def circumference # 円周
diameter * Math::PI
end
end
|
Math::PI (Ruby 2.7.0 リファレンスマニュアル)
1
2
3
4
5
6
7
8
9
10
|
irb(main):002:0> wheel = Wheel.new(26, 1.5)
irb(main):003:0> wheel
=> #<Wheel:0x00007ffcb4b72308 @rim=26, @tire=1.5>
irb(main):004:0> gear = Gear.new(52,11,wheel)
irb(main):005:0> gear
=> #<Gear:0x00007ffcb4bd9b48 @chainring=52, @cog=11, @wheel=#<Wheel:0x00007ffcb4aee120 @rim=26, @tire=1.5>>
irb(main):006:0> gear.ratio
=> 4.7272727272727275
irb(main):008:0> Gear.new(52, 11).ratio
=> 4.7272727272727275
|
エラーになるくね?
1
2
3
4
5
6
7
8
9
|
irb(main):002:0> Gear.new(52, 11).gear_inches
Traceback (most recent call last):
6: from /Users/k_end/.anyenv/envs/rbenv/versions/2.7.1/bin/irb:23:in `<main>'
5: from /Users/k_end/.anyenv/envs/rbenv/versions/2.7.1/bin/irb:23:in `load'
4: from /Users/k_end/.anyenv/envs/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
3: from (irb):2
2: from /Users/k_end/study/object_orientation/2_gear.rb:14:in `gear_inches'
1: from /Users/k_end/study/object_orientation/2_gear.rb:14:in `*'
TypeError (nil can't be coerced into Float)
|
1
2
3
|
def gear_inches
ratio * wheel.diameter
end
|
wheel = nilのときエラーになる
return nil unless wheel
とか入れたほうがいい気がするけど、Integerを返す前提ならraise
でカスタムエラーを返すのもありか??
少なくともそのままだとわかりづらいので。
記憶によるとこれは勘違い。