Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 是否有任何面向对象的方法或模式来处理表格数据?_Oop_Design Patterns_Tabular - Fatal编程技术网

Oop 是否有任何面向对象的方法或模式来处理表格数据?

Oop 是否有任何面向对象的方法或模式来处理表格数据?,oop,design-patterns,tabular,Oop,Design Patterns,Tabular,表格数据所需的操作: 用行切换列 在特定位置添加列/行 将列/行/单元格标记为属于同一组并获取特定组 更改列/行顺序 按行/列计算总计 转换为透视表 将结果输出为HTML/JSON 使用表格数据时,什么是好的面向对象方法?我认为首先需要一个好的/适当的数据结构来保存/操作表格数据。 这取决于您可以具有的特定要求,例如表的大小、性能要求等 假设您将使用一些Matrix类,该类提供对表的低级操作(设置单元格值、添加/删除行、转置等) 此类将使用基本数据结构进行操作,例如,它可能有get\u ro

表格数据所需的操作:

  • 用行切换列
  • 在特定位置添加列/行
  • 将列/行/单元格标记为属于同一组并获取特定组
  • 更改列/行顺序
  • 按行/列计算总计
  • 转换为透视表
  • 将结果输出为HTML/JSON

使用表格数据时,什么是好的面向对象方法?

我认为首先需要一个好的/适当的数据结构来保存/操作表格数据。 这取决于您可以具有的特定要求,例如表的大小、性能要求等

假设您将使用一些
Matrix
类,该类提供对表的低级操作(设置单元格值、添加/删除行、转置等)

此类将使用基本数据结构进行操作,例如,它可能有
get\u row
方法,该方法将返回一个数字列表。 例如,现在我们可以获取此列表中的值的摘要,但我们不能仅更改某些列表项,并将此更改反映在父矩阵中(行数据与父矩阵结构断开连接)

现在我们可以在这个
矩阵
类的基础上构建我们的结构,我们的两个目标是:

1) 为了让用户更方便,一些“便利”可以是:

  • 行、列和单元格对象都连接到父
    对象(如果我们修改行项目,它将反映在父表和其他行/列/单元格对象中)
  • 我们可以生成相同数据的不同视图(例如透视表)
  • 我们可以使用特殊的列/行寻址系统(例如,行使用1、2、3,…,列使用A、B、C,…)
2) 隐藏用于存储表数据的实际数据结构

  • 这样,我们就可以在不破坏用户代码的情况下独立地处理
    矩阵
    实现
  • 我们甚至可以用不同的结构来替换它(也许我们发现了更快或占用更少内存的东西),或者我们可以针对不同的情况使用不同的实现(例如桌面和移动应用程序)
这是我将首先介绍的近似类结构(类似python的伪代码):

矩阵
类是一种低级数据结构,不应作为公共接口的一部分

公共接口由以下
类和其他相关类表示:

class Table:
    """The user-level interface to work with table data."""

    constructor():
        """Initializes Matrix object."""
        # The "_data" object is private, only to be used internally.
        self._data = Matrix()

    row(int number) -> Row:
        """Returns `Row` object by row number (1, 2, 3, ...)."""
        row = Row(self, number)
        self.attach(row)
        return row

    column(string name) -> Column:
        """Returns `Column` object by string name (A, B, C, ...)."""
        column = Column(self, name)
        self.attach(column)
        return column

    cell(int row_number, string col_name) -> Cell:
        """Returns `Cell` object by string name (A, B, C, ...)."""
        cell = Cell(self, row_number, col_name)
        self.attach(cell)
        return column

    attach(Observer observer):
        """Register an observer to be notified when Table state was changed."""
        self.observers.append(observer)

    _notify():
        """Notify all dependent objects about the state change."""
        for observer in self.observers:
            observer.update()

    ...
要使
行/
列/
单元格
对象保持同步,我们可以使用该模式

这里的
主题
/
/
单元格
观察者
。 一旦
(和基础数据)的状态发生更改,我们就可以更新所有依赖对象

class Row(Observable):
    """Table row object."""

    constructor(Table parent, int index):
        self.parent = parent
        self.index = index
        self._data = None
        self.update()

    update()
        """Update row data.

        Fetches the `list` or row values from the `Matrix` object.
        """
        # Note: we have two choices here - the `Row`, `Column` and `Cell` objects
        # can either access `Table._data` property directly, or `Table` can provide
        # proxy methods to modify the data (like `_get_value(x, y)`); in both cases
        # there is a private interface to work with data used by `Table`, `Row`,
        # `Column` and `Cell` classes and the implementation depends on the language,
        # in C++ these classes can be friends, in python this can be just a documented
        # agreement on how these classes should work.
        # See also the comment in the `remove` method below.
        self._data = parent._data.get_row(index)

    sum():
        """Returns sum of row items."""
        sum = 0
        for value in self._data:
            sum += value
        return sum

    cell(string col_name):
        """Returns cell object."""
        return parent.cell(self.index, col_name)

    remove():
        """Removes current row."""
        # Here we access `parent._data` directly, so we also have to
        # call `parent._notify` here to update other objects.
        # An alternative would be a set of proxy methods in the `Table` class
        # which would modify the data and then call the `_notify` method, in such case 
        # we would have something like `self.parent._remove_row(self.index)` here.
        self.parent._data.remove_row(self.index)
        self.parent._notify()
        self.parent.detach(self)
单元格
类相似,
将保存列数据,
单元格
将包装单元格值。 用户级别的使用情况如下所示:

table = Table()
# Update table data
table.cell(1, "A").set(10)
table.cell(1, "B").set(20)
table.row(1).cell("C").set(30)
# Get row sum
sum = table.row(1).sum()

# Get the table row
row = table.row(1)
# The `remove` operation removes the row from the table and `detaches` it,
# so it will no longer observe the `table` changes.
row.remove()
# Now we have the detached row and we can put it into another table,
# so basically we cut-and-pasted the row from one table to another
another_table.add_row(row)
使用这种方法,您可以非常轻松地实现复制、剪切、粘贴等操作。您也可以在这里应用,并将这些操作提取到小类中。通过这种方式,实现撤销和重做也将非常容易

数据透视表
表也可以是一种特殊的
可观察的
。 根据对数据透视表功能的要求,您可能会发现配置数据透视表很有用。 大概是这样的:

pivotBuilder = PivotBuilder(table)
# Group by column "A" and use `SumAggregator` to aggregate grouped values.
pivotBuilder.group_by_column("A", SumArggregator())  # or maybe pivotBuilder.groupBy(table.column("A"))
pivotTable := pivotBuilder.get_result()
要将表导出为不同格式的类可能不必是可见的,因此它们只需包装
对象并将其转换为适当的格式:

json_table = JsonTable(table)
data = json_table.export()
当然,以上只是许多可能的实现选项之一,根据您的具体需求,将它们视为有用(或无用)的想法


您可能会在中找到更多想法。

您是否要求数据模型来实现上述功能?@cassandrad Yes和/或一些想法。
json_table = JsonTable(table)
data = json_table.export()