Je réfléchis actuellement à quel modèle je devrais résoudre le problème suivant.Modèle d'usine ou de service ou injection de méthode?
J'ai une entité appelée IdentificationRequest
. Cette entité est utilisée pour identifier un Person
selon certains critères.
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;
}
Ceci est un exemple simplifié. En realitiy le IdentificationRequest
contient beaucoup plus d'informations, ainsi que le IdentificationCriteria
.
Donc, fondamentalement, un client crée un IdentificationRequest
avec son IdentificationCriteria
et le bon Person
doit être identifié. Pour cela, les critères doivent être transmis à la couche de persistance pour vérifier si une personne dans la base de données correspond aux critères. Si aucune personne ne peut être trouvée, une interaction humaine est alors requise pour assigner le bon Person
à la demande.
Pour le processus d'identification, j'utilise actuellement un service. Comme:
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;
}
}
}
Ce service fait partie de l'assembly de domaine. Maintenant, ma question est, si c'est le bon modèle pour effectuer l'identification? Ou devrais-je utiliser une usine, pour créer la demande d'identification puis essayez directement de l'identifier, comme:
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;
}
}
De cette façon, un IdentificationRequest
ne peut être construit par l'usine, en veillant à ce que le processus d'identification est déjà fait et la demande est dans un état valide.
Ou voulez-vous laisser le IdentificationRequest
s'identifier en faisant une injection de méthode comme:
public class IdentificationRequest
{
public IdentificationCriteria Criteria;
public Person IdentifiedPerson;
public void Identify(IPersonRepository personRepository)
{
// identification logic here
}
}
Cet exemple coupler le processus d'identification à la demande directement.
Qu'est-ce qu'un modèle commun pour un tel cas? Y a-t-il un modèle commun de toute façon? Quels sont les avantages et inconvénients?
Merci d'avance!
Mise à jour
Peut-être que je ne comprends pas le motif de commande correctement, mais quels avantages puis-je obtenir de celui-ci dans ce cas? L'implémentation suivante est-elle correcte?
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);
}
}
L'appelant:
var identificationCommandFactory = new IdentificationCommandFactory(personRepository);
var command = identificationCommandFactory.Create(request);
command.Execute();
ne peut pas dire combien de fois tout au long de la journée, je dis cela. – Tigran