LoginSignup
0
0

More than 1 year has passed since last update.

クラス継承 オブエジェクト指向設計実践ガイドより

Last updated at Posted at 2021-06-15

はじめに

本題はここクラス継承からです

読者対象

読者対象はプログラミング初学者です。
といっても全くの初学者ではなく、Railsチュートリアルを終えたレベルと定義します。

オブジェクト指向設計実践ガイド

オブエジェクト指向設計実践ガイドの記事は、他の方も書いてありますが、
一度に全部まとめたものが多かったです。
この記事は、オブエジェクト指向らしく、各章ごとに、単一責任に、シンプルさを意識して書きました。
余談ですが、とある弁護士が弁護士は六法全書を丸暗記してないが、各条文を見ただけで、関係ある条文、知識を思い出すそうです。
この記事は、オブジェクト指向設計実践ガイドってこんなこと書いてあったなーと思いだすための記事でもあります。
また、オブエジェクト指向設計実践ガイドを読んだことがなくても、こういうことが書いてあるとのかー、とさわりだけでも理解して頂けたら幸いです。

オブジェクト指向設計実践ガイドで得た3つのポイント

リファクタリング前のコードを読み、コードの危うさを察知できる。
リファクタリングするために、より抽象的なコードの書き方を学べる。
gemなどの抽象的なコードを読解できる。

一問一答

一問一答風の構成にしています。
リファクタリング前のコードを読み、コードの危うさ、嗅覚を養っていきましょう。
その後、リファクタリング前のコードの危うさを説明し、自分なりにリファクタリングしたコードを書いてみましょう。
最後に、もう一度、リファクタリング前のコードと、リファクタリング後のコードを読み比べ、
抽象的な思考、抽象的な書き方を共に学んでいきましょう。

クラス継承

今回は第6章クラスによる継承について説明します。
下記コードを読んで、このコードの危うさを考え説明して見て下さい。
そして、自分なりにリファクタリングしたコードを書いてみましょう。
この記事を理解したなら、オブエジェクト指向設計実践ガイドの第6章 「継承によって振る舞いを獲得する」、
この章を半分理解していると言えるでしょう。(残りは後日書きます)

リファクタリング前

class Bicycle
  attr_reader :style,:size,:tape_color,:front_shock,:rear_shock

  def initialize(args)
    @style = args[:style]
    @size = args[:size]
    @tape_color = args[:tape_color]
    @front_shock = args[:front_shock]
    @rear_shock = args[:rear_shock]
  end

  def spares
    if style == :road
      {
        chain: "10-speed",
        tire_size: "23",
        tape_color: tape_color
      }
    else
      {
        chain: "10-speed",
        tire_size: "2.1",
        rear_shock: rear_shock
      }
    end
  end
end
bike = Bicycle.new(
  style: :mountain,
  size: "s",
  front_shock: "Manitou",
  rear_shock: "Fox"
)
bike.spares

コードの危険性

Bicycleクラスが肥大している。
特に、機能が拡張するたびに、sparesメソッド内のif文を修正しないといけない。←バグのもと

リファクタリング後

class Bicycle
  attr_reader :size
  def initialize(args = {})
    @size = args[:size]
  end
end
class RoadBike < Bicycle
  attr_reader :tape_color

  def initialize(args)
    @tape_color = args[:tape_color]
    super(args)
  end

  def spares
    {
      chain: "10-speed",
      tire_size: "23",
      tape_color: tape_color
    }
  end
end
class MountainBike < Bicycle
  attr_reader :front_shock,:rear_shock

  def initialize(args)
    @front_shock = args[:front_shock]
    @rear_shock = args[:rear_shock]
    super(args)
  end

  def spares
    super.merge(rear_shock: rear_shock)
  end
end
road_bike = RoadBike.new(
  size: "M",
  tape_color: "red"
)
road_bike.spares
mountain_bike = MountainBike.new(
  size: "s",
  front_shock: "Manitou",
  rear_shock: "Fox"
)
mountain_bike.size

クラスの継承

Bicycleクラスの下に、新たにサブクラスを設置することによって、
Bicycleクラスがすっきりしました!

注意点

このリファクタリング後のコードがベストではありません。
より改善できます。サブクラスを設置しない方法もあります。
あくまでリファクタリング前よりかはよくなったと捉えて下さい。

後記

コードの危険性の説明を加筆しようか検討中

参考文献

オブエジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0