我有一个名为Orders的类。我想保留所有“Orders”实例的数组,以便我可以.each map / reduce /或以其他方式查询它们。
后来我想要Marshal“dump”并“加载”“Orders”对象数组。
我的计划是在初始化时将创建的每个新对象添加到@@ all_orders数组堆栈中。然后我可以在@@ all_orders数组上执行我的.each方法,循环遍历所有“订单”对象。
我接近这个正确的OOP方式吗? (获得想法的代码片段)......
class Orders
@@all_orders = Array.new
attr_accessor :order_no, :customer
def initialize(order_no, customer)
@id, @customer = order_no, customer
@order_lines = Array.new
@@all_orders << self
end
答案 0 :(得分:1)
正确的面向对象的方法是拥有一个容器,您可以将订单放入其中。这可以是一个普通的数组或一个特殊的容器类。
这里最大的问题是你没有适当的背景来存储&#34;所有订单&#34;数据。所有订单都与什么相关?整个申请?如果是这种情况,您需要订单簿或数据库的概念来存储它们。
例如:
class OrderBook < Array
end
order_book = OrderBook.new
order_book << Order.new(...)
请注意,我已将Orders
重命名为Order
,因为这是更准确,更奇特的名称。
自动神奇地向容器添加实例几乎总是一种灾难。应该使用像 model-controller 这样的设计模式来处理这类事情。您希望将其包含在全球订单池中,这是一个巨大的假设。
答案 1 :(得分:0)
我会考虑使用dependency injection将列表对象传递给您的订单实例。 OOP中的最佳实践是解耦代码并尝试仅为每个对象赋予一个责任(单一责任原则)。这有助于保持代码的可维护性和易于更改。现在,您正在接近它的方式,Order
类正在执行与订单相关的内容和列表的存储。在下面的示例中,当实例化订单时,可以将列表对象传递给Order
对象,并且所有需要知道的顺序是列表对象应该响应#add
方法。这样,如果列表的实现必须更改,例如,使列表对象使用Redis商店,那么您就不需要同时更改Order
类和{{1} }类。您只需更新OrderList
类以在OrderList
方法中处理Redis。此外,您在#add
类中不再具有处理列表职责的内部依赖关系,因此订单仅执行应有的操作。
Order