代码之家  ›  专栏  ›  技术社区  ›  FMc TLP

我应该为一个涉及公共属性和不同方法的Ruby项目使用继承吗?

  •  0
  • FMc TLP  · 技术社区  · 15 年前

    我正在学习Ruby,并在做我的第一个真正的项目。程序将接收一个数据结构,并需要以各种文本格式复制包含该结构的信息。所有不同的输出类型都依赖于相同的基础属性集(大约40个)和相同的公共函数集(大约10个);但它们在如何将信息呈现为文本方面有所不同。

    我最初的倾向是使用继承来设计这个,如下面的示例所示。然而:

    1. 我不知道该怎么做(见 中的代码注释 Foo.produce_output )
    2. 我想知道我是否在 使用完全错误的轨道 继承而不是什么 或者——混音?

    理想情况下,项目的用户不必关心所有特定于格式的类。( FooFormatA , FooFormatB 等等)。相反,他们只会处理 Foo .

    任何建议都将不胜感激。

    class Foo
        attr_accessor :output_types  # Many other common attributes.
        def produce_output
            # Take a Foo object and invoke the
            # appropriate produce_output method for
            # each of the output types.
        end
    
        # Various other common methods. 
    end
    
    class FooFormatA < Foo
        def produce_output
            puts "FooA"
        end
    end
    
    class FooFormatB < Foo
        def produce_output
            puts "FooB"
        end
    end
    
    class FooFormatC < Foo
        def produce_output
            puts "FooC"
        end
    end
    
    # Example use case.
    f = Foo.new
    f.output_types = ['A', 'C']
    f.produce_output
    
    2 回复  |  直到 15 年前
        1
  •  3
  •   Martin DeMello    15 年前

    在这里,继承似乎确实是错误的。我要做的是有一套方法, format_output_a , format_output_b ,然后说

    ['a', 'c'].each {|i| puts self.send('format_output_#{i}')}
    

    如果不想将方法名与输出类型绑定,可以维护查阅表格

    FORMATTERS = {'A' => :format_a, 'B' => :format_b, ...}
    
    ['A', 'C'].each {|i| puts self.send(FORMATTERS[i])}
    
        2
  •  1
  •   Pesto    15 年前

    如果我正确理解了您的目标,您希望foo类型的每个对象都能够实现不同的输出格式吗?如果是这样,我会用这样的混音器:

    module FooFormats
      attr_accessor :output_types
    
      def produce_output_a
        puts "FooA"
      end
    
      def produce_output_b
        puts "FooB"
      end
    
      def produce_output_c
        puts "FooC"
      end
    
      def produce_output
        @output_types.each do |output_type|
          begin
            send "produce_output_#{output_type.to_s.downcase}"
          rescue
            #An undefined output format
          end
        end
      end
    
    end
    
    class Foo
      include FooFormats
    
      def initialize(output_types = [])
        self.output_types = output_types
      end
      # Various other common methods. 
    end
    
    # Example use case.
    f = Foo.new ['A', 'C']
    f.produce_output