当一个对象具有各种格式(XML,CSV)时,它可以表示在哪里,哪里可以存储这些格式的知识。
对象是否应该知道它在XML中的表示方式(即让对象通过对象上的某些方法转换自身,例如GetXML()
)。这对于对象有太多的知识吗?它应该存储在存储库/服务/其他层的外部吗?
如果它存储在存储库中,在对象的XML表示必须与其他信息一起持久化到数据库的用例中会发生什么,例如: -
insert into order values(1, '2004', <order><amount>2</amount><price>19.99</price></order>)
;
...对象的XML结构的知识将在XML存储库中,但SQL存储库也需要这些知识,这看起来像重复。
我不确定服务层是否应该持有对象表示,因为它似乎不是业务逻辑。
此用例的推荐实现是什么?
答案 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);