简体   繁体   English

减少实例方法的数量

[英]Reduce number of instance methods

I am modelling a report as a class and each column value as an accessor. 我将报告建模为一个类,将每个列值建模为一个访问器。 Each value in the report needs to be accessed from the database. 报告中的每个值都需要从数据库中访问。 But this makes the class look quite fat and RubyMine warns me of too many methods in class. 但这使类看起来很胖,RubyMine警告我类中的方法太多。

class Report

attr_accessor :name, :col1, :col2, :col3 .... :col15

def col1
 db.find({x: 1})['some_var']
end

def col2
 db.find({y: 4})['some_other_var']
end

and so forth for each attribute...

end

Since each getter is essentially single line that makes call to database, is there a simpler way to declare these vars without being in a method? 由于每个getter本质上是对数据库进行调用的单行,是否有一种更简单的方法来声明这些var,而无需使用方法?

I don't want to set these in the initialize method as these reports will be subclassed and child reports will not have all/some of these attributes. 我不想在initialize方法中设置这些属性,因为这些报告将被子类化,并且子报告将不具有所有/某些这些属性。

You can use meta-programming to create attr_accessor like methods on the fly. 您可以使用元编程来动态创建attr_accessor之类的方法。

For Example: 例如:

class Report
  def initialize(attributes)
    attributes.each do |attribute|
      define_singleton_method :"#{attribute}" do |hash_param, string_param|
        db.find(hash_param)[string_param]
      end
    end
  end
end

Then you can create new report object and pass attribute names as follow: 然后,您可以创建新的报表对象并按如下所示传递属性名称:

r = Report.new(["n","m"])

Now you can call n and m methods on the r object 现在您可以在r对象上调用nm方法

r.m({val1: "val1"}, "val2")
r.n({val2: "val1"}, "val2")

@Rahul based on answer to my question, the only advice I can give here then is to use best OOP design principles. @Rahul基于对我问题的回答,那么我在这里只能给出的建议是使用最佳OOP设计原则。 Subclass and modularize where possible as well as using ruby meta-programming. 尽可能进行子类化和模块化,以及使用ruby元编程。 If you need the methods, they have to be written somewhere. 如果需要这些方法,则必须将它们编写在某处。 But if you only need getters, consider attr_reader instead, unless you'll need setters too. 但是,如果只需要getter,则考虑attr_reader ,除非也需要setter。

If you can get the column names you can use dynamic method definition with something like this assuming db is magically defined somewhere you have not made clear, we'll assume it's a connection to the database. 如果可以获取列名,则可以使用动态方法定义以及类似的方法(假设db是在您不清楚的地方神奇定义的),我们将假定它是与数据库的连接。

class Report

  db.column_names.each do |col|
    define_method(col.to_sym) { db.find(options={}) }
  end

end

If you just want RubyMine to stop nagging you, I assume it's using rubocop and you can see this post for how to override rules. 如果您只是想让RubyMine停止对您的困扰,那么我认为它正在使用rubocop,您可以在这篇文章中了解如何覆盖规则。

https://www.jetbrains.com/help/ruby/2017.1/rubocop.html https://www.jetbrains.com/help/ruby/2017.1/rubocop.html

or 要么

https://github.com/rubocop-hq/rubocop https://github.com/rubocop-hq/rubocop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM