2009-06-09 45 views
2

我不确定我是否滥用这里的枚举。也许这不是最好的设计方法。枚举过度使用?

我有一个枚举,它向执行批处理文件的方法声明了可能的参数。

public enum BatchFile 
{ 
    batch1, 
    batch2 
} 

然后我有我的方法:

public void ExecuteBatch(BatchFile batchFile) 
{ 
    string batchFileName; 
    ... 
    switch (batchFile) 
     { 
      case BatchFile.batch1: 
       batchFileName = "Batch1.bat"; 
       break; 
      case BatchFile.batch2: 
       batchFileName = "Batch2.bat"; 
       break; 
      default: 
       break; 
     } 
    ... 
    ExecuteBatchFile(batchFileName); 
} 

所以我在想,如果这是声音设计。

我想另一种选择是创建一个字典<>在构造是这样的:

Dictionary<BatchFile, String> batchFileName = new Dictionary<BatchFile, string>(); 
batchFileName.Add(BatchFile.batch1, "batch1.bat"); 
batchFileName.Add(BatchFile.batch2, "batch2.bat"); 

然后,而不是使用switch语句我只想去:

public void ExecuteBatch(BatchFile batchFile) 
{ 
    ExecuteBatchFile(batchFileName[batchFile]); 
} 

我猜测后者是更好的方法。

回答

8

我可能会去设计这些方针:

public interface IBatchFile 
{ 
    void Execute(); 
} 

public class BatchFileType1 : IBatchFile 
{ 
    private string _filename; 

    public BatchFileType1(string filename) 
    { 
     _filename = filename; 
    } 

    ... 

    public void Execute() 
    { 
     ... 
    } 
} 

public class BatchFileType2 : IBatchFile 
{ 
    private string _filename; 

    public BatchFileType2(string filename) 
    { 
     _filename = filename; 
    } 

    ... 

    public void Execute() 
    { 
     ... 
    } 
} 

其实,我解压任何共同的功能BatchFile基类

+0

下载者请留下评论。谢谢。 – 2009-06-09 05:55:18

+0

在德国,这被称为“mit Kanonen auf Spatzenschießen”:) – VVS 2009-06-09 06:11:31

0

ExecuteBatch是否真的有必要仅在有限数量的可能文件名上工作? 你为什么不只是使它

public void ExecuteBatch(string batchFile) 
{ 
    ExecuteBatchFile(batchFile); 
} 
+0

因为,这个被编译成一个DLL,并通过其他消费不知道批处理文件名的人。所以使用Enum为它们提供了所有可选择的选项。 – 2009-06-09 05:21:05

2

我觉得后一种方法更好,因为它分离出来的担忧。您有一种方法专用于将枚举值与物理路径关联,并提供一个用于实际执行结果的单独方法。第一次尝试稍微混合了这两种方法。

但我认为使用switch语句来获取路径也是一种有效的方法。枚举在很多方面都意味着被转换。

0

后一种情况的问题是,如果有东西传递了不在字典内的无效值。 switch语句中的缺省值提供了一个简单的方法。

但是......如果你是枚举将有很多条目。字典可能是更好的方法。

无论采用哪种方法,我都会推荐一些方法来保护输入值,以免在ammoQ的回答中导致错误的错误。

3

我会亲自使用静态类常量在这种情况下:

public static class BatchFiles 
{ 
    public const string batch1 = "batch1.bat"; 
    public const string batch2 = "batch2.bat"; 
} 
0

第二种方法更好,因为它链接批处理文件对象(枚举)与字符串..

但是在谈论设计时,将枚举和字典分开是不太好的;你可以认为这是一种替代方案:

public class BatchFile { 
    private batchFileName; 

    private BatchFile(String filename) { 
     this.batchFileName = filename; 
    } 
    public const static BatchFile batch1 = new BatchFile("file1"); 
    public const static BatchFile batch2 = new BatchFile("file2"); 

    public String getFileName() { return batchFileName; } 
} 

您可以选择保留构造私有的,还是公开发布。

干杯,

jrh。

1

使用枚举是确定的,如果您不需要添加新的批处理文件,而无需重新编译/重新部署应用程序。不过我觉得最灵活的方法是在你的配置定义键/文件名对的列表。

要添加新的批处理文件,你只需将其添加到配置文件/重启/你能告诉你的用户的关键。你只需要处理未知的密钥/文件没有发现异常。

4

如果你突然需要第三个批处理文件?你必须修改你的代码,重新编译你的库以及每个使用它的人都必须这样做。

每当我发现自己写的魔法字符串可能会改变,我认为将它们放入一个额外的配置文件,保持数据输出的代码。

0

第一个解决方案(开关)是简单和直接的,你真的不必使其比这更复杂。

使用枚举可以是使用一个返回一个类的实例与相关数据的属性集的替代。这是相当可扩展的;如果稍后需要Execute方法对某些批处理进行不同的处理,则可以让属性返回具有不同实现的子类,并且仍以相同的方式调用它。

public class BatchFile { 

    private string _fileName; 

    private BatchFile(string fileName) { 
     _fileName = fileName; 
    } 

    public BatchFile Batch1 { get { return new BatchFile("Batch1.bat"); } } 
    public BatchFile Batch2 { get { return new BatchFile("Batch2.bat"); } } 

    public virtual void Execute() { 
     ExecuteBatchFile(_fileName); 
    } 

} 

用法:

BatchFile.Batch1.Execute(); 
3

如果你想使用一个枚举,那么你可能要考虑使用属性,这样你就可以对元素存储更多inforation(如文件名)。

下面是一些示例代码来演示如何声明属性:

using System; 

public enum BatchFile 
{ 
    [BatchFile("Batch1.bat")] 
    batch1, 
    [BatchFile("Batch2.bat")] 
    batch2 
} 

public class BatchFileAttribute : Attribute 
{ 
    public string FileName; 
    public BatchFileAttribute(string fileName) { FileName = fileName; } 
} 

public class Test 
{ 
    public static string GetFileName(Enum enumConstant) 
    { 
     if (enumConstant == null) 
      return string.Empty; 

     System.Reflection.FieldInfo fi = enumConstant.GetType().GetField(enumConstant.ToString()); 
     BatchFileAttribute[] aattr = ((BatchFileAttribute[])(fi.GetCustomAttributes(typeof(BatchFileAttribute), false))); 
     if (aattr.Length > 0) 
      return aattr[0].FileName; 
     else 
      return enumConstant.ToString(); 
    } 
} 

要获取文件名只需拨打:

string fileName = Test.GetFileName(BatchFile.batch1);