0

我正在编写一个日志文件解码器,它应该能够读取许多不同的文件结构。我的问题是如何最好地表示这些数据。我正在使用 C#,但对 OOP 很陌生。

示例:日志文件具有一系列传感器值。一个传感器读数可以称为A,另一个称为B。显然,有不止 2 种条目类型。在不同的日志文件中,它们可以存储为 ABABABABAB 或 AAAAABBBBB。

我正在考虑将其描述为条目块。所以在第一种情况下,一个块将是“AB”,有 5 个块。在第二种情况下,第一个块是'A',读取5次。这后面是一个'B'块,读取5次。

这是相当简单的(实际上有 40 种不同类型的日志文件,每个块中最多包含 40 个传感器值)。没有日志有超过 300 个块。

目前,我将所有这些存储在数据表中。每个条目都有一个列,具有要阅读的数量的属性。如果设置为 -1,它将继续到块中的下一列。如果没有,它将假定它已到达块的末尾。

这一切似乎都很笨拙。任何人都可以提出更好的方法吗?

4

4 回答 4

1

我认为你应该先从这里开始,然后在这里学习一点面向对象编程是什么。在学习 OOP 时不要担心您当前的问题。

在学习 OO 概念时,您应该开始了解代码不是数据,数据不是代码。从 OOP 立场如何表示数据并不重要。您可以编写 OO 代码来消费您的数据,或者您可以编写程序代码来消费您的数据,这部分与数据的格式无关。

那么回到你的问题

我的问题是如何最好地表示这些数据

这取决于您的需求。什么是写日志文件?你能控制作者和读者吗?如果我这样做了,我将依靠构建内置的序列化方法来最小化我需要编写的代码量。日志文件真的会很长吗?如果是这样,您描述的“数据表”方法通常会更好。如果日志文件的文件大小不会很大,那么 XML 真的很容易使用。

于 2011-07-20T14:33:11.700 回答
0

非常基本和直接:

  1. 定义一个IEnrty带有属性的接口,例如string EntryBlock, int Count
  2. 定义一个代表Entry和实现的类IEntry
  3. 进行二进制序列化的代码应该知道接口,例如它应该引用IEnumerable<IEntry>
  4. Entry可以重写ToString()以返回类似 [ABAB-2] 的东西,如果这在序列化时会有所帮助
  5. 如果有帮助,接口IEntry可以提供方法 void ,请自行决定CreateFromRawString(string rawDataFromLog)

如果您想了解更多信息,请分享您用于序列化/反序列化的代码

于 2011-07-20T15:20:06.257 回答
0

至于 OOP,你想学习SOLID

我建议您使用测试驱动开发来构建它。

从小处着手,使用您的日志数据的一个简单片段,然后编写一个类似的测试(您会根据经验找到更好的方法并将其应用于您的情况):

[Test]
public void ReadSequence_FiveA_ReturnsProperList()
{
  // Arrange
    string sequenceStub = "AAAAA";

    // Act
    MyFileDecoder decoder = new MyFileDecoder();
    List<string> results = decoder.ReadSequence(sequenceStub);

    // Assert
    Assert.AreEqual(5, results.Count);
    Assert.AreEqual("A", results[0]);
}

该测试代码片段只是一个起点,我试图在断言中相当冗长。随着时间的推移,你可以想出更多创造性的方法。关键是从小处着手。一旦此测试通过,添加另一个测试,在其中混合“AB”并更改您的解码器以正确处理此问题。最终,您将拥有处理不同格式的大量测试。使用 TDD,您将走上正确使用 SOLID 的道路。每当您发现无法测试的东西时,您应该查看规则,看看您是否不能使其更简单并注入依赖项。

最终你会陷入嘲笑。例如,您可能会发现您宁愿为您的MyFileDecoder类注入能够读取您的日志文件的依赖项的能力。在这种情况下,您将创建一个模拟对象并将其传递给构造函数,并将模拟设置为在sequenceStub调用方法时返回。

于 2011-07-20T14:50:54.160 回答
0

除了 Bob 提供的内容之外,我强烈推荐Head First Design Patterns作为 C# 程序员对 OO 的温和但稳健的介绍。示例使用 Java 编写,可轻松转换为 C#。

于 2011-07-20T14:51:36.500 回答