这个班级最好的设计是什么?
假设这个类:
public class Logger
{
static TextWriter fs = null;
public Logger(string path)
{
fs = File.CreateText(path);
}
public static void Log(Exception ex)
{
///do logging
}
public static void Log(string text)
{
///do logging
}
}
并且我必须像这样使用它:
Logger log = new Logger(path);
然后使用 Logger.Log() 来记录我想要的内容。我只使用一个记录器。 问题是:这是一个好的设计吗?实例化一个类然后总是调用它的静态方法?任何更好设计的建议都值得赞赏。
根据 Marc 的回答进行编辑:
我在 Log 的最后一行刷新,不需要我在打开文件时读取文件,文件未完全关闭的问题是正确的。这个类只是满足我的要求,不需要线程安全。我只想阅读实例化部分,我应该进入你说的 SetPath,有什么关闭文件的建议吗?
assume this class:
public class Logger
{
static TextWriter fs = null;
public Logger(string path)
{
fs = File.CreateText(path);
}
public static void Log(Exception ex)
{
///do logging
}
public static void Log(string text)
{
///do logging
}
}
and I have to use this like:
Logger log = new Logger(path);
and then use Logger.Log()
to log what I want. I just use one Logger.
the question is: is this a good design? to instantiate a class and then always call it's static method? any suggestion yield in better design is appreciated.
Edit based on Marc's answer:
I flush on the last line of Log and there is no need for me to read the file while it is open, the issue with file not cleanly closed is right. this class simply satisfy my requirements and there is no need to be thread safe for it. I just want to get read of the instantiation part, I should get into the SetPath you said, any suggestion for closing file?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,仅仅为此而有一个构造函数是糟糕的设计。只能调用一次(否则抛出异常)的静态
SetPath
方法似乎更好。您可以在应用程序启动等过程中设置路径。然后您可以将其设为静态类,或者如果需要满足某些基于接口的场景,则将其设为单例。
接下来:您必须在此处添加同步!那不是线程安全的。如果两个线程尝试同时记录,我预计这会严重崩溃。它不需要很复杂;最简单的:(
但请注意,这可能会产生一些阻塞成本;可以通过更复杂的代码来改进 - 见下文)
现有的日志记录库会考虑更多问题 - 文件分区、异步(以阻止你的代码被被IO阻塞)、批处理等;为什么不只使用其中之一呢?特别是,此时您的文件不会在应用程序退出时完全关闭,不会定期刷新,并且大部分时间都会保持文件锁定。不好。
Yes, having a constructor just for this is bad design. A static
SetPath
method that can only be called once (else throws an exception) would seem better. You would set the path during app-startup, etc.Then you can either make it a
static class
, or a singleton if it is required to satisfy some interface-based scenario.Next: you must add synchronisation here! That is not thread safe. If two threads attempt to log at the same time, I would expect this to collapse horribly. It doesn't need to be complex; at the simplest:
(but note that this may incur some blocking costs; which can be improved with more sophisticated code - see below)
There are existing logging libraries that will think of lots more issues - file partitioning, async (to stop your code being blocked by IO), batching, etc; why not just use one of them? In particular, at te moment your file will not be cleanly closed at app-exit, doesn't flush regularly, and will keep the file locked most of the time. Not good.
不,这没有意义。每次实例化 Logger 时,静态 TextWriter 都会被覆盖,这会影响该类的所有使用者。如果您想保留实例构造函数,那么您应该将 TextWriter 设为实例字段,并且方法应该是实例方法。
作为替代方案,您可能需要考虑使用 log4net,它将为您完成此类日志记录工作。
No, this doesn't make sense. Each time a Logger is instantiated, the static TextWriter will be overwritten, which will affect all consumers of the class. If you want to keep the instance constructor then you should make the TextWriter an instance field and the methods should be instance methods.
As an alternative, you may want to consider using log4net, which will do this kind of logging work for you.
我认为你应该使用静态属性使整个类静态,从而允许你设置日志路径。
I think you should make whole class static with static property allowing you to set up the log path.