【问题标题】:Ruby + OOP: Is it okay that my subclasses expect different data types for a @shipping_address IV?Ruby + OOP:我的子类对@shipping_address IV 期望不同的数据类型可以吗?
【发布时间】:2014-01-22 20:24:07
【问题描述】:

我的子类中的实例变量具有不同类型是不好的做法吗?或者这就是 ruby​​ 和动态类型的美妙之处?

例如:

我有一个超类UpsShipping,它有一个实例变量@shipping_method

这是我的第一个子类:

class UpsShippingQuote < UpsShipping

  def ship_to
    {
      "CompanyName" => shipping_address.company, #<-- expects an object that responds to company, etc
      "AttentionName" => shipping_address.name,
      "PhoneNumber" => shipping_address.phone,
      "Address" => recipient_address,
      "ResidentialAddress" => nil
    }
  end

  def recipient_address
    {
      "AddressLine1" => shipping_address.address,
      "AddressLine2" => shipping_address.address_2,
      "City" => shipping_address.city,
      "StateProvinceCode" => shipping_address.state.code,
      "CountryCode" => 'US',
      "PostalCode" => shipping_address.postal_code
    }
  end

和第二个子类:

class UpsShippingEstimator < UpsShipping

  def ship_to
    {
      "CompanyName" => "Test",
      "AttentionName" => "Test",
      "PhoneNumber" => "1231231234",
      "Address" => recipient_address,
      "ResidentialAddress" => nil
    }
  end

  def recipient_address
    {
      "AddressLine1" => "Test",
      "City" => shipping_address['city'], #<-- Expects a hash
      "StateProvinceCode" => shipping_address['state'],
      "CountryCode" => 'US',
      "PostalCode" => shipping_address['zip_code']
    }
  end

所以在UpsShippingQuote 中,它希望shipping_method 是我的Address 模型的一个实例,但在UpsShippingEstimator 中,它希望shipping_method 是一个哈希实例。

这样好吗?或者这是我做错继承的代码味道?或者我做得很好,因为我正在利用动态类型?

【问题讨论】:

    标签: ruby oop


    【解决方案1】:

    我认为你应该只接受散列或类似散列的东西。这是一个你可以给别人的接口。

    对象是一种封装知识的方式,因此您可以更好地向他人解释它。如果对象的子对象采用不同的参数,则无法记录该对象。

    另一方面,您可以使用哈希作为接口:

    class UpsShippingQuote < UpsShipping
    
      def ship_to
        {
          "CompanyName" => shipping_address['company'], #<-- expects an object that responds to company, etc
          "AttentionName" => shipping_address.['name'],
          "PhoneNumber" => shipping_address.['phone'],
          "Address" => recipient_address,
          "ResidentialAddress" => nil
        }
      end
    
    end
    

    这将适用于ActiveRecord,但您也可以使用以下方法为其他 ruby​​ 类启用此行为:

    def [] attribute
      public_send(attribute)
    end
    

    这应该让任何 Ruby 类都像哈希一样嘎嘎作响。

    【讨论】:

      猜你喜欢
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      相关资源
      最近更新 更多