2009-11-17 82 views
12

我有一个日历事件对象。我有计划使其与CalDAV/iCal/vCal协议/文件格式兼容,这些协议/文件格式要求将事件序列化并从不同格式进行反序列化。我应该使用哪种设计模式进行导入/导出?

我可以写一个ImportICal,ExportICal,ImportVCal,ExportVCal等一套方法,但似乎像一个很好的做法不对,因为如果什么的vCal格式更新等

有任何人处理过这种类型的进口/出口情况?如果是这样,什么设计模式(如果有的话)通常是最好的?

感谢您的帮助!

回答

19

我不是特别熟悉这些格式,但我会创建一个简单的数据传输对象,它代表您的genereric日历事件对象。它不只是保存数据(伪):

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

然后你创建CalendarEventReader和CalendarEventWriter接口(这是战略模式,也许是生成器模式,差不多)

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 
{ 
    ... 
} 

你最好再有一个信息库(它与辛格尔顿模式也许)维持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 2009-11-18 06:08:30

+0

我自己提出的解决方案类似(不包括工厂部分)。那么客户端代码会是什么样子呢?日历对象会使用该工厂,还是客户端代码会使用它? – 2009-11-18 13:49:30

0

如果更新了vCal格式,则必须更改您使用哪种设计模式编写的任何代码(除非他们决定切换到类似于ASN.1的升级版本)。

我会创建一个带有导入和导出方法的格式接口,以及可能的元数据和方法,用于测试随机位的XML是否可能是该格式。然后,对于每种不同的格式,您都有一个实现该接口的对象。这是一种“策略设计模式”,但是每种格式都代表几种策略,用于执行一组一致的内容(导入,导出,检测),而不是具有单独的策略对象。

0

通常的方式安排多个实现(在你的情况日历协议)有一个共同的接口是Bridge Pattern

+0

这意味着我会将ICalExporter的实现传递给CalendarEvent对象的构造函数。然后,在CalendarEvent对象上,我调用Export()并使用该ICalExporter对象将事件导出为任何格式。如果我需要两种格式呢? – 2009-11-18 13:54:25

+0

您可以使用该组合模式 – jimkont 2014-04-22 05:59:07

相关问题