jjzjj

php - 将业务逻辑与 PHP Doctrine 2 分开

coder 2024-01-03 原文

我使用 symfony 2.3 和 php doctrine 2。

程序有以下模型:

  • 实体订单 - 典型的客户订单
  • entity BadOrderEntry(fields: id, order - 与 Order, createdAt 的单向一对一关系)
  • 用于创建实体 BadOrderEntry 的工厂 BadOrderEntryFactory
  • 存储库 BadOrderEntryRepository 用于实体 BadOrderEntry 的搜索方法
  • 管理器 BadOrderEntryManager,用于保存/编辑/删除实体 BadOrderEntry 的方法
  • AND MAIN CLASS BadOrderList - 不良订单列表,此类代码:

    private $factory;
    private $repository;
    private $manager;
    
    public function __construct(
        BadOrderEntryFactory $f,
        BadOrderEntryRepository $r,
        BadOrderEntryManager $m
    ) {
        $this->factory = $f;
        $this->repository = $r;
        $this->manager = $m;
    }
    
    public function has(Order $order)
    {
        return $this->repository->existsByOrder($order);
    }
    
    public function add(Order $order)
    {
        if (! $this->has($order)) {
            $entry = $this->factory->create($order);
            $this->manager->save($entry);
        }
    }
    
    public function remove(Order $order)
    {
        $entry = $this->repository->findOneByOrder($order);
        if ($entry !== null) {
            $this->manager->delete($entry);
        }
    }
    

我很喜欢这个类(class)的设计。我想了很多。 一切都很棒。但!存在一个问题:add 和 remove 方法中的操作必须在事务中执行。

PHP Docrine 2 中的事务代码如下所示:

<?php
$em->getConnection()->beginTransaction();
try {
    //... do some work
    $em->getConnection()->commit();
} catch (Exception $e) {
    $em->getConnection()->rollback();
    throw $e;
}

但是我如何在 BadOrderList 中调用这段代码呢?

我花了很多时间删除依赖数据库(以及相应的 PHP Doctrine 2),然后重新创建它? 现在依赖隐藏在类 BadOrderEntryRepository 和 BadOrderEntryManager 中。

如何在类BadOrderList中隐藏对交易机制的依赖?

最佳答案

经过我们的讨论,我对您的问题有了答案。 问题实际上不是“如何隐藏对类 BadOrderList 中事务机制的依赖?”,而是如何将模型与持久层分离?(Doctrine2 在那特殊情况)。

我试着用一些代码来说明我的建议

class BadOrderEntry
// Bad - is too bad word to describe an order here. Why is it bad? Is it Declined? Cancelled?
{
   private $order;
   // some code
}
class BadOrderEntryFactory 
{ 
   // If there is not to much processing to build BadOrderEntry better use factory method like BadOrderEntry::fromOrder($order); 
}
class BadOrderEntryRepository 
{ 
   // here is some read model 
}
class BadOrderEntryManager  
// ITS a part of our model and shouldn't be coupled to ORM
{
  public function save(BadEntry $be) 
  {
    // some model events, model actions
    $this->doSave($be); // here we should hide our storage manipulation
  }

  protected function doSave($be) // it can be abstract, but may contain some basic storage actions  
  { 
  }

  // similar code for delete/remove and other model code
}
class ORMBadOrderEntryManager extends BadOrderEntryManager 
// IT'S NOT the part of your model. There is no business logic. There is only persistent logic and transaction manipulation
{ 
  protected $entityManager;

  // some constructor to inject doctrine entitymanager

  protected doSave($be)
  {
    $em = $this->entityManager;
    $em->getConnection()->beginTransaction(); // suspend auto-commit
    try {
      $em->persist($be);
      $em->flush();
      $em->getConnection()->commit();
    } catch (Exception $e) {
      $em->getConnection()->rollback();
      throw $e;
    }
  }
}
// You can also implement ODMBadOrderEntryManager, MemcacheBadOrderEntryManager etc.

因此,如果我们谈论目录结构,您的所有模型都可以从 bundle 中移出并在任何地方使用。您的 Bundle 结构如下:

BadEntryBundle
|
+ Entity
| |
| --- BadOrderEntryEntity.php
|
+ ORM
| |
| --- ORMBadOrderEntryManager.php 

然后您只需将 ORMBadOrderEntryManager 注入(inject) BadOrderEntryList

关于php - 将业务逻辑与 PHP Doctrine 2 分开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27766476/

有关php - 将业务逻辑与 PHP Doctrine 2 分开的更多相关文章

  1. ruby-on-rails - 如何将验证与模型分开 - 2

    我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:

  2. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  3. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  4. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  5. ruby-on-rails - Ruby 和 SQL 中的重复业务逻辑 - 2

    我有一个PORO(普通旧Ruby对象)来处理一些业务逻辑。它接收一个ActiveRecord对象并对其进行分类。为了简单起见,以下面为例:classClassificatorSTATES={1=>"Positive",2=>"Neutral",3=>"Negative"}definitializer(item)@item=itemenddefnameSTATES.fetch(state_id)endprivatedefstate_idreturn1if@item.value>0return2if@item.value==0return3if@item.value但是,我还想根据这些st

  6. ruby - 了解 Ruby 中赋值和逻辑运算符的优先级 - 2

    在以下示例中,我无法理解Ruby运算符的优先级:x=1&&y=2由于&&的优先级高于=,我的理解是类似于+和*运算符:1+2*3+4解析为1+(2*3)+4它应该等于:x=(1&&y)=2但是,所有Ruby源代码(包括内部语法解析器Ripper)都将其解析为x=(1&&(y=2))为什么?编辑[08.01.2016]让我们关注一个子表达式:1&&y=2根据优先规则,我们应该尝试将其解析为:(1&&y)=2这没有意义,因为=需要特定的LHS(变量、常量、[]数组项等)。但是既然(1&&y)是一个正确的表达式,那么解析器应该如何处理呢?我试过咨询Ruby的parse.y,但它太像意大利面条

  7. ruby - AASM:将状态机定义与类定义分开 - 2

    假设我有这个类(直接取自aasm文档):classJobtruestate:runningstate:cleaningevent:rundotransitions:from=>:sleeping,:to=>:runningendevent:cleandotransitions:from=>:running,:to=>:cleaningendevent:sleepdotransitions:from=>[:running,:cleaning],:to=>:sleepingendendend我不太喜欢将状态机定义与类定义混合在一起的事实(当然,在实际项目中,我会向Job类添加更多方法)。我

  8. Ruby每道逻辑题 - 2

    我正在尝试解决来自SevenLanguagesinSevenWeeks的一个简单的Ruby问题Printthecontentsofanarrayofsixteennumbers,fournumbersatatime,usingjusteach这是我想到的,可以用简单的方式完成还是改进它?a=(1..16).to_ai=0j=[]a.eachdo|item|i+=1j可以在一行中使用each_slicea.each_slice(4){|x|px} 最佳答案 Teja,你的解决方案没问题。由于您需要使用每一个,因此算法的复杂性将受限于数

  9. arrays - 给定一个大小为 y 的数组,其中包含大小为 n 的数组,我如何使用 Ruby 返回所有逻辑组合? - 2

    我想做的是处理n个集合,而我在下面提供的代码正好处理4个集合。defshow_combinations@combos=[]['A','noA'].eachdo|a|['B','noB'].eachdo|b|['C','noC'].eachdo|c|['D','noD'].eachdo|d|@combos我如何重构以下代码来处理以下场景:鉴于我有一个大小为y的数组,其中包含大小为n的数组,我想返回所有组合。请务必注意,每个子数组中只能有一个项目出现在结果中。(如“已完成资料”不能同时出现在“未完成资料”的结果中)背景:用户可能有一些任务:例如,“完成配置文件”或“设置电子邮件”或其他任何

  10. ruby-on-rails - 如何使用 searchkick 进行逻辑运算的复杂查询 - 2

    我正在使用searchkick库作为产品搜索的elasticsearch客户端。https://github.com/ankane/searchkick可以创建'OR'条件和'AND'条件;AND运算Product.search其中:{price:{lte:200},in_stock:true}或运算Product.search其中:{或:[[{in_stock:true},{backordered:true}]]}但我坚持使用searchkick创建多个“AND”“OR”条件。我需要类似的东西A或B或(C和D)或者我需要这样,A与B与(C或D)请指导我,如何实现这一目标谢谢

随机推荐