Шаблон проектирования - жировой адаптер

Мы реализовали шаблон проектирования адаптера, работа которого заключается в следующем:

  1. Выступать в качестве связующего звена между уровнями обслуживания и доступа к данным.
  2. Преобразование необработанных данных (из источника данных, внутренних или внешних) в специфичные для домена данные. Сделайте необходимую проверку и массаж.
  3. Иногда выполнение вызовов DAO может зависеть от данных, недоступных из входных параметров, или могут потребоваться дополнительные вызовы службы на основе входных данных. Другими словами, адаптер не всегда может выполнить отображение 1:1 между службой и DAO. Он может отображать один и тот же вызов от службы к различным вызовам DAO на основе входных параметров.

Пункт № 3 начинает беспокоить меня, поскольку адаптеры становятся все более сложными, чем я мог себе представить. Я не знаю шаблон дизайна для обрезки адаптера. Есть один? Предложения?

2 ответа

Вы использовали то, что я люблю называть "швейцарский армейский нож".

В соответствии с передовой практикой вам следует разбить свой класс как минимум на 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);
    }
}

Следующим шагом может быть добавление генериков для чтения и посетителей. В этом случае у вас будут маленькие классы, и вы получите гибкость и преимущества надежных принципов, таких как единая ответственность, разделение интерфейса и т. Д. Таким образом, вы можете создать богатый инкапсулированный домен и расширить его функциональность с помощью некоторых принципов проектирования. С уважением!

Другие вопросы по тегам