编程语言
首页 > 编程语言> > php – 松散耦合vs封装.平衡设计的最佳方法

php – 松散耦合vs封装.平衡设计的最佳方法

作者:互联网

根据下一个例子:

class InvoiceGenerator
{
   function create(Invoice $invoice)
   {
      $invoice->create();
   }
}



class InvoiceGenerator
{
   function create($invoiceData)
   {
      $invoice = new Invoice();
      $invoice->create($invoiceData);
   }
}

第一个示例在InvoiceGenerator和Invoice类之间的耦合较少,因为InvoiceGenerator不需要Invoice类.此外,它不仅可以处理一个类,而且可以处理几乎没有修改的整个界面.我已多次读过这样的原则:接口代码,而不是实现.这种情况的缺点是我被迫在客户端代码中实例化Invoice类.

第二个有更多的封装.实例化和创建发票的所有过程都委托给InvoiceGenerator类.尽管两个类都是耦合的,但这是有道理的,因为“发票生成器”在没有发票的情况下不会做任何事情.

您认为哪种最合适?或者两者之间的平衡设计的关键点是什么?

解决方法:

首先,我认为你正在混淆一些事情.看起来你的InvoiceGenerator类是factory class.它的职责是创建并返回一个Invoice对象. Invoice对象不是InvoiceGenerator的依赖项(在这种情况下,将Invoice对象作为参数传递确实更好,称为Dependency Injection).

但是,正如我所说,InvoiceGenerator类似乎是一个工厂类,工厂类的整个想法是实例化对象的逻辑被封装在该类中(如第二个例子中所示).如果您将Invoice对象作为参数传递(如第一个示例中所示),则必须在其他地方将其实例化,如果您的代码中有多个位置发生这种情况,则最终会复制实例化逻辑.工厂模式的整个想法是为了防止这种情况.

通过使用工厂类,您可以封装对象实例化逻辑并避免重复.您还可以将一些更高级的逻辑放入InvoiceGenerator的create()方法中,以确定要返回的对象类型.例如,如果总价格> 1,您可能想要返回Invoice对象.如果价格<1,则为CreditNote对象;当然,它们都应该扩展相同的接口(例如InvoiceInterface). 此外,看起来您正在将Invoice对象的实际初始化委托给对象本身,因为InvoiceGenerator的create()方法只是调用Invoice对象的create()方法,其中实际逻辑似乎需要地点.这违反了single responsibility principle,因为Invoice类现在都负责保存有关发票的数据并设置数组中的所有数据.后者应该是工厂阶级的责任.

所以,我会创建这样的类:

class InvoiceFactory
{
    public function create(array $data)
    {
        if ($data['total'] >= 0) {
            $invoice = new Invoice();
        } else {
            $invoice = new CreditNote();
        }

        $invoice->setTotal($data['total']);
        // set other data using setters as well

        return $invoice;
    }
}

如您所见,$invoice对象上没有调用create()方法.

标签:php,encapsulation,loose-coupling,coupling
来源: https://codeday.me/bug/20190519/1138570.html