This page looks best with JavaScript enabled

『オブジェクト志向設計実践ガイド』2章

 ·   ·  ☕ 3 分で読めます

自転車の画像を見ながら読むことをおすすめする。

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クラス

よくわからんので割愛。
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でカスタムエラーを返すのもありか??
少なくともそのままだとわかりづらいので。

Share on

aiandrox
Written by
aiandrox
今日も楽しく明日も楽しく

目次