Централизованное статические методы фабрики с инъекцией зависимостей


Я пытаюсь сделать небольшой электронной коммерции бэкенда на PHP. Я централизованно все статические фабричные методы в класс EntityFactory. Основной причиной этого было централизовать зависимость от инжектора зависимостей и, чтобы сделать его легким для клиента, чтобы инициализировать объект.

class EntityFactory
{
    private static $employeeRepository;
    private static $productRepository;

    public static function employee($name, $designation, $salary, $contactNo)
    {
        if (!self::$employeeRepository)
            self::$employeeRepository = resolve(EmployeeRepository::class);

        return new Employee(self::$employeeRepository, $name, $designation, $salary, $contactNo);
    }

    public static function product($itemCode, $name, Brand $brand, Category $category, $costPrice, $salePrice)
    {
        if (!self::$productRepository)
            self::$productRepository = resolve(ProductRepository::class);

        return new Product($itemCode, $name, $brand, $category, $costPrice, $salePrice, self::$productRepository);
    }

    public static function brand($name, $id = null)
    {
        $brand = new Brand($name);
        if ($id) $brand->setId($id);
        return $brand;
    }

    public static function category($name, $id = null)
    {
        $category = new Category($name);
        if ($id) $category->setId($id);
        return $category;
    }

    public static function purchaseOrder($customer, $user)
    {
        return new PurchaseOrder($customer, $user);
    }

    public static function orderItem($item, $qty)
    {
        return new PurchaseOrderItem($item, $qty);
    }
}

Основная проблема я чувствую себя здесь, что это нарушает, тем более ПСП, ИСП и OCP. Я, возможно, также сталкиваются с проблемами, касающиеся модульного тестирования в будущем(хотя я еще не столкнулась). Код для покупки товара:

//controller: create a new purchase order
public function store(Request $request)
    {
        $this->validateRequest($request);

    $user = $this->productRepository->findById(Auth::id());
    $customer = $this->supplierRepository->findById($request->input('id'));
    $products = $request->input('products');
    $purchaseOrder = EntityFactory::purchaseOrder($customer, $user);

    foreach ($products as $product) {
        $item = $this->productRepository->findById($product['id']);
        $purchaseOrder->addItem(EntityFactory::orderItem($item, $product['qty']));
    }

    $this->purchaseOrderRepository->beginTransaction();
    $this->purchaseOrderRepository->save($purchaseOrder);
    $purchaseOrder->finalize();
    $this->purchaseOrderRepository->endTransaction();
}

Здесь я легко гашу репозиториев в контроллере

// class PurchaseOrder

public function addItem(PurchaseOrderItem $item)
{
    $this->items[] = $item;
}

public function finalize()
{
    foreach ($this->items as $item) {
        $product = $item->getProduct();
        $product->purchase($item->getQuantity());
    }
}


//class Product
public function purchase($qty)
{
    if ($this->stock - $qty < 0) {
        throw new \RuntimeException("Product not available");
    } else {
        $this->stock += $qty;
        $this->productRepository->update($this);
    }
}

Здесь также ProductOrderItem и продукт может быть стаба.

Я не хочу, чтобы завод нужно инстанцирование. Иначе бы граф зависимостей как фабрика -> хранилище -> отображения -> завод, где правит данных из классов ORM для классов сущностей.

Каковы ваши мысли?



Комментарии