2008-12-02 60 views
8

在此先感謝您的幫助。我想知道是否有可應用於此問題的(設計)模式。設計模式:解析文本文件中類似但不同的模式

我正在尋找解析,處理和提取出相似但格式不同的文本文件中的值。

更具體地說,我構建了一個處理引擎,接受來自多個不同網站的在線撲克手歷史文件並解析出特定數據字段(Hand#,DateTime,Players)。我將需要邏輯來解析每種格式的文件略有不同,但提取的值的處理將相同。

我的第一個想法是創建一個類,它接受每個文件類型的「模式」並相應地解析/處理。我確信有更好的解決方案。

謝謝!

獎勵積分: C#中的任何特定實現提示。

回答

6

這聽起來像是Strategy模式的候選人。在C#中的示例可以找到here和另一個here。簡要說明可在Wikipedia上找到。

更多的完整描述請見FowlerKerievsky

它也可從GoF書中獲得。

2

「供應商」模式是你正在尋找的...這是什麼在ADO.Net中使用。每個數據庫供應商都有一個單獨的數據「供應商」,它可以「知道」如何從其特定的數據庫供應商產品中讀取數據,但將數據以標準格式(接口)傳送到下游系統......您將編寫一個小型「供應商」組件(單個類將足以)「知道」您的每個不同的網站撲克歷史數據提供商的格式,並以完全相同的方式將數據暴露給讀取它的上游系統...

1

首先,創建您的「在線撲克手歷史」模型。該模型將代表數據,並能夠獨立於來源處理這些數據。然後創建供應商爲每個不同的源格式必須能夠將文件的信息轉換爲模型。

編輯:例如

public interface IDataProvider 
{ 
    IOnlinePokerInfo ParseFileInformation(FileInfo input); 
} 

public interface IOnlinePokerInfo 
{ 
    int Hand { get; set; } 
    DateTime DateInfo { get; set; } 
    List<IPlayer> Players { get; set; } 
    void ProcessInformation(); 
} 

public interface IPlayer 
{ 
    string Name { get; set; } 
} 

public class MyOnlinePokerInfo : IOnlinePokerInfo 
{ 
    private int hand; 
    private DateTime date; 
    private List<IPlayer> players; 

    public int Hand { get { return hand; } set { hand = value; } } 
    public DateTime DateInfo { get { return date; } set { date = value; } } 
    public List<IPlayer> Players { get { return players; } set { players = value; } } 

    public MyOnlinePokerInfo(int hand, DateTime date) 
    { 
     this.hand = hand; 
     this.date = date; 
     players = new List<IPlayer>(); 
    } 

    public MyOnlinePokerInfo(int hand, DateTime date, List<IPlayer> players) 
     : this(hand, date) 
    { 
     this.players = players; 
    } 

    public void AddPlayer(IPlayer player) 
    { 
     players.Add(player); 
    } 

    public void ProcessInformation() 
    { 
     Console.WriteLine(ToString()); 
    } 

    public override string ToString() 
    { 
     StringBuilder info = new StringBuilder("Hand #: " + hand + " Date: " + date.ToLongDateString()); 
     info.Append("\nPlayers:"); 
     foreach (var s in players) 
     { 
      info.Append("\n"); 
      info.Append(s.Name); 
     } 
     return info.ToString(); 
    } 
} 

public class MySampleProvider1 : IDataProvider 
{ 
    public IOnlinePokerInfo ParseFileInformation(FileInfo input) 
    { 
     MyOnlinePokerInfo info = new MyOnlinePokerInfo(1, DateTime.Now); 
     IPlayer p = new MyPlayer("me"); 
     info.AddPlayer(p); 
     return info; 
    } 
} 

public class MySampleProvider2 : IDataProvider 
{ 
    public IOnlinePokerInfo ParseFileInformation(FileInfo input) 
    { 
     MyOnlinePokerInfo info = new MyOnlinePokerInfo(2, DateTime.Now); 
     IPlayer p = new MyPlayer("you"); 
     info.AddPlayer(p); 
     return info; 
    } 
} 

public class MyPlayer : IPlayer 
{ 
    private string name; 
    public string Name { get { return name; } set { name = value; } } 

    public MyPlayer(string name) 
    { 
     this.name = name; 
    } 
} 

public class OnlinePokerInfoManager 
{ 
    static void Main(string[] args) 
    { 
     List<IOnlinePokerInfo> infos = new List<IOnlinePokerInfo>(); 

     MySampleProvider1 prov1 = new MySampleProvider1(); 
     infos.Add(prov1.ParseFileInformation(new FileInfo(@"c:\file1.txt"))); 

     MySampleProvider2 prov2 = new MySampleProvider2(); 
     infos.Add(prov2.ParseFileInformation(new FileInfo(@"c:\file2.log"))); 

     foreach (var m in infos) 
     { 
      m.ProcessInformation(); 
     } 
    } 
} 
1

你也可以考慮使用Command Pattern,你將有覆蓋面的行動您需要處理的文件類型的時間。通過這種方式,您可以擁有所有格式的靈活性,並堅持您的流程所需的一致參數。

另一個好處是你可以爲每個新的文件格式創建新的動作而不用重構其他格式的代碼。