Skip to content

Instantly share code, notes, and snippets.

@sunaot
Created April 9, 2012 08:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sunaot/2342368 to your computer and use it in GitHub Desktop.
Save sunaot/2342368 to your computer and use it in GitHub Desktop.
オブジェクト指向プログラミングと構造化プログラミングの視点の違い

OOP とトップダウンの構造化プログラミングの設計上の違いとしてわかりやすいのは、 フローごとの動作の差異をどこが担保するかだと思います。

決済で、キャリア決済とクレジットカードによる決済を実装しようとしたとき、 トップダウンの場合、

case payment_method
when :carrier
  do_carrier_payment
when :creditcard
  do_creditcard_payment
end

でフローを分岐しておいて共通する処理は内部で共通のモジュールを呼び出す形で書くと思います。

また、構造化プログラミングでよく見かける悪い書き方だと共通の処理をダーッと書いて キャリアとクレカの違いの部分だけ都度フラグを見て挙動を変えます。

get_payment_amount

if (payment_method == :carrier) 
  call_carrier_payment_api(payment_amount) if in_limit? and valid_user?
elsif (payment_method == :creditcard)
  call_authorize_api(payment_amount)
  payment_commit_api(payment_amount)
end

... # 引き続き共通の後続する手続き

一方、OOP の場合、二つの決済手段があるということをそのままコードで書き、 両者に共通のプロトコルをまとめてフローを書きます。

共通のプロトコルのほうはこのようになります。

def payment(payment_amount, payment_method)
  payment_method.commit(payment_amount) if payment_method.commitable?(payment_amount)
end

それぞれの決済手段ごとの実装の差異は payment_method へ渡される、 キャリア決済クラスのインスタンスやクレカ決済クラスのインスタンスとして表現されます。

class CarrierPayment
  def commit payment_amount
    call_carrier_payment_api(payment_amount)
  end

  def  commitable? payment_amount
    in_limit?(payment_amount) and valid_user?
  end
end

class CreditCardPayment
  def initialize card_number
    @card_number = card_number
  end

  def commit payment_amount
    payment_commit_api(payment_amount)
  end

  def  commitable?
    status = call_authorize_api(@card_number, payment_amount)
    authorized?(status)
  end
end

こうすると、トップダウンのプログラミングでコード値による条件分岐として実装されていた 決済手段のバリエーションが、 それぞれのオブジェクトによるポリモーフィズムとして実装されます。 これは決済手段が増えたときの結合度の低さにつながり、 保守性の高いプログラムを書きやすくなります。 こんな風に発想の起点が違うのが一番の違いかなと思ってます。

とくに、クラスに注目するのではなくて、 「payment_method という変数に束縛されるインスタンスによって挙動が実行時に動的に決まる」 という点が道具としてなじむと、OOP に慣れたといえる気がします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment