簡體   English   中英

工廠或服務模式或方法注入?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM