当一个对象具有各种格式(XML,CSV)时,它可以表示在哪里,哪里可以存储这些格式的知识.
对象是否应该知道它是如何用XML表示的(即让对象通过对象上的某些方法转换自己GetXML()
).这对于对象有太多的知识吗?它应该存储在存储库/服务/其他层的外部吗?
如果它存储在存储库中,那么在用例中必须将对象的XML表示与其他信息一起持久化到数据库中的情况会发生什么,例如: -
insert into order values(1, '2004',
;
...对象的XML结构的知识将在XML存储库中,但SQL存储库也需要这些知识,这看起来像重复.
我不确定服务层是否应该持有对象表示,因为它似乎不是业务逻辑.
这个用例的推荐实现是什么?
一般来说,您希望对象的XML(或其他...)格式代码与对象本身分开.实际的原因是希望有多个XML表示(比如摘要和详细表示).如果这些方法的对象的API的所有部分,那么你开始具有:
public String GetShortXml(){ ... } public String GetFullXml(){ ... } public String GetCsv(){ ... } public String GetJson(){ ... }
作为每个业务对象的API的一部分,并且快速变得难看.此外,这违反了单一责任原则,因为每个类都负责id所做的事情,并将自己表示为XML,JSON,CSV等.
因此,通常最好有一个知道如何格式化您关心的业务对象的类,并拥有一个SummaryXmlFormatter,DetailedXmlFormatter,CsvFormatter,JsonFormater等.
你可以更进一步让你的对象实现一个IFormattable接口(以下是访问者模式的改编,它给了我们双重调度的好处):
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);