为特定客户端重构方法

时间:2014-06-24 07:53:13

标签: c# refactoring strategy-pattern

特定于客户的方法:

我尝试重构一个代码,其中有很多特定客户的逻辑:

public void SendDocumentsToCustomer(List<Case> cases)
{
    foreach(var case in cases)
    {
        if(case.CustomerId==123)
        {
        if(case.Type==1 || case.Type==2)
        {
        SendDocumentsToCustomer123(case)
        }
        else if(case.CustomerId==456)
        {
        if(case.Type==1 || case.Type==3)
        {
        SendDocumentsToCustomer456(case);
        }
        }
        else if(case.CustomerId==768)
        {
        if(case.Type==2)
        {
        SendDocumentsToCustomer456(case);
        }
        else
        {
        SendDocumentsToCustomer(case);
        }
    }
}

特定客户的列表将会增长,条件也将被修改。我将有一个通用的解决方案,但也许像这样的方法DoItForClient123不是一个糟糕的解决方案,我应该这样,并以这种方式引入像CanDocumentsBeSendToClient123等方法?

我将非常感谢一些输入

2 个答案:

答案 0 :(得分:1)

为了区分每个特定客户的逻辑,我会使用这样的代码:

abstract class DocumentSender   //Base class for all document sending components
{
    public abstract bool CanSend(Case @case);        // Check if sender can send the document
    public abstract void SendDocument(Case @case);   // Send the document
}

class DefaultDocumentSender : DocumentSender
{
    public override bool CanSend(Case @case)
    {
        return true;   //Can process all requests
    }

    public override void SendDocument(Case @case)
    {
       // Do something
    }
}

class Customer123DocumentSender : DocumentSender
{
    public override bool CanSend(Case @case)
    {
        return @case.CustomerId == 123;   //Specific case
    }

    public override void SendDocument(Case @case)
    {
        if(@case.Type==1 || @case.Type==2)
        {
            // Do something different
        }
    }
}

//Separate class for getting the correct sender
class CaseSenderFactory    
{
    readonly List<DocumentSender> _senders = new List<DocumentSender>();

    public DocumentSenderFactory()
    {
        //Initialize the list of senders from the most specific. 
        _senders.Add(new Customer123DocumentSender());
        // Add more specific cases here
        _senders.Add(new DefaultDocumentSender());   //Last item should be the default sender
    }

    public DocumentSender GetDocumentSender(Case @case)
    {
        //At least one sender needs to satisfy the condition
        return _senders.First(x => x.CanSend(@case));   
    }
}

然后您可以使用这样的发件人:

var factory = new DocumentSenderFactory();
foreach(var @case in cases)
{
    var sender = factory.GetDocumentSender(@case);
    sender.SendDocument(@case);
}

答案 1 :(得分:0)

我认为制作这样的东西是一个很好的想法: 如果代码确实特定于某些客户,则可以为他们创建一个类。如果特定客户的代码以某种方式相关但以不同的方式组合,那么你应该在DecoratorPattern上获取一个战利品(mabye it help)

class Customer
{
    public abstract SendDocumentsTo(Customer c);
}


class SpecificCustomerA
{
    public overwrite SendDocumentsTo(Customer c)
    {
        if (c is SpecificCustomerB)
        {
            //Logic here
        }
    }
}

class SpecificCustomerB { ... }
相关问题