8

在此先感谢您的帮助。我想知道是否有(设计)模式可以应用于这个问题。

我希望从具有相似但不同格式的文本文件中解析、处理和提取值。

更具体地说,我正在构建一个处理引擎,它接受来自众多不同网站的在线扑克手牌历史文件,并解析出特定的数据字段(手牌#、日期时间、玩家)。我需要将文件解析为每种格式略有不同的逻辑,但提取值的处理将是相同的。

我的第一个想法是只创建一个接受每种文件类型的“模式”并相应地解析/处理的类。我确信有更好的解决方案。

谢谢!

奖励点: C# 中的任何特定实现提示。

4

5 回答 5

6

这听起来像是策略模式的候选者。可以在此处找到 C# 中的示例,并在此处找到另一个示例。维基百科上提供了简要说明。

更完整的描述可在FowlerKerievsky的书中找到。

它也可从 GoF 书中获得。

于 2008-12-02T16:01:08.863 回答
2

“提供者”模式是您正在寻找的模式......它是在 ADO.Net 中使用的模式。每个数据库供应商都有一个单独的数据“提供者”,它“知道”如何从其特定的数据库供应商产品中读取数据,但以标准格式(接口)将其交付给下游系统......您将编写一个小型“提供者”组件(单个类就足够了)“知道”每个不同网站扑克历史数据提供者的格式,并以完全相同的方式将该数据公开给读取它的上游系统......

于 2008-12-02T15:56:31.807 回答
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();
        }
    }
}
于 2008-12-02T15:59:42.923 回答
1

听起来您需要策略模式,它允许您以多种不同的方式实现算法:

http://en.wikipedia.org/wiki/Strategy_pattern

于 2008-12-02T16:02:54.803 回答
1

您还可以考虑使用命令模式,您可以在其中对需要处理的文件类型的到达时间进行操作。通过这种方式,您可以灵活地使用所有格式,并遵守您的流程所需的一致参数。

另一个好处是您可以为每种新文件格式创建新的操作,而无需为其他格式重构代码。

于 2008-12-04T01:39:09.057 回答