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