Шаблон проектирования: парсинг похожих, но разных схем в текстовых файлах - PullRequest
8 голосов
/ 02 декабря 2008

заранее спасибо за вашу помощь. Мне интересно, есть ли (дизайн) шаблон, который можно применить к этой проблеме.

Я хочу проанализировать, обработать и извлечь значения из текстовых файлов с похожими, но разными форматами.

В частности, я создаю механизм обработки, который принимает файлы истории рук в онлайн-покере со множества различных веб-сайтов и анализирует определенные поля данных (Hand #, DateTime, Players). Мне понадобится логика для анализа файлов, чтобы они немного отличались для каждого формата, но обработка извлеченных значений будет одинаковой.

Моей первой мыслью было бы создать только 1 класс, который принимает "схему" для каждого типа файла и анализирует / обрабатывает соответственно. Я уверен, что есть лучшее решение для этого.

Спасибо!

Бонусный балл: Любые конкретные подсказки реализации в C #.

Ответы [ 5 ]

6 голосов
/ 02 декабря 2008

Звучит как кандидат на шаблон Стратегии. Пример в C # можно найти здесь , а другой здесь . Краткое описание доступно в Википедии .

Более полное описание доступно в книге Фаулера и Кериевского .

Он также доступен в книге GoF.

2 голосов
/ 02 декабря 2008

Шаблон "Provider" - это тот, который вы ищете ... это то, что используется в ADO.Net. У каждого поставщика базы данных есть отдельный «поставщик» данных, который «знает», как читать данные из своего конкретного продукта поставщиков БД, но доставляет их в стандартном формате (интерфейсе) для последующих систем ... Вы напишите небольшой «поставщик» компонент (достаточно одного класса), который «знает» формат для каждого из ваших различных поставщиков данных истории покера на веб-сайте и предоставляет эти данные точно так же, как и вышестоящая система, которая их читает ...

1 голос
/ 04 декабря 2008

Вы также можете использовать Командный шаблон , где у вас будет действие для времени достижения типа файла, который вам нужно обработать. Таким образом, вы можете иметь гибкость для всех форматов и придерживаться согласованных параметров, которые потребуются вашему процессу.

Еще одним преимуществом является то, что вы можете создавать новые Действия для каждого нового формата файла без рефакторинга кода для других форматов.

1 голос
/ 02 декабря 2008

Похоже, вам нужен шаблон Стратегии, который позволяет вам реализовать алгоритм несколькими различными способами:

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

1 голос
/ 02 декабря 2008

Сначала создайте свою "историю рук в онлайн-покере" модель . Эта модель будет представлять данные и сможет обрабатывать эти данные независимо от источника. Затем создайте провайдеров для каждого из различных исходных форматов, которые должны быть способны преобразовывать информацию файла в модель.

РЕДАКТИРОВАТЬ: например,

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();
        }
    }
}
...