Skip to content

Instantly share code, notes, and snippets.

@sozuuuuu
Created May 12, 2019 04:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sozuuuuu/6abb6e9c059d3ef5b89a4402cf613a64 to your computer and use it in GitHub Desktop.
Save sozuuuuu/6abb6e9c059d3ef5b89a4402cf613a64 to your computer and use it in GitHub Desktop.
現場でDDD持ち帰ってやってみたのRuby実装
# https://little-hands.hatenablog.com/entry/2019/05/11/genba-ddd-handson
# 上記のブログ記事に触発されてRubyでの実装を試してみました。
# 本当はCapacityPlanとOptionPlanのデータをMinitest外で宣言したかったのですが、
# Minitestから参照できなかったのでsetupで宣言しています。
class Price
def initialize(value)
raise "value should be greater than or equal to 0. given value:#{value}" unless value >= 0
@value = value
end
def to_i
@value
end
def plus(price)
Price.new(value + price)
end
end
class Plans < Array
def [](id)
find { |item| item.id_eq?(id) }
end
end
class CapacityPlan
def initialize(id, price)
@id = id
@price = Price.new(price)
end
def to_s
@id.to_s
end
def id_eq?(id)
@id == id
end
def self.seed
Plans.new([
CapacityPlan.new(:_1GB, 1000),
CapacityPlan.new(:_3GB, 3000),
CapacityPlan.new(:_30GB, 6000)
]);
end
end
class OptionPlan
def initialize(id, price, permitted_capacity_plans)
@id = id
@price = Price.new(price)
@permitted_capacity_plans = permitted_capacity_plans
end
def permitted?(capacity_plan)
@permitted_capacity_plans.contains(capacity_plan)
end
def id_eq?(id)
@id == id
end
def self.seed
Plans.new([
OptionPlan.new(:movie_free, 1000, [:_3GB, :_30GB]),
OptionPlan.new(:call_free, 3000, [:_1GB, :_3GB, :_30GB])
]);
end
end
class PlanValidator
def initialize(capacity_plan, option_plans = [])
@capacity_plan = capacity_plan
@option_plans = option_plans
end
def valid?
return true if @option_plans.empty?
@option_plans.any? { |option_plan| option_plan.permit?(@capacity_plan) }
end
def validate!
raise "Unpermitted capacity_plan:#{@capacity_plan} given" unless valid?
end
end
class Contract
def initialize(capacity_plan, option_plans = [])
PlanValidator.new(capacity_plan, option_plans).validate!
@capacity_plan = capacity_plan
@option_plans = option_plans
end
end
require 'minitest/autorun'
class TestContract < Minitest::Test
def setup
@capacity_plans = CapacityPlan.seed
@option_plans = OptionPlan.seed
end
def test_valid_1GB_without_options
Contract.new(@capacity_plans[:_1GB], [])
end
def test_invalid_1GB_with_movie_free
assert_raises do
Contract.new(@capacity_plans[:_1GB], [@option_plans[:movie_free]])
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment