2014-12-04 86 views
1

我有一個叫Orders的類。我想保留所有「訂單」實例的數組,以便我可以映射/減少/或以其他方式查詢它們。跟蹤在Ruby中創建的對象

後來我想元帥「轉儲」和「加載」對象的「訂單」數組。

我的計劃是在初始化時將每個創建的對象添加到@@ all_orders數組堆棧上。然後,我可以在@@ all_orders數組上執行我的.each方法,循環遍歷所有「訂單」對象。

我接近這個正確的面向對象的方式嗎? (代碼片段的想法)...

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

需要注意的是,使用簡短的''''符號而不是'Array.new'幾乎總是可取的。 – tadman 2014-12-04 20:45:46

回答

1

正確的面向對象的方式來做到這一點是讓你把訂單到容器中。這可以是一個普通的舊數組或特殊的容器類。

這裏最大的問題是您沒有適當的上下文來存儲「所有訂單」數據。所有與什麼有關的命令?整個應用程序?如果是這種情況,你需要訂單或數據庫的概念來存儲它們。

例如:

class OrderBook < Array 
end 

order_book = OrderBook.new 
order_book << Order.new(...) 

請注意,我已經改名OrdersOrder因爲這是更準確的,奇異的名字。

自動-神奇將實例添加到容器幾乎總是一個災難的祕訣。這種事情應該使用像模型控制器這樣的設計模式來處理。這是一個巨大的假設,您希望將其包含在全局訂單池中。

0

我會考慮使用dependency injection將列表對象傳遞給您的訂單實例。 OOP的最佳實踐是解耦代碼並嘗試爲每個對象分配一個責任(單一責任原則)。這有助於保持代碼的可維護性和易於更改。你現在正在接近它的方式,Order類正在做與訂單相關的東西和存儲列表。在下面的示例中,當實例化訂單時,可以將一個列表對象傳遞給Order對象,並且所有訂單都需要知道列表對象應該響應#add方法。這樣,如果列表的實現必須更改(例如,使列表對象使用Redis存儲),則不需要同時更改Order類和OrderList類。您只會更新OrderList類來處理#add方法中的Redis。此外,您不再有Order類的內部依賴關係來處理列表責任,因此該訂單僅做它應該做的事情。

class OrderList 
    attr_reader :items 

    def initialize 
    @items = [] 
    end 

    def add(order) 
    @items << order 
    end 
end 

class Order 
    def initialize(opts) 
    order_list = opts[:order_list] 
    order_list.add self 
    end 
end 

order_list = OrderList.new 
order1 = Order.new order_list: order_list 
order2 = Order.new order_list: order_list 

puts order_list.list.inspect