代码之家  ›  专栏  ›  技术社区  ›  Filipe Miguel Fonseca

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

  •  0
  • Filipe Miguel Fonseca  · 技术社区  · 15 年前

    想象一下以下模型:

    • 桌子
    • A. 一行 细胞

    以“面向对象的方式”处理这些类的首选接口是什么?

    / (不一定公开底层数据结构,但创建例如类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) {}
    ...
    

    5 回复  |  直到 15 年前
        1
  •  1
  •   S.Robins    15 年前

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

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

    如果数据“行”是有限的,您还可以决定最好直接公开列表:

    myClass.SomeArrayOfValues[itemIndex]
    

        2
  •  1
  •   FP.    15 年前

    根据您对用法的评论,“主要用例是添加、排序和迭代值”,我可能不允许检索单个元素,而是让用户提供一个函子来处理存储的元素。用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);
    }
    

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

        3
  •  1
  •   Wayne Conrad    15 年前

    想想你能摆脱多少吸气剂和定位器。一个健壮的OO设计需要对象之间相互输出行为,而不是数据。例如,人的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:
    

    下面是一些使用Person的(伪)代码:

    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)"
    

    person.order_drink_from(bar)
    

    我不会说在OO程序中永远不需要getter。但我要说的是:尤其是二传手,应该让你重新思考设计。每次你写一个getter或setter时,让你脑后的声音问你是否有办法让对象导出行为而不是数据。

        4
  •  0
  •   Oded    15 年前

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

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

        5
  •  0
  •   Sliq    15 年前

    用户需要单个单元格吗?单个行/列?行/列的子部分?

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

    推荐文章