0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ダックタイピング オブエジェクト指向設計実践ガイドより

Last updated at Posted at 2021-06-15

#はじめに
本題はここダックタイピングからです
##読者対象
読者対象はプログラミング初学者です。
といっても全くの初学者ではなく、Railsチュートリアルを終えたレベルと定義します。
##オブジェクト指向設計実践ガイド
オブエジェクト指向設計実践ガイドの記事は、他の方も書いてありますが、
一度に全部まとめたものが多かったです。
この記事は、オブエジェクト指向らしく、各章ごとに、単一責任に、シンプルさを意識して書きました。
余談ですが、とある弁護士が弁護士は六法全書を丸暗記してないが、各条文を見ただけで、関係ある条文、知識を思い出すそうです。
この記事は、オブジェクト指向設計実践ガイドってこんなこと書いてあったなーと思いだすための記事でもあります。
また、オブエジェクト指向設計実践ガイドを読んだことがなくても、こういうことが書いてあるとのかー、とさわりだけでも理解して頂けたら幸いです。
##オブジェクト指向設計実践ガイドで得た3つのポイント
リファクタリング前のコードを読み、コードの危うさを察知できる。
リファクタリングするために、より抽象的なコードの書き方を学べる。
gemなどの抽象的なコードを読解できる。
##一問一答
一問一答風の構成にしています。
リファクタリング前のコードを読み、コードの危うさ、嗅覚を養っていきましょう。
その後、リファクタリング前のコードの危うさを説明し、自分なりにリファクタリングしたコードを書いてみましょう。
最後に、もう一度、リファクタリング前のコードと、リファクタリング後のコードを読み比べ、
抽象的な思考、抽象的な書き方を共に学んでいきましょう。
#ダックタイピング
今回はダックタイピングというコードの書き方を説明します。
下記コードを読んで、このコードの危うさを説明し、自分なりにリファクタリングしたコードを書けるレベルに達しているなら、
オブエジェクト指向設計実践ガイドの第五章 「ダックタイピングでコストを削減する」、
この章を理解していると言えるでしょう。
##リファクタリング前

class Trip
  attr_reader :bicycles,:customers,:vehicle
  def prepare(prepares)
    prepares.each do |preparer|
      case preparer
      when Mechanic
        preparer.prepare_bicycles(bicycles)
      when TripCordinator
      preparer.buy_food(customers)
      when Driver
        preparer.gas_up(vehicle)
        preparer.fill_water_tank(vehicle)
      end
    end
  end
end
class Mechanic
  def prepare_bicycles(bicycles)
    bicycles.each {|bicycle| prepare_bicycle(bicycle)}
  end
  def prepare_bicycle(bicycle)

  end
end
class TripCordinator
  def buy_food(customers) ; end
end
class Driver
  def gas_up(vehicle) ;end
  def fill_water_tank(vehicle) ; end
end
trip =Trip.new
prepares = [Mechanic.new,TripCordinator.new]
trip.prepare(prepares)

###このコードの危険性
Tripクラスのprepareメソッドが各クラスに依存しすぎている。
機能が拡張するたびに、prepareメソッドを修正しないといけない。←バグのもと
##リファクタリング後

class Trip
  attr_reader :bicycles,:customers,:vehicle
  def prepare(prepares)
    prepares.each do |preparer|
      preparer.prepare_trip(self)
    end
  end
end
class Mechanic
  def prepare_trip(trip)
    trip.bicycles.each do |bicycle|
      prepare_bicycle(bicycle)
    end
  end
  def prepare_bicycle(bicycle) ;end
end
class TripCordinator
  def prepare_trip(trip)
    buy_food(trip.customer)
  end
  def buy_food(customers) ; end
end
class Driver
  def prepare_trip(trip)
    vehicle = trip.vehicle
    gas_up(vehicle)
    fill_water_tank(vehicle)
  end
  def gas_up(vehicle) ;end
  def fill_water_tank(vehicle) ; end
end
trip =Trip.new
prepares = [Mechanic.new,TripCordinator.new]
trip.prepare(prepares)

##ダックタイピング
各クラスにprepare_trip(trip)メソッドを書くことによって、
Tripクラスのprepareメソッドがすっきりしました!!
このような書き方をダックタイピングといいます。
詳しくはオブジェクト指向設計実践ガイドに書いてあります。
#参考文献
オブエジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方

0
1
1

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?