ruby:如何进行继承或组合

时间:2016-11-23 07:37:21

标签: ruby oop inheritance composition

我正在尝试干掉一些代码。 如何使用这段代码与ruby进行组合和/或继承。

module Ns4
  module Maps
    module StrokeStyle
      class RedOutline
        def self.strokeColor
          "red"
        end

        def self.strokeWeight
          4
        end
      end

      class Random
        def self.strokeColor
          [ "#808080", "#909090" ].sample(1)[0]
        end

        def self.strokeWeight
          4
        end
      end

      class Transparent
        def self.strokeColor
          "transparent"
        end

        def self.strokeWeight
          0
        end
      end
    end
  end
end

基本上我想尽可能减少逻辑重复。

2 个答案:

答案 0 :(得分:1)

我可以想到以下几点:

module Ns4
  module Maps
    module StrokeStyle
      module StrokeHelper
        def self.included(base)
          base.singleton_class.send(:attr_accessor, *%i(strokeColor strokeWeight))
        end
      end
      class RedOutline
        include StrokeHelper
      end
      class Random
        include StrokeHelper
      end
      class Transparent
        include StrokeHelper
      end
    end
  end
end

现在每个类中都有strokeColorstrokeWeight的setter和getter:

Ns4::Maps::StrokeStyle::RedOutline.strokeColor = 'red'
Ns4::Maps::StrokeStyle::RedOutline.strokeColor
#=> "red"
Ns4::Maps::StrokeStyle::RedOutline.strokeWeight = 4
Ns4::Maps::StrokeStyle::RedOutline.strokeWeight
#=> 4

答案 1 :(得分:1)

如果你想真的干它:

METHODS = %i|strokeColor strokeWeight|
DECLARATIONS = { 
  :RedOutline => [-> { 'red' }, 4], 
  :Random => [-> { %w|#808080 #909090|.sample }, 4], 
  :Transparent => ['transparent', 0]
}


module Ns4 
  module Maps
    module StrokeStyle
      DECLARATIONS.each do |klazz, props|
        StrokeStyle.const_set(klazz, Module.new do
          METHODS.zip(props).each do |(m, p)| 
            define_method m do p.is_a?(Proc) ? p.call : p end
          end
          module_function *METHODS
        end)
      end 
    end 
  end 
end

puts Ns4::Maps::StrokeStyle::RedOutline.strokeColor
#⇒ red
puts Ns4::Maps::StrokeStyle::Random.strokeColor
#⇒ #808080
puts Ns4::Maps::StrokeStyle::Transparent.strokeColor
#⇒ transparent

添加新方法就像添加新的Hash元素一样简单。