8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FizzBuzz問題で学ぶOCP(Open Closed Principle)

Posted at

動画概要

以下の動画で、SOLID原則の一つであるOCP(Open Closed Principle・開放/閉鎖原則)について、FizzBuzz問題を通じて解説しました。
ソフトウェアの拡張に対して開かれている一方で、修正に対しては閉じているという原則です。

内容

元々のFizzBuzz

通常、FizzBuzzは以下のような形で実装されますが、新しいルールの追加が求められた場合、このコードでは変更が必要になります。

コード

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

    number.to_s
  end
end

実行例

main.rb
require_relative './fizz_buzz'

fizz_buzz = FizzBuzz.new

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

FizzBuzzの拡張

新たなルール、「2の倍数で"Nizz"を返す」を追加するとなったとき、既存のconvertメソッドに修正を加える必要があります。これはOCPに違反します。

NewFizzBuzzの実装

動的にルールを適用できるNewFizzBuzzクラスを導入することで、この問題を解決しました。

rulesモジュール

rule.rb
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

new_fizz_buzzクラス

new_fizz_buzz.rb
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

実行例

main.rb
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

この新しいアプローチにより、コードの拡張がしやすくなります。

8
2
0

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
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?