什么是使用 ZF2 和 Doctrine 实现业务逻辑模型的“正确方法”,同时创建干净的 OOP 和 MVC 结构,并为模型提供对 EntityManager 的访问权限?
尽管我很想将 Doctrine Repositories 用于所有业务逻辑,但我知道它们应该主要用于执行复杂的查询。我也知道 ZF2 中的模型可以通过多种方式提供依赖项(EntityManager):ZF2:依赖注入以正确的方式完成 http://zend-framework-community.634137.n4.nabble.com/ZF2-Injecting-对象到控制器或从服务定位器获取对象 td4656872.html
为了说明现实生活中的问题,我们如何为简单的网上商店功能创建模型层:
首先,我们将拥有实体
/**
* @Entity(repositoryClass="App\Repository\ProductRepository")
* @Table(name="products")
*/
class Product { ... }
/**
* @Entity(repositoryClass="App\Repository\ProductgroupRepository")
* @Table(name="productgroups")
*/
class Productgroup { ... }
以及为我们提供更详细查询功能的存储库
class ProductRepository extends EntityRepository {
public function isAvailable() { ... }
public function getQuantity() { ... }
public function getProductImages() { ... }
public function getRelatedProducts() { ... }
...
}
class ProductgroupRepository extends EntityRepository {
public function getAvailableProducts() { ... }
public function getAllProducts() { ... }
...
}
但是我们把这样的业务逻辑放在哪里呢?
Products functionalities:
- createNewProduct( $data ), eg. update prices, retrieve new quantities, generate a new image gallery, notify the administrator, ...
- deleteProduct(), eg. delete corresponding files and existing associations, put product into archive
- ...
Productgroups functionalities:
- removeProductFromProductgroup( $product), eg. update ordering in group, remove associations, ...
- addProductToProductgroup( $product ), eg. update ordering in group, create associations, ...
- deleteProductgroup(), eg. delete productgroup, set all it's products as uncategorized
- ...
例如,是否应该将 Productgroup 业务模型创建为在服务级别注入 EntityManager 的类?--
class Productgroup implements ServiceLocatorAwareInterface
{
public function removeProductFromProductgroup( $productgroup, $product) { }
public function addProductToProductgroup( $productgroup, $product) { }
}
还是应该扩展原始实体以访问其内部结构?--
class Productgroup extends \Application\Entity\Productgroup
implements ServiceLocatorAwareInterface
{
public function removeProductFromProductgroup( $productgroup, $product) { }
public function addProductToProductgroup( $productgroup, $product) { }
}
如果是这样,它是否也应该有某种设置状态方法?公共函数集($product){$this->populate($product);}