孤独プログラマー譚

孤独死が近い。

Ruby 元のクラスを触らずに機能を拡張する

機能を追加することになった。
だが、元のクラスは触りたくない。
だってバグりそうだから。前のテストのやり直しをさせらせるかもしれない…。

自分の身を守るためにも、安全に機能を拡張する方法をまとめる。


以下クラスを拡張する。
フルネーム「白石麻衣」と表示出来れば、OK。

class Family
  def name
    '白石'
  end
end

1.継承する

定番。ぱっと見、分かりやすい。
インスタンス変数に依存した実装になりやすい。副作用大。

class Full < Family
  def name
    super + '麻衣'
  end
end

full = Full.new
p full.name # 白石麻衣

2.委譲する

委譲先から委譲元のインスタンス変数を触れないので、疎結合。良い。

class Full
  def name
    family = Family.new
    family.name + '麻衣'
  end
end

full = Full.new
p full.name # 白石麻衣

3.特異メソッドを定義

インスタンスにメソッドを定義する。

family = Family.new
def family.full_name
  name + '麻衣'
end
p family.full_name # 白石麻衣

4.モジュールをextend

インスタンスにモジュールをミックスインする。

module Full
  def full_name
    name + '麻衣'
  end
end

family = Family.new
family.extend Full
p family.full_name # 白石麻衣

5.Decoratorパターン

委譲の発展版。
インスタンス変数を内側・外側で、それぞれどう持ち回すかは謎。工夫が必要っぽい。

class Full
  def initialize(family)
    @family = family
  end
  def name
    @family.name + '麻衣'
  end
end

full = Full.new(Family.new)
p full.name # 白石麻衣


うーん、前任者のコードを触りたくない…。