在构造函数中创建目录是个坏主意吗?
本文关键字:构造函数 创建目录 | 更新日期: 2023-09-27 17:50:24
一开始看起来很自然——如果一组目录不存在,在它们上面工作的对象将无法履行它的契约。因此,在构造函数中,我有一些逻辑来检查某些目录是否存在,如果不存在则创建它们。虽然这个对象实际上还不是单例,但它的使用方式与单例类似。
构造函数是这种设置逻辑的坏地方吗?
这个类叫做FileGetter。它抽象地从远程服务器获取特定的文件,提取它们,准备文件并将它们放在另一个目录中,其中第二个类将是文件系统监视/处理数据。
从控制反转或依赖反转的角度来看,是的,这是不正确的。
你声明在目录上工作的对象如果目录不存在就不能完成它的工作。我将把目录的提供和检查/创建抽象为另一个抽象,然后将该抽象的实现传递给您的对象。
然后,您的对象将简单地从这个抽象中获取目录,并从那里继续。
作为一个例子,这就是我的意思。首先是目录提供程序的抽象,如下所示:
public interface IDirectoryProvider
{
// Gets the full paths to the directories being worked on.
IEnumerable<string> GetPaths();
}
然后是实现。
public sealed class DirectoryProvider
{
public DirectoryProvider(IEnumerable<string> directories)
{
// The validated directories.
IList<string> validatedDirectories = new List<string>();
// Validate the directories.
foreach (string directory in directories)
{
// Reconcile full path here.
string path = ...;
// If the directory doesn't exist, create it.
Directory.CreateDirectory(path);
// Add to the list.
validatedDirectories.Add(path);
}
}
private readonly IEnumerable<string> _directories;
public IEnumerable<string> GetPaths()
{
// Just return the directories.
return _directories;
}
}
最后是处理目录的类,它看起来像这样:
public sealed DirectoryProcessor
{
public DirectoryProcessor(IDirectoryProvider directoryProvider)
{
// Store the provider.
_directoryProvider = directoryProvider;
}
private readonly IDirectoryProvider _directoryProvider;
public void DoWork()
{
// Cycle through the directories from the provider and
// process.
foreach (string path in _directoryProvider.GetPaths())
{
// Process the path
...
}
}
}
我想说这要看情况。一般来说,让对象构造尽可能便宜是个好主意;也就是说,让构造函数包含尽可能少的逻辑。这反对在构造函数中创建目录。另一方面,如果对象在没有目录的情况下确实无法操作,那么尽早失败可能是一个好主意(例如,由于某种原因无法创建目录)。这可以表示在构造函数中创建它们。
我个人可能倾向于而不是在构造函数中创建它们,而是让每个需要它们的方法调用一些创建目录的方法,如果还没有完成的话。
您可以将处理缺少文件夹的逻辑放在类本身或将使用该类的每个代码段中。
选择,真的,取决于你。如果您选择将它放在类本身中,那么构造函数是放置它的完美位置,因为构造函数的作用是"设置"类及其运行所需的所有东西。
我喜欢casperOne的回答。但是我会考虑以下内容:
- 这个对象创建的频率。
- 正在创建多少个目录。
- 创建目录 使用构造函数的频率
- 您需要关于目录状态的反馈吗
- 您是否需要关于目录不存在的原因或任何其他错误的反馈?
- 最后但并非最不重要的是:是否值得努力思考另一种方式?
根据这些问题,您可能会意识到这只是在对象的生命周期中调用一次的情况。它不应该失败,如果它失败了,其他东西就完全出错了。所以我决定把逻辑保持在原来的地方。
如果您有时间并且考虑扩展程序,在其他地方使用类或可能创建更多目录,那么创建一个由casperOne描述的目录提供程序可能是值得的。如果创建的目录不止一个,而且不止一次,例如在程序的每次启动时,并且/或者您可以重用代码并尽可能灵活……那么我强烈建议使用目录提供程序,从而使对象更加灵活,并减少在构造函数中创建SPOF的机会。
我认为构造函数是为这种事情吗?