0

我有一个维护应用程序,它必须将企业数据(来自各种数据库/表)转换为平面文件,每个文件都采用特定格式,供遗留应用程序使用。我有像这样的数据模型

public class StatusCode
{
    public String Id { get; set; }
    public Char Level { get; set; }
    public String Description { get; set; }
}

我将从数据源中选择一些子集或所有这些记录。而且我需要将每个实体映射到文件的一行,这可能需要调整数据(填充、转换或处理null)。

public delegate String MapEntity<T>(T entity);
public MapEntity<StatusCode> MapStatusCode = delegate(StatusCode entity)
{
    return String.Format("{0},{1},{2}",
        entity.Id.PadLeft(3, '0'),
        entity.Level == 'S' ? 0 : 1,
        entity.Description ?? "-");
}

问题是,我如何编写转换类?我是否提供了一个带有映射委托的“DefaultFileCreator”?

public interface IFileCreator
{
    Byte[] Create<T>(MapEntity<T> map, IEnumerable<T> entities);
}

public class DefaultFileCreator : IFileCreator
{
    public Byte[] Create<T>(MapEntity<T> map, IEnumerable<T> entities)
    {
        StringBuilder sb = new StringBuilder();
        foreach (T entity in entities)
            sb.AppendLine(map(entity));

        return Encoding.Default.GetBytes(sb.ToString());
    }
}

...
fileCreator.Create(MapStatusCode, repository<StatusCode>.FindAll());
...

有了这个解决方案,我担心我应该在哪里以及在什么范围内保留映射委托。以及我将如何在不知道的情况下给他们打电话T(如果我需要的话)。

或者,我是否更改接口并要求具体类中的映射?

public interface IFileCreator<T>
{
    Byte[] Create(IEnumerable<T> entities);
}

public abstract class FileCreator : IFileCreator<T>
{
    protected abstract String Map(T entity);

    public Byte[] Create(IEnumerable<T> entities)
    {
        StringBuilder sb = new StringBuilder();
        foreach (T entity in entities)
            sb.AppendLine(Map(entity));

        return Encoding.Default.GetBytes(sb.ToString());
    }
}

public class StatusCodeFile : FileCreator<StatusCode>
{
    public override String Map(T entity)
    {
        return String.Format("{0},{1},{2}",
            entity.Id.PadLeft(3, '0'),
            entity.Level == 'S' ? 0 : 1,
            entity.Description ?? "-");
    }
}

该解决方案在具体类中爆炸,但它们与映射委托一样薄。我觉得IFileCreator<T>和工厂一起工作更舒服。(同样,仅在必要时)。

我假设一些基类很有用,因为StringBuilder循环和Byte[]编码很简单。具体类是否应该在基类中设置委托属性(而不是调用抽象方法)?我应该在方法上保留类型参数(以及这将如何影响基类/具体类)?

我准备好了任何解决方案。我的主要目标是易于维护。我现在有 12 个模型/文件,这可能会增加到 21 个。我可能需要在任何文件中插入任意页眉/页脚行(这就是我喜欢可覆盖的基类方法 Map 的原因)。

4

2 回答 2

1

您是否必须为每个可能的映射实际创建具体的子类?也许可以改用 XML 文件(或数据库)来描述每种文件的格式/内容。然后,您有一个单一的类,它采用“FileType”键并使用 XML 中的格式信息来确定如何为该 FileType 构建文件。

于 2009-08-12T15:26:25.330 回答
0

现在我已经编写了一些转换,我倾向于使用每类映射方法。我必须能够针对伪造的模型运行单元测试,以确保正确构建文件(针对已知的良好示例文件测试它们)。

我一直在将映射委托私有到它们所属的“工作流”类(每个模型/文件一个“工作流”)。我必须将它们公开以对它们进行单元测试,或输出中间文件内容(工作流将完成的文件保存到数据存储中)。

每个类的映射似乎更具可测试性和可分解性。

于 2009-08-13T19:35:22.533 回答