我有一个日历事件对象。我计划使其与CalDAV / iCal / vCal协议/文件格式兼容,这需要将事件序列化和反序列化为不同格式。
我可以编写一个ImportICal,ExportICal,ImportVCal,ExportVCal等方法集,但这似乎不是一个非常好的方法,因为如果更新vCal格式等等。
之前有没有人处理过这种进出口情况?如果是这样,通常哪种设计模式(如果有的话)最好?
感谢您的帮助!
答案 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。