2010-01-12 58 views
0

想象一下以下模型:在類中暴露列表最合適的方式是什麼?

  • 一個有許多
  • 一個有許多細胞

什麼會是較好的界面來處理這些「面向對象的方式」的類?

1 - 提供來訪問屬性/細胞(不一定暴露下面的數據結構,但創建例如一個類RowCollection ...)

my_table = new Table() 
my_table.rows.add([1,2,3]) 
my_row = my_table.rows.get(0) 
my_row.cells.get(0) 
for(cell in my_row.cells) {} 
... 

2 - 或提供直接在行方法

my_table = new Table() 
my_table.add_row([1,2,3]) 
my_row = my_table.get_row(0) 
my_row.get_cell(0) 
for(cell in my_row.get_cells) {} 
... 

3 - 以上都不是......

+0

主要用例是添加,排序和迭代值 – 2010-01-12 11:40:51

回答

0

這取決於您打算如何訪問行/單元格。

沒有一個正確的方法來做到這一點 - 你需要決定你想如何訪問它們,並建立你的對象,讓它們以你想要使用它們的方式暴露它們。

0

這取決於數據以及您打算如何處理它。 用戶是否需要單個單元格?個別行/列?行/列的子節點?

也許最清潔的方式是提供仿函數接口。提供一個或多個函數,這些函數將在每個元素或函子中定義的子集上運行仿函數。

如果用戶需要訪問複雜的單元組合,這可能會工作得不好。

1

我認爲答案很主觀。如果我們按照您的示例進行操作,則提供您的類的方法或屬性以通過行/列引用返回值可能是適當的。這些可以同時實現,例如:

myClass.Row[x].Column[y]  
myClass.Column[y].Row[x]  
myClass.Cell[x,y] 

您可能還決定,最好是直接公開的列表,如果數據「行」是有限的:

myClass.SomeArrayOfValues[itemIndex] 

我你使用的短語通知像「表」和「行」,所以我可能會認爲你希望你的類代表一個數據庫或類似的結構,但是你可能會發現雖然以這種方式存儲數據可能是有效的,但你可能會發現暴露數據在另一種形式中對你班級的用戶可能更有意義。最後,你如何選擇這樣做的目的應該是真實地反映數據本身和你正在建模的系統的目的,而這隻能根據具體情況來決定。

+0

目標是表示一個基本的電子表格結構 – 2010-01-12 12:41:39

+1

既然如此,如果它是有意義的,那麼您甚至可能會公開一個方法或屬性使用應用程序中使用標準電子表格單元格表示法的字符串(例如:「A1」,「D3」等)。這可能是最好的,但作爲我在上面的回答中給出的例子的一些延伸或包裝。 – 2010-01-12 13:08:19

1

根據您對使用的評論,「主要用例是添加,排序和迭代值」,我可能不會允許檢索單個元素,而是讓用戶提供一個函數來對存儲的元素。用C++表達。

class Table 
{ 
public: 
    Table(); 
    //Table(unsigned int numberOfRows, unsigned int numberOfCells); 

    void addRow(); 
    void addCell(); 

    //Throw exception if out of range or don't supply these functions if not needed by user. 
    void removeRow(unsigned int rowNumber); 
    void removeCell(unsigned int rowNumber, unsigned int cellNumber); 

    //Iterate over entire table 
    template<class Pred> 
    void forEach(Pred pred); 

    //Iterate over a specific row, throw exception if row is out of range. 
    template<class Pred> 
    void forEach(unsigned int row, Pred pred); 
} 

您將不得不根據您計劃如何輸入/更新數據來調整添加/更新/刪除調用。這種設計強烈地傾向於操縱元素集合。這種設計的積極之處在於,您並未將您的用戶提交給您如何表示表格的具體基礎結構。這符合得墨忒耳定律。

如果您需要訪問特定的單個元素,則需要採用其他方法或將其作爲此處已提供內容的擴展。

1

考慮你可以擺脫多少個getter和setter。強大的面向對象設計具有相互導出行爲的對象,而不是數據。例如,一個人一個getter/setter方法模型的骨架:

class Person: 
    def set_name(value): 
    def get_name: 
    def set_age(value): 
    def get_age: 
    def set_drink(value): 
    def get_drink: 
    def set_favorite_drink(value): 
    def get_favorite_drink: 

這裏是一個使用的人一些(僞)代碼:

def order_drink(person) 
    if person.age >= 21: 
    puts "#{person.name} can have a drink" 
    person.drink = bar.order(person.favorite_drink) 
    else: 
    puts "#{person.name} cannot drink (legally)." 

這裏是你如何能有一個不帶一個人

class Person: 
    def order_drink_from(bar): 
    if self.age >= 21: 
     puts "#{self.name} can have a drink" 
     self.drink = bar.order(favorite_drink) 
    else: 
     puts "#{self.name} cannot drink (legally)" 

像這樣使用:參與訂購飲料的getter或setter方法

person.order_drink_from(bar) 

我不會說你永遠不需要在面向對象程序中使用getters。但我會這樣說:特別是制定者應該讓你重新考慮設計。每次你寫一個getter或者setter時,讓頭腦裏的小聲問你是否有辦法讓對象輸出行爲而不是數據。