Шаблон проектирования - жировой адаптер
Мы реализовали шаблон проектирования адаптера, работа которого заключается в следующем:
- Выступать в качестве связующего звена между уровнями обслуживания и доступа к данным.
- Преобразование необработанных данных (из источника данных, внутренних или внешних) в специфичные для домена данные. Сделайте необходимую проверку и массаж.
- Иногда выполнение вызовов DAO может зависеть от данных, недоступных из входных параметров, или могут потребоваться дополнительные вызовы службы на основе входных данных. Другими словами, адаптер не всегда может выполнить отображение 1:1 между службой и DAO. Он может отображать один и тот же вызов от службы к различным вызовам DAO на основе входных параметров.
Пункт № 3 начинает беспокоить меня, поскольку адаптеры становятся все более сложными, чем я мог себе представить. Я не знаю шаблон дизайна для обрезки адаптера. Есть один? Предложения?
2 ответа
Вы использовали то, что я люблю называть "швейцарский армейский нож".
- Точка 1 - модель брокера (или аналогичная)
- Точка 2 - шаблон адаптера (или аналогичный)
- Точка 3 является маршрутизацией на основе контента (или аналогичной)
В соответствии с передовой практикой вам следует разбить свой класс как минимум на 3 класса, по одному для каждой группы.
Вместо использования адаптера или полного репозитория (операции CRUD) я бы использовал интерфейс IReader для чтения и шаблон посетителя для удаления обновления вставки, чтобы можно было отделить логику домена от деталей инфраструктуры (персистентности). Вот идея:
public class MyBusinessObject : IAcceptBusinessVisitor, IAcceptMyBusinessIdVisitor
{
private readonly string _id;
private string MyPrivateProp { get; set; }
//Fully encapsulated object
public MyBusinessObject(string id, string myPrivateProp)
{
_id = id;
MyPrivateProp = myPrivateProp;
}
public void UpdateMyProp(string newProp)
{
if (string.IsNullOrWhiteSpace(newProp)) throw new ArgumentNullException(nameof(newProp));
//Business rules ...
MyPrivateProp = newProp;
}
public void Accept(IMyBusinessObjectVisitor visitor)
{
if (visitor == null) throw new ArgumentNullException(nameof(visitor));
visitor.Visit(_id, MyPrivateProp);
}
public void Accept(IMyBusinessIdVisitor visitor)
{
if (visitor == null) throw new ArgumentNullException(nameof(visitor));
visitor.Visit(_id);
}
}
public interface IAcceptBusinessVisitor
{
void Accept(IMyBusinessObjectVisitor visitor);
}
public interface IAcceptMyBusinessIdVisitor
{
void Accept(IMyBusinessIdVisitor visitor);
}
public interface IMyBusinessObjectVisitor
{
void Visit(string id, string prop);
}
public interface IMyBusinessIdVisitor
{
void Visit(string id);
}
public class SavePersistanceVitor : IMyBusinessObjectVisitor
{
public void Visit(string id, string prop)
{
//Save to Database
}
}
public class UpdatePersistanceVitor : IMyBusinessObjectVisitor
{
public void Visit(string id, string prop)
{
//Update to Database
}
}
public class DeleteVitor : IMyBusinessIdVisitor
{
public void Visit(string id)
{
//Delete in Database
}
}
Здесь для чтения:
public interface IMyBusinessObjectReader
{
MyBusinessObject Read(string id);
}
class MyBusinessObjectReaderFromDb : IMyBusinessObjectReader
{
public MyBusinessObject Read(string id)
{
//Read from database
string myPrivateProp = "";
return new MyBusinessObject(id, myPrivateProp);
}
}
Следующим шагом может быть добавление генериков для чтения и посетителей. В этом случае у вас будут маленькие классы, и вы получите гибкость и преимущества надежных принципов, таких как единая ответственность, разделение интерфейса и т. Д. Таким образом, вы можете создать богатый инкапсулированный домен и расширить его функциональность с помощью некоторых принципов проектирования. С уважением!