哪种设计模式最适合每种客户方法的多种实现?

时间:2013-05-22 14:00:24

标签: c# design-patterns

我有客户,每个客户都有一个生成参考编号的方法,但每个客户的参考编号都不同。我有一个实现如下,但我很好奇是否存在任何可伸缩性问题以及这种设计模式或最适合这种情况的设计模式:

//All customers will implement this.
public interface ICustomer
{

}

//All customers will implement this.
public interface IReferenceNumber
{
    string GenerateReferenceNumber();
}

   public class CustomerOne : ICustomer, IReferenceNumber
{
    public string GenerateReferenceNumber()
    {
        return "Reference Implemenation 1";
    }
}

public class CustomerTwo : ICustomer, IReferenceNumber
{
    public string GenerateReferenceNumber()
    {
        return "Reference Implemenation 2";
    }
} 

以下是我可以称之为:

Dictionary<string,ICustomer> customers = new Dictionary<string,ICustomer>();

customers.Add("CustomerOne",new CustomerOne());
customers.Add("CustomerTwo",new CustomerTwo());

CustomerOne customerOne = (CustomerOne)customers["CustomerOne"];
CustomerTwo customerTwo = (CustomerTwo)customers["CustomerTwo"];

Console.WriteLine(customerOne.GenerateReferenceNumber());
Console.WriteLine(customerTwo.GenerateReferenceNumber());

以下是一些更具体的问题:

  1. 我拥有ICustomer的唯一原因是我没有做Dictionary<string,object> customers = new Dictionary<string,object>()之类的事情,但现在我想知道IReferenceNumber是否是不必要的,GenerateReferenceNumber应该被移动进入ICustomer
  2. 另外,我讨厌做CustomerOne customerOne = (CustomerOne)customers["CustomerOne"];。有没有办法我可以让客户回来并在其上调用方法而无需显式转换?

    似乎基于评论,我应该有类似的东西:

    public class Customer
    {
       public string GenerateReferenceNumber()
       {
           //Logic
           return "Default reference number";
       }
    }
    

    但是,如果每个客户都需要唯一的逻辑来生成参考号,那么除非我有多个GenerateReferenceNumber方法或one huge if else statementdifferent concrete implementations of customers,否则我如何才能保留一个Customer对象并覆盖该行为可以使用默认引用号或它们自己的唯一逻辑来生成一个。

2 个答案:

答案 0 :(得分:4)

您可以将GenerateReferenceNumber()方法移动到ICustomer接口,并在字典中更简单地使用它:

//All customers will implement this.
public interface ICustomer
{
    string GenerateReferenceNumber();
}

public class CustomerOne : ICustomer
{
    public string GenerateReferenceNumber()
    {
        return "Reference Implemenation 1";
    }
}

public class CustomerTwo : ICustomer
{
    public string GenerateReferenceNumber()
    {
        return "Reference Implemenation 2";
    }
} 


Dictionary<string,ICustomer> customers = new Dictionary<string,ICustomer>();

customers.Add("CustomerOne",new CustomerOne());
customers.Add("CustomerTwo",new CustomerTwo());

var customerOne = customers["CustomerOne"];
var customerTwo = customers["CustomerTwo"];

Console.WriteLine(customerOne.GenerateReferenceNumber());
Console.WriteLine(customerTwo.GenerateReferenceNumber());

或者,如果你真的想要保留两个接口,你可以使ICustomer派生自IReferenceNumber:

public interface ICustomer : IReferenceNUmber
{

}

然后用法是相同的 - 不需要演员表。

至于设计模式问题,我没有看到任何应该在这里使用的具体设计模式。它是继承的基本情况,而不是更复杂的行为,它具有将其作为一般方法实现的设计模式。因此,无需将此代码与设计模式复杂化。

答案 1 :(得分:0)

使用Composition over inheritance,我会想出这样的事情:

public class Customer
{
    private readonly IReferenceNumberGetter ReferenceNumberGetter;

    public Customer(IReferenceNumberGetter referenceNumberGetter)
    {
        ReferenceNumberGetter = referenceNumberGetter;
    }

    public string GenerateReferenceNumber()
    {
        return ReferenceNumberGetter.GenerateReferenceNumber();
    }

    // other Customer stuff
}

public interface IReferenceNumberGetter
{
    string GenerateReferenceNumber();
}

public class ReferenceNumberGetterOne : IReferenceNumberGetter
{
    public string GenerateReferenceNumber()
    {
        return "4";
    }
}

public class ReferenceNumberGetterTwo : IReferenceNumberGetter
{
    public string GenerateReferenceNumber()
    {
        return "42";
    }
}

并像这样使用它:

var customerOne = new Customer(new ReferenceNumberGetterOne()); 
var customerTwo = new Customer(new ReferenceNumberGetterTwo());