我应该使用什么设计模式进行导入/导出?

时间:2009-11-17 22:23:39

标签: design-patterns oop

我有一个日历事件对象。我计划使其与CalDAV / iCal / vCal协议/文件格式兼容,这需要将事件序列化和反序列化为不同格式。

我可以编写一个ImportICal,ExportICal,ImportVCal,ExportVCal等方法集,但这似乎不是一个非常好的方法,因为如果更新vCal格式等等。

之前有没有人处理过这种进出口情况?如果是这样,通常哪种设计模式(如果有的话)最好?

感谢您的帮助!

3 个答案:

答案 0 :(得分:19)

我并不熟悉那些格式,但是我会创建一个简单的数据传输对象来代表你的genereric日历事件对象。除了保存数据(伪代码)之外什么都不做:

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

然后你有一个存储库(工厂模式可能带有 Singleton ),它维护着不同格式的ICalenderEventReader / Writer实现列表:

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*/)
    { 
    ...
    }
}

答案 1 :(得分:0)

如果更新了vCal格式,则无论您使用哪种设计模式,都必须更改所写的代码(除非他们决定切换到ASN.1,其中包含升级)。

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

答案 2 :(得分:0)

使用单个公共接口安排多个实现(在您的案例中为日历协议)的常用方法是Bridge Pattern