2009-08-12 40 views
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)。

回答

0

現在我已經寫了一些轉換,我傾向於按照類的映射方法。我必須能夠針對僞造模型運行單元測試,以確保文件正確構建(根據已知的良好示例文件對其進行測試)。

我一直在使映射委託私人到他們所屬的「工作流」類(每個模型/文件一個「工作流程」)。我必須讓它們公開以單元測試它們,或者輸出中間文件內容(工作流將完成的文件保存到數據存儲區)。

每個類的映射似乎有更多的可測試性和可分解性。

+0

我也在考慮重寫每個具體類MapEntity(delegate)中的抽象屬性。覆蓋方法Map(T)的效果相同。不同的外觀。 – 2009-09-04 13:33:45

1

您是否必須爲每個可能的映射實際創建具體的子類?也許可以使用XML文件(或數據庫)來描述每種文件的格式/內容。然後您將擁有一個採用「FileType」鍵的類,並使用XML中的格式化信息來確定如何爲該FileType構建文件。

+0

我認爲這是與使用映射委託相同的解決方案(意圖)。 – 2009-08-12 18:11:50

+0

@ajmastrean - 現在我更仔細地看它,你是對的。至於如何在不知道「T」是什麼的情況下做到這一點 - 你只需要使用反射來獲得所有的屬性,所以你真的不需要知道對象的類型。 – 2009-08-12 20:36:43