#はじめに
本題はここクラス継承からです
##読者対象
読者対象はプログラミング初学者です。
といっても全くの初学者ではなく、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でわかる 進化しつづける柔軟なアプリケーションの育て方