Menu
Coddy logo textTech

Повторение — способы оплаты

Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 36 из 57.

challenge icon

Задание

Сложно

Создайте оформление заказа с полиморфизмом, абстрактным методом и утиной типизацией. PaymentMethod#charge(amount) — шаблонный метод: он возвращает nil, когда available?(amount) имеет значение false, а в противном случае возвращает card paid 50.00, fee 1.00, используя label и абстрактный fee(amount), который вызывает исключение NotImplementedError в PaymentMethod. available? — это хук, возвращающий true. Card взимает комиссию 2%; PayPal — 0.30 плюс 3%; GiftCard.new(balance) не взимает комиссию, доступен только пока его баланса хватает на покрытие суммы, и уменьшает баланс. Voucher.new(value) не является PaymentMethod: у него есть только собственный charge(amount), возвращающий voucher covered 20.00, когда номинала хватает на покрытие суммы, и nil в противном случае. Вспомогательная функция checkout(amount, methods) в functions.rb по очереди вызывает 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