什么是存储对象的XML / CSV /其他表示的最佳位置

时间:2009-01-04 13:20:41

标签: c# .net architecture

当一个对象具有各种格式(XML,CSV)时,它可以表示在哪里,哪里可以存储这些格式的知识。

对象是否应该知道它在XML中的表示方式(即让对象通过对象上的某些方法转换自身,例如GetXML())。这对于对象有太多的知识吗?它应该存储在存储库/服务/其他层的外部吗?

如果它存储在存储库中,在对象的XML表示必须与其他信息一起持久化到数据库的用例中会发生什么,例如: -

insert into order values(1, '2004', <order><amount>2</amount><price>19.99</price></order>);

...对象的XML结构的知识将在XML存储库中,但SQL存储库也需要这些知识,这看起来像重复。

我不确定服务层是否应该持有对象表示,因为它似乎不是业务逻辑。

此用例的推荐实现是什么?

2 个答案:

答案 0 :(得分:5)

一般来说,您希望对象的XML(或其他...)格式代码与对象本身分开。实际的原因是希望有多个XML表示(比如摘要和详细表示)。如果这些方法的对象的API的所有部分,那么你开始具有:

public String GetShortXml(){ ... }
public String GetFullXml(){ ... }
public String GetCsv(){ ... }
public String GetJson(){ ... }

作为每个业务对象的API的一部分,并且快速变得难看。此外,这违反了single responsibility priciple,因为每个类都负责id所做的事情,并将自己表示为XML,JSON,CSV等。

因此,通常最好有一个知道如何格式化你关心的业务对象的类,并拥有一个SummaryXmlFormatter,DetailedXmlFormatter,CsvFormatter,JsonFormater等。

你可以更进一步让你的对象实现一个IFormattable接口(以下是visitor patter的改编,它给了我们双重调度的好处):

public interface IFormattable {
    public String Format(IFormatter formatter);
}

实现如:

public String Format(IFormatter formatter){
    return formatter.FormatBusinessObjectOne(this);
}

使用IFormatter接口定义:

public interface IFormatter{
    public String FormatBuisinessObjectOne(BusinessObjectOne boo);
    public String FormatBuisinessObjectTwo(BusinessObjectTwo bot);
    ...
}

这将允许以多态方式调度您的格式化调用。根据您的要求可能有用也可能没有用(您是否持有不同类型的集合,因此需要进行多态调度或超载?)。

您对格式的调用将如下所示:

IFormatter formatter = new XmlFormatter();
BusinessObjectOne boo = new BusinessObjectOne(...);

// With visitor like double dispatch
String xml = boo.Format(formatter);

// Without 
String xml = formatter.FormatBusinessObjectOne(boo);

// With overloading
String xml = formatter.Format(boo);

答案 1 :(得分:0)

您想要存储在数据库中的是什么?

insert into order 
values(1, '2004', '<order><amount>2</amount><price>19.99</price></order>');

insert into order values(1, '2004', 2, 19.99);