创建一个类的多个实例。最惯用的吗?

问题描述 投票:0回答:1

[如果我们考虑一家杂货店有一套库存。我想知道是否还有一种更惯用的方法?

首先,我有一个可爱的货架班:

# The Shelves class holds the items in the market
class Shelves
  attr_reader :item_price

  def initialize(item_name, item_price, item_promo_group, item_quantity)
    @item_name = item_name
    @item_price = item_price
    @item_promogroup = item_promo_group
    @item_quantity = item_quantity
  end
end

我的意图是致电Market.new并创建一组初始库存。目前,我正在实例化多个Shelves实例,如下所示:

class Market
  attr_reader :initial_stock

  def initialize
    @initial_stock = [Shelves.new('item1',  1.00, 'A', 10),
                      Shelves.new('item2',  1.50, 'B',  9),
                      Shelves.new('item3',  2.00, 'C',  8),
                      Shelves.new('item4',  2.50, 'A',  7),
                      Shelves.new('item5',  3.00, 'B',  6),
                      Shelves.new('item6',  4.50, 'C',  5),
                      Shelves.new('item7',  5.00, 'A',  4),
                      Shelves.new('item8',  1.00, 'B',  3),
                      Shelves.new('item9',  1.50, 'C',  2),
                      Shelves.new('item10', 2.00, 'A',  1)]
  end
end

它在一个数组中,因为...主要是我用它来求和所有价格的总和,以获得总股价。我想到了另一种方式,例如使用实例变量,但这也感觉太冗长,例如:

@apple = Shelves.new('apple',  1.00, 'A', 10)
@banana = Shelves.new('banana',  1.00, 'A', 10)
@pear = Shelves.new('pear',  1.00, 'A', 10)

基本上我是在问,做与上面类似的事情的最惯用的方法是什么?

ruby
1个回答
0
投票

TL; DR

建模业务域对象并非易事。为了进行可靠的实际库存管理,您可能希望使用真实的数据库而不是“普通的旧Ruby对象”(PORO)来管理CRUD操作和数据规范化,但是您当然可以使用以下方法来model问题域一些相当基本的PORO,例如ArrayStruct

域建模示例和示例用法

我可能会误解您的问题,但是似乎问题更多的是关于如何正确建模域的问题。您确实需要一个完全标准化的数据库,该数据库应具有描述库存中的项目(以及可能的每个项目的位置数据,如过道和货架)的模式,而不是复杂的Ruby对象。

也就是说,如果您只是想找到一种方法来用纯Ruby表示当前数据集,则可以考虑以下方法:

require 'singleton'

class Inventory
  include Singleton
  attr_accessor :items

  def initialize
    @items = []
  end
end

class Item < Struct.new(:name, :price, :quantity, :promo_group)        
end

inventory = Inventory.instance

inventory.items.append(
  Item.new('apple',  0.99, 5, 'A'),
  Item.new('orange', 1.50, 7, 'B'),
)

[基本上,这个想法是创建一个singleton库存对象,其中包含一个Item对象的数组。每个Item对象都是一个Struct,其中包含您可能需要的任何数据。您可以通过Inventory#items的getter和setter方法操作库存,或通过其Struct的类似于Enumerable的行为来引用库存中单个项目的属性。例如:

inventory.items
#=> [#<struct Item name="apple", price=0.99, quantity=5, promo_group="A">, #<struct Item name="orange", price=1.5, quantity=7, promo_group="B">]

inventory.items.map &:name
#=> ["apple", "orange"]

inventory.items.select { _1.promo_group == ?A }
#=> [#<struct Item name="apple", price=0.99, quantity=5, promo_group="A">]

inventory.items.filter { _1.name == 'apple' }.count
#=> 1

inventory.items.filter { _1.name == 'apple' }.map &:to_h
#=> [{:name=>"apple", :price=>0.99, :quantity=>5, :promo_group=>"A"}]

这解决了您所问的问题,但是您必须为基本操作(例如搜索,添加,删除或更新特定库存项目)构建自己的方法。具有object-relational mapping的真实数据库(例如,在SQL或NoSQL数据库之上的ActiveRecordSequel或类似的ORM接口)对于真实世界的应用程序确实是更好的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.