使用接口实现开闭原则(SOLID)

Posted

技术标签:

【中文标题】使用接口实现开闭原则(SOLID)【英文标题】:Achieve Open-Closed Principle (SOLID) Using Interface 【发布时间】:2019-01-01 18:21:26 【问题描述】:

我有多种付款方式(Stripe、Paypal、PayUMoney 等)。我想为每种支付类型创建一个单独的类,并为这些类创建一个 支付接口

interface PaymentInterface 
   public function payment($params);

class Stripe implements PaymentInterface 
   public function payment($params)  ... 


class Paypal implements PaymentInterface 
   public function payment($params)  ... 

在我的主课中,我想使用一种付款方式。我会将付款数据发送到我的主要方法,并希望动态检测付款方式。

class PaymentModule 
public function confirmPayment(Request $request)
   // create an object of the payment class
   // $obj = new PaymentTypeClass **(Problem is here)**
   // $obj->payment($params)
  

我的问题在这里,我如何动态创建相关的支付类/对象并从主方法调用 payment() 方法?

如果我有条件地创建对象,那么我就违反了开闭原则。因为,我正在使用 If ... else 检查支付类型,然后创建对象并调用可能需要进一步修改的 payment()

【问题讨论】:

只需从您的数据库或其他什么中提取类。可以是变量:$class = 'Paypal'; $obj = new $class; $obj->payment($params); 【参考方案1】:

如果我有条件地创建对象,那么我就违反了开闭原则。因为,我正在使用 If ... else 检查支付类型,然后创建对象并调用可能需要进一步修改的 payment()。

您的某些代码最终将不得不接受用户输入并决定使用哪个支付实现。这通常使用factory object 完成,它可能使用 if-else 或 map 或其他方式将正确的对象返回给您,这是工厂的“单一职责”。

【讨论】:

我完全同意@casablanca,我想补充一点,这通常会有一个抽象障碍,其中一方(非易失性)仅取决于抽象类型,而另一方(易失性)是创建具体对象。这一面通常与我们的 Main 方法有关。在您的情况下,工厂将属于易失性方面,并且可以通过非易失性方面的接口使用。 谢谢@casablanca。但是由于我对 OOP/SOLID 没有深入的了解,请您解释一下我如何使用工厂对象并遵循solid? 网上的例子很多,随便搜索一下“php factory pattern”就可以了。

以上是关于使用接口实现开闭原则(SOLID)的主要内容,如果未能解决你的问题,请参考以下文章

利用开闭原则 (SOLID)

SOLID - 违反开闭原则

如何应用 SOLID 原则在 React 中整理代码之开闭原则

如何应用 SOLID 原则在 React 中整理代码之开闭原则

设计模式SOLID - 开闭原则

学习设计模式 - 六大基本原则之开闭原则