如何使用工厂方法创建对象,而不是提供可选的对象构造函数


How to create an object using Factory method, instead of supplying alternative object constructor

我在应用工厂模式时遇到了一些问题。

我有一个类,我通常称之为Product($modelNumber, $wheelCount)。但是在我正在重构的一部分遗留代码中,我没有$modelNumber,只有$productID,其中{$modelNumber, $productID}之间的链接在数据库中(或者在我的情况下,我可以硬编码它,因为我目前只有几个选择的产品)。

我需要能够创建我的类使用$productId,但如何?

使用过程方法,我将有一个函数进行查找,我将把该函数放在一个文件中,并将该文件包含在我需要进行查找的任何地方。这样做:

$modelNumber = modelLookup($productId)
Product($modelNumber, $wheelCount);

但是我如何使用面向对象的方式?

注意:我在这里发布了一个更详细的情况:https://softwareengineering.stackexchange.com/q/233518/119333,这是工厂模式(以及其他模式,如接口和函数指针传递)在概念上被建议的地方,但是当我试图在PHP中实现它们时,我碰壁了。这似乎是一个简单的问题,但我认为有几种方法可以做到这一点,我有点迷路了。所以我需要一些帮助。

对于您的SRP问题,我在Programmers Exchange上提供了一个概念性的答案,但是我想我可以在这里演示一下。

你想要的基本上是其他一些对象,它将做的工作,以获得给定产品ID的型号。

class ProductModelNumberProvider {
    public function findByProductId($productId) {
        // The lookup logic...
    }
}

你的工厂应该提供一个setter构造函数,这样它就可以在需要的时候在内部使用这个对象来查找型号。所以基本上你最终会得到一个类似这样的ProductFactory

class ProductFactory {
    private $productModelNumberProvider;
    
    public function __construct(ProductModelNumberProvider $productModelNumberProvider) {
        $this->productModelNumberProvider = $productModelNumberProvider;
    }
    public function getProductByIdAndWheels($productId, $wheels) {
        $modelNumber = $this->productModelNumberProvider($productId);
        return $this->getProductByModelNumberAndWheels($modelNumber, $wheels);
    }
    public function getProductByModelNumberAndWheels($modelNumber, $wheels) {
        // Do your magic here...
        return $product;
    }
}

编辑

重新考虑setter并不是最好的方法,因为拥有ProductModelNumberProvider实例是强制性的。这就是为什么我将它移动到通过构造函数注入的原因。

我可以这样想:

$factory = new ProductBuilder();
$factory->buildFromProductId($productId, $wheelCount); //uses modelLookup() internally
$factory->buildFromModelNumber($modelNumber, $wheelCount); //just returns Product()

它基本上是在过程函数之上创建一个类,但是它确实将创建类的逻辑与查找映射的逻辑分开了。