Created
November 25, 2012 02:15
-
-
Save ryancheung/4142129 to your computer and use it in GitHub Desktop.
specification pattern implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
class TagSpec | |
attr_reader :tag | |
attr_accessor :result | |
def initialize(tag) | |
@tag = tag | |
end | |
def match?(tag_collection) | |
tag_collection.include?(tag) | |
end | |
def and(other) | |
other = TagSpec.new(other) unless other.kind_of?(TagSpec) | |
AndTagSpec.new(self, other) | |
end | |
def or(other) | |
other = TagSpec.new(other) unless other.kind_of?(TagSpec) | |
OrTagSpec.new(self, other) | |
end | |
def not | |
NotTagSpec.new(this) | |
end | |
end | |
class AndTagSpec < TagSpec | |
attr_reader :left, :right | |
def initialize(left, right) | |
@left = left | |
@right = right | |
end | |
def match?(tag_collection) | |
left.match?(tag_collection) && right.match?(tag_collection) | |
end | |
end | |
class OrTagSpec < TagSpec | |
attr_reader :left, :right | |
def initialize(left, right) | |
@left = left | |
@right = right | |
end | |
def match?(tag_collection) | |
left.match?(tag_collection) || right.match?(tag_collection) | |
end | |
end | |
class NotTagSpec < TagSpec | |
attr_reader :wrapper | |
def initialize(wrapper) | |
@wrapper = wrapper | |
end | |
def match?(tag_collection) | |
!wrapper.match?(tag_collection) | |
end | |
end | |
class OrderedCompositeSpec < TagSpec | |
def initialize | |
@specs = [] | |
end | |
def add(tag_spec, priority) | |
@specs << [tag_spec, priority] | |
end | |
def match?(tag_collection) | |
ordered_specs = @specs.sort { |x, y| x.last <=> y.last } | |
ordered_specs.each do |spec, _| | |
if spec.match?(tag_collection) | |
self.result = spec.result | |
return true | |
end | |
end | |
false | |
end | |
end | |
spec1 = TagSpec.new("有伤病").and("没时间运动") | |
spec1.result = { default: "针对您无法运动/没时间运动的情况,我们帮您制定了一个能将运动融入生活的计划。培养规律的饮食习惯对于您的减重计划尤为重要。由于缺乏足够的有氧运动,减重速度必定会受影响,因此,只要时间允许尽量安排每周4~5次的有氧运动,用以提升减重效果。接下来,建议多关注围度变化,而不仅仅是体重的变化。让我们开始全新的NICE轻松、快乐减重之旅吧!" } | |
spec2 = TagSpec.new("重度肥胖").and("肥胖") | |
spec2.result = { default: "您目前的BMI远超健康上限,减重不是一两天的事情,坚定信心,但不要操之过急。建议您用3个月左右的时间让体重稳定的减轻10kg,同时关注腰围的变化,这对于保护心脑血管健康非常重要。相信我们只要认真努力,一定会有很好的成绩,马上就开始崭新的NICE健康、快乐减重之旅吧!" } | |
spec3 = TagSpec.new("超重") | |
spec3.result = { default: "您目前的BMI已经超出健康范围,减肥的第一步是把体重控制在健康体重范围*斤以内,再减至*斤左右(BMI=22 时对应的体重,此时健康达到比较好的水平),然后可向标准体重**斤前进;同时在此过程中需关注身体围度的变化。" } | |
composite_spec = OrderedCompositeSpec.new | |
composite_spec.add(spec1, 0) | |
composite_spec.add(spec2, 1) | |
composite_spec.add(spec3, 1) | |
if composite_spec.match?(["没时间运动", "超重", "有伤病"]) | |
puts composite_spec.result[:default] | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment