FizzBuzz問題で学ぶOpen Closed Principle

ruby

SOLID原則の1つであるOpen Closed PrincipleをFizzBuzz問題を通して理解しよう!という趣旨の動画です。

動画

動画内の説明で利用していたコード

# require_relative './fizz_buzz'

# fizz_buzz = FizzBuzz.new

# (1..30).each do |number|
#   puts fizz_buzz.convert(number)
# end

require_relative './new_fizz_buzz'
require_relative './rules'

rules = [
  Rules::Rule.new(2, 'Nizz'),
  Rules::Rule.new(3, 'Fizz'),
  Rules::Rule.new(5, 'Buzz'),
  Rules::DefaultRule.new
]
new_fizz_buzz = NewFizzBuzz.new(rules)

(1..30).each do |number|
  puts new_fizz_buzz.convert(number)
end
module Rules
  class Rule
    def initialize(divisor, word)
      @divisor = divisor
      @word = word
    end

    def match(_carry, number)
      (number % @divisor).zero?
    end

    def apply(carry, _number)
      carry + @word
    end
  end

  class DefaultRule
    def match(carry, _number)
      carry.empty?
    end

    def apply(_carry, number)
      number.to_s
    end
  end
end
class NewFizzBuzz
  def initialize(rules)
    @rules = rules
  end

  def convert(number)
    carry = ''
    @rules.each do |rule|
      carry = rule.apply(carry, number) if rule.match(carry, number)
    end

    carry
  end
end
class FizzBuzz
  def convert(number)
    return 'FizzBuzz' if (number % 15).zero?
    return 'Buzz' if (number % 5).zero?
    return 'Fizz' if (number % 3).zero?

    number
  end
end
# FizzBuzzで学ぶ OCP
OCP: Open Closed Principle(開放/閉鎖原則)
  SOLID原則の1つ
  拡張に対しては開いており、修正に対しては閉じていること

例えば、FizzBuzzのコードがあります.
- 3の倍数で'Fizz'
- 5の倍数で'Buzz'
- (15の倍数では'FizzBuzz')

これに、「2の倍数で'Nizz'」を追加したい。
下記のようになる. <= convertメソッドを変更する必要がある.(OCPに違反)

- 2の倍数で'Nizz'
- 3の倍数で'Fizz'
- 5の倍数で'Buzz'

- (30の倍数では'NizzFizzBuzz)
- (15の倍数では'FizzBuzz')
- (10の倍数では'NizzBuzz')
- (6の倍数では'NizzFizz')

# 実装のイメージ
1. NewFizzBuzzクラス作成
    - initializeでrules渡す
    - convertメソッド
2. Ruleクラス作成
    - initializeでdivisor, wordを渡す
    - matchメソッド
    - applyメソッド

コメント