2009-11-17 3 views
12

У меня есть объект события календаря. Я планирую сделать его совместимым с протоколами/форматами CalDAV/iCal/vCal, которые требуют, чтобы событие было сериализовано и де-сериализовано в разных форматах и ​​из них.Какой шаблон дизайна следует использовать для импорта/экспорта?

Я мог бы написать ImportICal, ExportICal, ImportVCal, ExportVCal и т.д. набор методов, но это не похоже, очень хороший подход, потому что, если формат VCAL обновляется и т.д.

Имеет кто имел дело с этим типом ситуации импорта/экспорта раньше? Если да, то какой шаблон дизайна (если таковой имеется) в целом лучше всего подходит?

Благодарим за помощь!

ответ

19

Я не очень хорошо знаком с этими форматами, но я бы создал простой объект передачи данных, который представляет ваш общий объект событий календаря. Он ничего не делает, но держит данные (псевдокод):

class CalendarEvent 
{ 
    DateTime Date { get; } 
    string Title { get; } 
    string Description { get; } 
} 

Затем вы создаете интерфейс для CalendarEventReader и CalendarEventWriter (это стратегия шаблон и, возможно, в Builder шаблон, вид):

interface ICalendarEventReader 
{ 
    CalendarEvent Read(Stream data); 
    // Add additional methods if needed e.g.: 
    string GetTitleOnly(Stream data); 
} 
interface ICalendarEventWriter 
{ 
    Stream Write(CalendarEvent event); 
    // Add additional methods if needed e.g.: 
    Stream WriteSummaryOnly(CalendarEvent event); 
} 

После этого фактические реализации реализуют вышеуказанные интерфейсы. Один для каждого формата. Вы можете даже думать о том, читатель и писатель в одном классе:

class CalDavConverter : ICalenderEventWriter, ICalendarEventReader 
{ 
    ... 
} 

Вы бы тогда иметь Repository (это Factory модель может быть с Singleton), который поддерживает список реализаций/Writer ICalenderEventReader для различных форматов:

static class CalenderEventConverterRepository 
{ 
    static ICalendarEventReader GetReader(string formatName /*or any other data upon wich to decide wich format is needed*/) 
    { 
    ... 
    } 

    static ICalendarEventReader GetWriter(string formatName /*or any other data upon wich to decide wich format is needed*/) 
    { 
    ... 
    } 
} 
+3

Я не думаю, что интерфейсы считывающего устройства можно назвать строителем. Но кроме этого +1 для хорошего дизайнерского внушения. – Tanmay

+0

Решение, которое я придумал самостоятельно, было аналогичным (минус заводская часть). Как выглядит код клиента? Будет ли объект календаря использовать эту фабрику или использовать код клиента? –

0

Если формат vCal обновлен, вам придется изменить любой код, который вы написали, в зависимости от того, какой шаблон дизайна вы используете (если только они не захотят переключиться на нечто вроде ASN.1, где производится обновление).

Я бы создал интерфейс формата с методами импорта и экспорта и, возможно, метаданные и методы для проверки того, является ли случайный бит XML, скорее всего, таким форматом. Затем для каждого другого формата у вас есть объект, который реализует этот интерфейс. Это своего рода «шаблон стратегии стратегии», но каждый формат представляет собой несколько стратегий для создания целостного набора вещей (импорт, экспорт, обнаружение), а не отдельные стратегические объекты.

0

Обычный способ организовать несколько реализаций (протоколы календаря в вашем случае) с одним общим интерфейсом является Bridge Pattern.

+0

Это означает, что я передам реализацию, скажем, ICalExporter, в конструктор объекта CalendarEvent. Затем, в объекте CalendarEvent, я вызываю Export(), и он использует этот объект ICalExporter для экспорта события в любой формат. Что делать, если мне это нужно в обоих форматах? –

+0

Вы можете использовать составной шаблон для этого – jimkont

Смежные вопросы