我正在编写一些导入文件的代码,这些代码将根据描述文件布局的模板导入分隔文件或固定宽度文件。
我创建了一个接口IFileTemplate:
public interface IFileTemplate
{
string Name { get; set; }
bool IgnoreEmptyLines { get; set; }
}它由DelimitedFileTemplate类和FixedWidthFileTemplate类使用。
我还有一个接口,用于指定组成模板的每个列:
public interface IFileTemplateColumn
{
int ID { get; set; }
string Name { get; set; }
bool Ignore { get; set; }
}然后,DelimitedTemplateColumn类和FixedWidthTemplateColumn类使用这个接口。
由于DelimitedFileTemplate和FixedWidthFileTemplate类都有一个列列表,所以我已经将该列表作为IFileTemplate列的成员:
List<IFileTemplateColumn> Fields { get; set; }我的问题是,当我在DelimitedFileTemplate和FixedWidthFileTemplate类中实现列表时,例如:
public class FixedWidthFileTemplate : IFileTemplate
{
public int ID { get; set; }
public string Name { get; set; }
public List<FixedWidthFileTemplateColumn> Fields { get; set; }
}如果我尝试用List<DelimitedFileTemplateColumn>或List<FixedWidthFileTemplateColumn>实现List<DelimitedFileTemplateColumn>或List<FixedWidthFileTemplateColumn>,那么编译器会抱怨它们与List<IFileTemplateColumn>不匹配。
我可以理解这一点,但是在ITemplateInterface中没有列列表似乎是错误的。我能想到的唯一解决办法是让分隔的类和FixedWidth类使用List<IFileTemplateColumn>,并让属性getter将列表转换为分隔的或固定宽度的列列表,但这似乎有一点代码气味。有人能提出更好的方法来做这件事吗?
发布于 2014-01-31 12:05:56
泛型是解决这个设计问题的合适且无臭味的解决方案:
interface IFileTemplate<T> where T : IFileTemplateColumn
{
List<T> Fields { get; set; }
}DelimitedFileTemplate实现了IFileTemplate<DelimitedFileTemplateColumn>等等。
也许文件模板之间的所有差异都可以由IFileTemplateColumn明智地定义,并且您可以简化FileTemplate<IFileTemplateColumn>在每一个FileTemplateColumn类关系中嵌入一个FileTemplate类的情况。
更新
至于工厂方法:IFileTemplate<IFileTemplateColumn> Create:如果假定该方法的使用者能够访问列列表,则方法签名必须包含具体的ColumnTemplate。例如:
DelimitedFileTemplate Create或
interface IFactory<T> where T : IFileTemplateColumn
{
IFileTemplate<T> Create();
}
class DelimitedFactory : IFactory<DelimitedFileTemplateColumn>
{
IFileTemplate<DelimitedFileTemplateColumn> Create()
{
return new DelimitedFileTemplate();
}
}如果该方法的使用者对列表不感兴趣,请引入一个更通用的接口(非常类似于IEnumerable<T> : IEnumerable):
interface IFileTemplate { ... }
interface IFileTemplate<T> : IFileTemplate where T : IFileTemplateColumn
{
List<IFileTemplateColumn> Columns { get; set; }
}然后,无论列是什么,IFileTemplate Create()方法都可以返回任何具体的FileTemplate。
我使用过这种泛型,它们可能会传播(在本例中,列层次结构将在FileTemplate层次结构中复制,并可能在工厂层次结构中复制)。有时,这会暴露出设计中的一些缺陷。如果您能够明智地将IFileTemplate层次结构划分为一个基本的参数化FileTemplate类,那么这当然是可行的。这就是我经常使用的方法:定义最小的部分,如果层次结构倾向于重复,算法的某些部分可能会被移动到“最小的部分-类”。
https://stackoverflow.com/questions/21479533
复制相似问题