当一个对象有不同的格式(XML,CSV)时,它可以用来表示,人们应该在哪里存储这些格式的知识。
对象应该知道它在XML中是如何表示的(例如,让对象通过对象上的某个方法进行自我转换,比如GetXML())。对于对象来说,这是不是太多的知识,是否应该将其存储在存储库/服务/其他层的外部?
如果它存储在存储库中,那么在对象的XML表示必须与其他信息一起持久化到数据库的用例中会发生什么情况,例如:
insert into order values(1, '2004', <order><amount>2</amount><price>19.99</price></order>);
对象的XML结构的...the知识应该在XML存储库中,但是SQL存储库也需要这些知识,这似乎是重复的。
我也不确定服务层是否应该包含对象表示,因为这似乎不是业务逻辑。
对于此用例,推荐的实现是什么?
发布于 2009-01-04 15:03:36
一般来说,您需要对象的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);
...
}这将允许以多态方式分派格式化调用。这取决于您的需求是否有用(您是否曾经持有不同类型的集合,因此需要多态分派,或者是否足够重载?)。
然后,您对format的调用将如下所示:
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);发布于 2009-01-04 15:36:08
您希望在数据库中存储什么内容?
insert into order
values(1, '2004', '<order><amount>2</amount><price>19.99</price></order>');或
insert into order values(1, '2004', 2, 19.99); https://stackoverflow.com/questions/410966
复制相似问题