Menu
Coddy logo textTech

復習 - 支払い方法

CoddyのRubyジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 36/57。

challenge icon

チャレンジ

難しい

ポリモーフィズム、抽象メソッド、ダックタイピングを使ってチェックアウト処理を構築します。PaymentMethod#charge(amount)はテンプレートメソッドです。available?(amount)が false の場合はnilを返し、それ以外の場合はlabelと、PaymentMethodでNotImplementedErrorを発生させる抽象メソッドfee(amount)を使って、card paid 50.00, fee 1.00を返します。available?はtrueを返すフックです。Cardは手数料として2%を請求し、PayPalは0.30に加えて3%を請求します。GiftCard.new(balance)は手数料を請求せず、残高が金額をカバーしている間だけ利用可能で、残高を減らします。Voucher.new(value)はPaymentMethodではなく、独自のcharge(amount)だけを持ち、値が金額をカバーしている場合はvoucher covered 20.00を返し、それ以外の場合はnilを返します。functions.rbのヘルパーcheckout(amount, methods)は、各メソッドのchargeを順番に試し、最初の結果を返します。どれも成功しなければdeclinedを返します。

最初の入力行には、gift:30,voucher:20,cardのように支払い方法を列挙します。それ以降の各行は注文金額であり、提供されたコードはそれぞれについてcheckoutの結果を出力します。

コードはpayment_method.rb、card.rb、pay_pal.rb、gift_card.rb、voucher.rb、functions.rbに記述します。main.rbには提供された入出力コードが含まれており、編集できません。

自分で試してみよう

require_relative 'payment_method'
require_relative 'card'
require_relative 'pay_pal'
require_relative 'gift_card'
require_relative 'voucher'
require_relative 'functions'

# 提供された入出力コード: そのままにしておく
input = []
while (line = gets)
  input << line.chomp
end
methods = input[0].split(",").map do |entry|
  kind, value = entry.split(":")
  case kind
  when "card" then Card.new
  when "paypal" then PayPal.new
  when "gift" then GiftCard.new(value.to_f)
  else Voucher.new(value.to_f)
  end
end
input.drop(1).each { |line| puts checkout(line.to_f, methods) }

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rubyオンラインコンパイラ