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