Когда объект имеет различные форматы (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(){ ... }
Как часть API каждого бизнес-объекта, и это быстро становится ужасно. Кроме того, это нарушает принцип единой ответственности, поскольку каждый класс отвечает как за то, что делает id, так и за представление себя как XML, JSON, CSV и т. д.
Таким образом, часто лучше иметь класс, который знает, как форматировать бизнес-объекты, которые вам нужны, и имеет SummaryXmlFormatter, DetailXmlFormatter, 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);
Что вы хотите сохранить в БД?
insert into order
values(1, '2004', '<order><amount>2</amount><price>19.99</price></order>');
или же
insert into order values(1, '2004', 2, 19.99);
?
Первый: вставить в значения заказа (1, '2004', '<order> <amount> 2 </amount> <price> 19.99 </price> </order>');
Действительно хорошие методы в этом ответе, спасибо, что нашли время.