[英]Factory or service pattern or method injection?
我目前正在考慮用什么模式來解決以下問題。
我有一個名為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
。
所以基本上客戶端使用其IdentificationCriteria
創建一個IdentificationRequest
,然后需要識別正確的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
}
}
此示例將直接將標識過程耦合到請求。
這種情況的常見模式是什么? 反正有共同的模式嗎? 優缺點都有什么?
Thx提前!
更新
也許我沒有正確理解命令模式,但在這種情況下我能得到什么好處呢? 以下實現是否正確?
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();
開發的主要目標應該是使用最簡單,最干凈的代碼來滿足要求。 ( http://msdn.microsoft.com/en-us/magazine/cc163962.aspx )
話雖如此,除非您有特定理由使用其中一種模式,否則立即停止。 如果沒有具體的理由去做這項工作,你只需編寫更多的代碼,希望它有一天會有用。 只要寫出有效的方法。 如果需要,稍后重構它。
如果需要,繼續沿着保持簡單的道路前進。 選擇一個模式,庫或其他工具,使您可以編寫干凈,簡單,可讀的代碼來完成工作。
你的IdentificationCriteria和IdentificationCriteriaAnalyzer類型對我來說很像規格 ,所以我會看到在那個方向重構它們是否有意義。
在我看來,IdentificationRequest類打破了單一責任原則 - 為什么它有一個Person字段/屬性?
API也可以從更好的命令查詢分離中受益。
所以我認為更好的模型是定義一個接受IdentificationCriteria並返回某種Command的接口 。 這樣的界面本質上是一個抽象工廠 。
public interface IIdentificationCommandFactory
{
IIdentificationCommand Create(IdentificationCriteria spec);
}
實現它時,您可以在repostiry中查找匹配項,並根據該查詢的結果和其他規范(例如IdentificationCriteriaAnalyzer),您可以返回正確的IIdentificationCommand實現。
然后調用者會要求返回的命令執行。
它看起來像你應該使用命令模式:
- http://www.dofactory.com/Patterns/PatternCommand.aspx
- http://c2.com/cgi/wiki?CommandPattern
- http://en.wikipedia.org/wiki/Command_pattern
您的IdentificationRequest也不像實體類 ,但我會將您的Person類描述為實體。
通常命令模式中的Invoker向接收者發送響應,指示成功或失敗,並且在成功的情況下,響應對象可以包含已識別的角色。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.