Language agnostic 什么';在类中公开列表最合适的方法是什么?

Language agnostic 什么';在类中公开列表最合适的方法是什么?,language-agnostic,oop,encapsulation,information-hiding,Language Agnostic,Oop,Encapsulation,Information Hiding,想象一下以下模型: 一个表有许多行 行有许多单元格 以“面向对象的方式”处理这些类的首选接口是什么 1-提供对属性行/单元格的访问(不一定公开底层数据结构,但创建例如类RowCollection…) 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) {} ..

想象一下以下模型:

  • 一个有许多
  • 有许多单元格
以“面向对象的方式”处理这些类的首选接口是什么

1-提供对属性/单元格的访问(不一定公开底层数据结构,但创建例如类RowCollection…)

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-以上任何一项…

这取决于您打算如何访问行/单元格


没有一种正确的方法可以做到这一点-您需要决定如何访问它们,并构建对象以使用它们的方式公开它们。

这取决于您打算如何访问行/单元格


没有一种正确的方法可以做到这一点——你需要决定如何访问它们,并构建你的对象,以使用它们的方式公开它们。

这在很大程度上取决于数据以及你打算如何使用数据。 用户需要单个单元格吗?单个行/列?行/列的子部分

可能最干净的方法是提供函子接口。提供一个或多个函数,这些函数将在每个元素上或在函子中定义的子集上运行函子


如果用户需要访问复杂的单元格组合,这可能会不太好。这在很大程度上取决于数据以及您计划如何处理数据。 用户需要单个单元格吗?单个行/列?行/列的子部分

可能最干净的方法是提供函子接口。提供一个或多个函数,这些函数将在每个元素上或在函子中定义的子集上运行函子


如果用户需要访问复杂的单元格组合,那么这可能不太好。

我认为答案很大程度上是主观的。如果我们以您的示例为例,提供类的方法或属性以通过行/列引用返回值可能是合适的。这些可以同时实施,例如:

myClass.Row[x].Column[y]    
myClass.Column[y].Row[x]    
myClass.Cell[x,y]
如果数据“行”是有限的,您还可以决定最好直接公开列表:

myClass.SomeArrayOfValues[itemIndex]
我注意到您使用了诸如“tables”和“rows”之类的短语,因此我可能会假设您希望让您的类表示一个数据库或类似的结构,但是您可能会发现,虽然这样存储数据可能会很有效,但您可能会发现以另一种形式公开数据对您的类用户来说可能更有意义


最后,您选择这样做的方式应该真正设计为反映数据本身和您正在建模的系统的目的,这只能根据具体情况来决定

我认为答案很大程度上是主观的。如果我们以您的示例为例,提供类的方法或属性以通过行/列引用返回值可能是合适的。这些可以同时实施,例如:

myClass.Row[x].Column[y]    
myClass.Column[y].Row[x]    
myClass.Cell[x,y]
如果数据“行”是有限的,您还可以决定最好直接公开列表:

myClass.SomeArrayOfValues[itemIndex]
我注意到您使用了诸如“tables”和“rows”之类的短语,因此我可能会假设您希望让您的类表示一个数据库或类似的结构,但是您可能会发现,虽然这样存储数据可能会很有效,但您可能会发现以另一种形式公开数据对您的类用户来说可能更有意义


最后,您选择这样做的方式应该真正设计为反映数据本身和您正在建模的系统的目的,这只能根据具体情况来决定

根据您对用法的评论,“主要用例是添加、排序和迭代值”,我可能不允许检索单个元素,而是让用户提供一个函子来处理存储的元素。用C++表示。< /P>
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);
}
类表
{
公众:
表();
//表(unsigned int numberOfRows,unsigned int numberOfCells);
void addRow();
void addCell();
//如果超出范围,则抛出异常;如果用户不需要,则不提供这些函数。
无效删除行(无符号整数行数);
void removeCell(无符号整数行数,无符号整数单元格数);
//迭代整个表
模板
void forEach(Pred-Pred);
//迭代特定行,如果行超出范围,则抛出异常。
模板
void forEach(无符号整数行,Pred-Pred);
}
您必须根据您输入/更新数据的计划定制添加/更新/删除呼叫。此设计强烈面向操作元素集合。这种设计的优点在于,您没有将用户提交给表示表的特定底层结构。这符合得墨忒尔定律


如果您需要访问特定的单个元素,您将需要一种不同的方法,或者将其作为这里已经提供的方法的扩展

根据您对用法的评论,“主要用例是添加、排序和迭代值”,我可能不允许检索单个元素,而是让用户提供一个函子来处理存储的元素。用C++表示。< /P>
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);
}
类表
{
公众:
表();
//表(unsigned int numberOfRows,unsigned int numberOfCells);
void addRow();
void addCell();
//如果超出范围,则抛出异常;如果用户不需要,则不提供这些函数。
无效删除行(无符号整数行数);
void removeCell(无符号整数行数,无符号整数单元格数);
//迭代整个表
模板
void forEach(Pred-Pred);
//迭代特定行,如果行超出范围,则抛出异常。
模板
void forEach(无符号整数行,Pred-Pred);
}
你必须
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)"
person.order_drink_from(bar)