【问题标题】:Should I refer to an instance or a class method in a loop that creates objects?我应该在创建对象的循环中引用实例还是类方法?
【发布时间】:2019-01-28 01:50:48
【问题描述】:

我正在将 .csv 文件导入 Ruby on Rails 应用程序。导入器将从文件的每一行创建一个新的数据库记录。

class Invoice < ApplicationRecord

  def self.import(file)
    output_log = []
    CSV.foreach(file.path) do |row|
      output_log << some_method_name(row)
    end
    return output_log
  end

end

我希望将数据验证、记录创建和错误报告的所有复杂性隐藏在另一种方法中,而不是让我的 import 方法变得混乱。我以some_method_name 为例。我真的应该打电话给什么?

我想到了两种可能性。实例方法:

output_log << Invoice.new.populate_from_row(row)

或者,一个类方法:

output_log << Invoice.create_from_row(row)

(要么返回一个记录成功或失败的字符串。)

两者都可以,但哪个更有意义?是否有一些设计原则或模式可以告诉我如何选择?

【问题讨论】:

    标签: ruby-on-rails oop design-patterns methods import-csv


    【解决方案1】:

    我建议您在 import 方法中使用最合适的方法名称,并将所有逻辑封装在私有方法(或服务对象)中。在我的应用程序中,我通常会执行以下操作:

    class Invoice < ApplicationRecord
    
      def self.import(file)
        output_log = []
        CSV.foreach(file.path) do |row|
          output_log << create_invoice_from_csv_row(row)
        end
        return output_log
      end
    
      private
    
      def create_invoice_from_csv_row(row)
        Invoice.find_or_create_by(
          order_number: row["Order Number"],
          customer_name: row["Customer Name"],
          # ...
        )
        return ""
      rescue => e
        return e.message
      end
    end
    

    【讨论】:

    • 看起来不错!你选择了一个类方法;对你为什么做出这个选择有任何见解吗?这真的很重要吗?
    • 您会在其他地方使用此代码吗?如果是,我可能会选择 ServiceObject,这样您就可以重用代码而无需复制它。
    猜你喜欢
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 2015-11-25
    • 2014-06-28
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 2013-04-22
    相关资源
    最近更新 更多