繁体   English   中英

类设计-接口还是抽象类?

[英]The class design - interface or abstract class?

我的业务场景如下:

我们可以使用几种付款系统(PS1,PS2,PS3 ...)进行付款。 常用功能是-ProcessPayment。 付款基于数据库中的数据。

我可以使用什么设计?

1)使用ProcessPayment方法和PaymentSystemBase基类创建IPaymentSystem接口,该基类可处理数据库内容(例如连接,检索数据等)。 创建实现IPaymentSystem接口并从PaymentSystemBase基类派生的特定类PS1,PS2,PS3 ...,以便使用通用数据库。

2)创建包含所有ProcessPayment方法和数据库内容的抽象基类。

3)还有别的。

interface IPaymentSystem
{
    void ProcessPayment();
}

public class PaymentSystemBase
{
    public PaymentSystemBase()
    {
        CheckInputParameters();
        CreateDatabaseConnection();
    }

    protected void CheckInputParameters() {}
    protected void CreateDatabaseConnection() {}
}

public class PS1 : PaymentSystemBase, IPaymentSystem
{
    public void ProcessPayment()
    {
        Console.WriteLine("Process PS1...");
    }
}

public class PS2 : PaymentSystemBase, IPaymentSystem
{
    public void ProcessPayment()
    {
        Console.WriteLine("Process PS2...");
    }
}

从您的代码中,我假设为了付款,我必须:-验证/检查参数-处理数据库连接-可能还很多

我认为这些动作应该由两个不同的对象来完成。 PaymentSystem应该将它们用作协作者。 没有抽象类。

经验法则是“偏重于继承而不是继承”: http : //www.hautelooktech.com/2013/02/05/design-principle-favor-composition-over-inheritance/

为了能够创建不同的支付系统,您可以从您的PaymentSystem的每个协作者中提取一个接口,并通过属性注入或更好的构造函数注入来切换它们(也就是组成一个新的支付系统)。

http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/

总而言之,您的PaymentSystem应该是真正简单的协作者的“协调者”。

我将使用第一种方法Interface,Abstract类来实现常规方法和具体类。

在我看来,抽象类永远不会替代接口,因此我将放弃第二种方法。

其他解决方案可能取决于您的业务,要求,...

唯一可能出错的是,您的类可能会违反单一职责,因为它必须处理付款和类似的事情,还必须创建数据库连接。 对我来说,数据库连接应该在另一个地方。

问候

在这种情况下,我建议您使用Interface。 仅涉及一种方法的地方。 您可以针对各种付款类型(PS1,PS2,PS3 ...)给出自己的实现。

如果您有更多的方法和变量在ProcessPayment中很常见,那么您可以考虑抽象类,其中至少某些方法的行为不会改变。 但是请记住,使用Abstract类时会丢失类继承。

如果仅涉及一种方法,则使用接口。

您宁愿创建一个抽象类 ,以将所有数据库内容放入其中; 如果要声明接口 ,则抽象类应实现该接口:

// Not necessary
public IPaymentable {
  void ProcessPayment();
}

// Interface should be implemented here
public abstract class PaymentSystemBase: IPaymentable {
  ...
  private IDatabaseConnection connectToDatabase() {...}
  ...
  protected void loadFromDatabase() {...}
  protected void saveToDatabase() {...} 
  ...
  protected PaymentSystemBase() {...}

  public abstract void ProcessPayment();
}

// A concrete class should only override ProcessPayment() method
public class PS1: PaymentSystemBase {
  public override void ProcessPayment() {...}
}

// A concrete class should only override ProcessPayment() method
public class PS2: PaymentSystemBase {
  public override void ProcessPayment() {...}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM