2

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

//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

另外,我讨厌不得不这样做CustomerOne customerOne = (CustomerOne)customers["CustomerOne"];。有没有一种方法可以让客户回来并在其上调用方法而无需显式转换?

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

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

但是,如果每个客户都需要唯一的逻辑来生成参考号,我怎么能只保留一个客户对象并覆盖行为,除非我有多个GenerateReferenceNumber方法,one huge if else statement或者different concrete implementations of customers可以使用默认参考号或他们自己的唯一逻辑来生成一个。

4

2 回答 2

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
{

}

然后用法是一样的——不需要演员表。

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

于 2013-05-22T14:06:04.077 回答
0

使用Composition 而不是继承,我会想出这样的东西:

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()); 
于 2013-05-22T14:44:09.020 回答