0

レガシーアプリケーションで使用するために、(さまざまなデータベース/テーブルからの)エンタープライズデータをそれぞれ特定の形式のフラットファイルに変換する必要があるメンテナンスアプリケーションがあります。私は次のようなデータモデルを持っています

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

データソースからこれらのレコードのサブセットまたはすべてを選択します。また、各エンティティをファイルの1行にマップする必要があります。これには、データの調整(パディング、変換、または処理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[]エンコーディングは単純なので、いくつかの基本クラスが役立つと思います。具象クラスは、(抽象メソッドを呼び出すのではなく)基本クラスにデリゲートプロパティを設定する必要がありますか?メソッドのtypeパラメーターを保持する必要がありますか(そしてそれは基本/具象クラスにどのように影響しますか)?

私はどんな解決策も求めています。私の主な目標は、メンテナンスのしやすさです。現在12個のモデル/ファイルがあり、これは最大21個まで増える可能性があります。任意のファイルに任意のヘッダー/フッター行を挿入する必要がある場合があります(これが、オーバーライド可能な基本クラスメソッドであるMapが好きな理由です)。

4

2 に答える 2

1

可能なマッピングごとに具体的なサブクラスを実際に作成する必要がありますか? おそらく、代わりに XML ファイル (またはデータベース) を使用して、各種類のファイルの形式/内容を記述することができます。次に、「FileType」キーを受け取り、XML からのフォーマット情報を使用してその FileType のファイルを構築する方法を決定する単一のクラスを作成します。

于 2009-08-12T15:26:25.330 に答える
0

いくつかの変換を記述したので、クラスごとのマッピングアプローチに傾倒しています。ファイルが適切にビルドされていることを確認するために、偽のモデルに対して単体テストを実行できる必要があります(既知の良好なサンプルファイルに対してテストします)。

私はマッピングを作成してきました-デリゲートは、それらが属する「ワークフロー」クラスにプライベートになります(モデル/ファイルごとに1つの「ワークフロー」)。それらを単体テストするために公開するか、中間ファイルの内容を出力する必要があります(ワークフローは完成したファイルをデータストアに保存します)。

クラスごとのマッピングは、はるかにテスト可能で分解可能のようです。

于 2009-08-13T19:35:22.533 に答える