我正在尝试重构一个解析文件的方法。为了支持任意大小的文件,该方法使用具有固定缓冲区的分块方法。
public int Parse()
{
// Get the initial chunk of data
ReadNextChunk();
while (lengthOfDataInBuffer > 0)
{
[parse through contents of buffer]
if (buffer_is_about_to_underflow)
ReadNextChunk();
}
return result;
}
上面的伪代码是类中唯一的公共非静态方法(构造函数除外)的一部分。该类仅用于封装在解析文件时必须跟踪的状态。此外,一旦在类上调用此方法,就不能/不应该再次调用它。因此使用模式如下所示:
var obj = new MyClass(filenameToParse);
var result = obj.Parse();
// Never use 'obj' instance again after this.
由于某种原因,这让我感到困惑。我可以将MyClass构造函数设为私有,将Parse更改为静态方法,并使Parse方法新建一个Parse作用域的实例。这将产生如下的使用模式:
var result = MyClass.Parse(filenameToParse);
MyClass不是静态类;我仍然需要在Parse方法中创建一个本地实例。
由于这个类只有两种方法;解析和(私有)ReadNextChunk,我想知道通过在Parse中嵌入ReadNextChunk逻辑作为匿名方法将Parse写为单个静态方法可能不是更清晰。可以将状态的其余部分作为局部变量而不是成员变量进行跟踪。
当然,我可以通过将ReadNextChunk作为静态方法,然后传递所有上下文来完成类似的事情,但我记得anon方法可以访问外部范围。
这是一种奇怪而丑陋,还是一种合理的做法?
答案 0 :(得分:4)
这可能更适合代码审查。
但是,这些是我对你的设计的评论:
我认为只使用过一次的obj实例并不重要。如果你对它有所了解,有两种方法可以欺骗它:
使用其他方法,例如:
public int Parse()
{
var obj = new MyClass(filenameToParse);
return obj.Parse();
}
使MyClass
实现IDisposable并将其包装在using语句中。我不建议这样做,因为IDisposable通常在Dispose()
方法
我认为最好将MyClass
中的Parse
接受参数改为Parse(string fileNameToParse)
。它将MyClass
作为服务类,使其成为无状态,可重复使用和可注射的。
关于对静态类的影响。首先,它会在您的消费者和MyClass
之间添加耦合。有时,如果您想在不使用consumer
解析器的情况下测试/单元测试MyClass
,则很难/不可能将MyClass
模拟为您想要的内容。
答案 1 :(得分:0)
您只需要一个静态解析方法来创建实例,就像您在问题中建议的那样
public class MyClass
{
// your existing code.... but make the members and constructor private.
public static int Parse(string filenameToParse)
{
return new MyClass(filenameToParse).Parse();
}
}
然后
就像你建议的那样使用它......
var result = MyClass.Parse(filenameToParse);
答案 2 :(得分:0)
MyClass不是静态类;我还是要创建一个本地的 Parse方法中的实例。
您不需要静态类来利用静态方法。例如,这很好用:
public class MyClass
{
public static string DoStuff(string input)
{
Console.WriteLine("Did stuff: " + input);
return "Did stuff";
}
}
public class Host
{
public void Main()
{
MyClass.DoStuff("something");
}
}