В настоящее время я думаю о том, с каким шаблоном мне следует решить следующую проблему.
У меня есть сущность с именем IdentificationRequest
.Этот объект используется для идентификации Person
по некоторым критериям.
public class IdentificationRequest
{
public IdentificationCriteria Criteria;
public Person IdentifiedPerson;
protected internal virtual void RedirectToManualIdentification()
{
ChangeState(IdentificationRequestState.ManualIdentificationRequested);
}
public virtual void StartManualIdentification()
{
ChangeState(IdentificationRequestState.ManualIdentificationInProgress);
}
public virtual void AssignIdentifiedPerson(Person person)
{
identifiedPerson = person;
ChangeState(IdentificationRequestState.IdentificationFinished);
}
}
public class IdentificationCriteria
{
public string Name;
}
Это упрощенный пример.В действительности IdentificationRequest
содержит гораздо больше информации, а также IdentificationCriteria
.
Таким образом, в основном клиент создает IdentificationRequest
со своим IdentificationCriteria
, и тогда необходимо определить правильный Person
,Для этого критерии должны быть переданы на уровень постоянства, чтобы проверить, есть ли человек в базе данных, соответствующий критериям.Если человек не может быть найден, необходимо взаимодействие с человеком, чтобы назначить правильный Person
для запроса.
Для процесса идентификации я в настоящее время использую сервис.Как:
public class IdentificationService : IIdentificationService
{
private readonly IPersonRepository personRepository ;
private readonly IIdentificationRequestRepository identificationRequestRepository;
public IdentificationService(IPersonRepository personRepository )
{
this.personRepository = personRepository ;
}
public bool IdentifyPerson(IdentificationRequest identificationRequest)
{
var matches = personRepository.FindByIdentificationCriteria(identificationRequest.Criteria);
// some additional post analysis of the matches returned from the persistence layer
var criteriaAnalyzer = new IdentificationCriteriaAnalyzer(identificationRequest.Criteria);
var uniqueMatch = criteriaAnalyzer.TryIdentify(matches);
if(uniqueMatch != null)
{
identificationRequest.AssignIdentifiedPerson(uniqueMatch);
return true;
}
else
{
identificationRequest.RedirectToManualIdentification();
return false;
}
}
}
Этот сервис является частью сборки домена.Теперь мой вопрос, является ли это правильным шаблоном для идентификации?Или я бы использовал фабрику, чтобы создать запрос идентификации, а затем напрямую попытаться идентифицировать его, например:
public class IdentificationRequestFactory
{
private readonly IPersonRepository personRepository;
public IdentificationRequestFactory(IPersonRepository personRepository)
{
this.personRepository = personRepository;
}
public IdentificationRequest Create(IdentificationCriteria identificationCriteria)
{
var request = new IdentificationRequest(identificationCriteria);
var matches = personRepository.FindByIdentificationCriteria(identificationRequest.Criteria);
var criteriaAnalyzer = new IdentificationCriteriaAnalyzer(identificationRequest.Criteria);
var uniqueMatch = criteriaAnalyzer.TryIdentify(matches);
if(uniqueMatch != null)
{
identificationRequest.AssignIdentifiedPerson(uniqueMatch);
}
else
{
identificationRequest.RedirectToManualIdentification();
}
return request;
}
}
Таким образом, IdentificationRequest
может быть создан только фабрикой, убедившись, чтопроцесс идентификации уже завершен, и запрос находится в допустимом состоянии.
Или вы позволите IdentificationRequest
идентифицировать себя, выполнив инъекцию метода, например:
public class IdentificationRequest
{
public IdentificationCriteria Criteria;
public Person IdentifiedPerson;
public void Identify(IPersonRepository personRepository)
{
// identification logic here
}
}
В этом примересвязать процесс идентификации с запросом напрямую.
Какая общая схема для такого случая?В любом случае, есть ли общий шаблон?Каковы плюсы и минусы?
Спасибо заранее!
Обновление
Возможно, я не правильно понимаю шаблон команды, но какие преимущества я получу?получить это в этом случае?Правильна ли следующая реализация?
public class IdentificationCommandFactory
{
private readonly IPersonRepository personRepository;
public IdentificationCommandFactory(IPersonRepository personRepository)
{
this.personRepository = personRepository;
}
public IIdentificationCommand Create(IdentificationRequest identificationRequest)
{
var matches = personRepository.FindByIdentificationCriteria(identificationRequest);
var criteriaAnalyzer = new IdentificationCriteriaAnalyzer(identificationRequest);
var uniqueMatch = criteriaAnalyzer.TryIdentify(matches);
if(uniqueMatch != null)
{
return new AssignIdentifiedPersonCommand(identificationRequest, uniqueMatch);
}
else
{
return new RedirectToManualIdentificationCommand(identificationRequest);
}
}
}
public interface IIdentificationCommand
{
void Execute();
}
public class RedirectToManualIdentificationCommand : IIdentificationCommand
{
private readonly IdentificationRequest identificationRequest;
public RedirectToManualIdentificationCommand(IdentificationRequest identificationRequest)
{
this.identificationRequest = identificationRequest;
}
public void Execute()
{
identificationRequest.RedirectToManualIdentification();
}
}
public class AssignIdentifiedPersonCommand : IIdentificationCommand
{
private readonly IdentificationRequest identificationRequest;
private readonly Person personIdentified;
public AssignIdentifiedPersonCommand(IdentificationRequest identificationRequest, Person personIdentified)
{
this.identificationRequest = identificationRequest;
this.personIdentified = personIdentified;
}
public void Execute()
{
identificationRequest.AssignIdentifiedPerson(personIdentified);
}
}
Вызывающая сторона:
var identificationCommandFactory = new IdentificationCommandFactory(personRepository);
var command = identificationCommandFactory.Create(request);
command.Execute();