php - 将 Eloquent 模型与业务逻辑分离

标签 php laravel orm solid-principles single-responsibility-principle

我想编写离散框架不可知模型。

我为所有这些模型编写了接口(interface)。

问题是在实现这些接口(interface)时,例如使用 Eloquent,我将所有业务逻辑链接到 ORM 中。

例如,我想要在 Product 模型上使用 addVariation 方法。

界面

interface ProductInterface
{   
    /**
     * Adds a variation
     *
     * @param VariationInterface $variation
     */
    public function addVariation(VariationInterface $variation);

    // ...
}

结核

class Product extends Model 
{
    /**
     *  @param Collection | VariationInterface
     */
    protected $variations;

    public function addVariation(VarientInterface $varient)
    {
        if( ! $this->hasVariation($varient) ) 
        {
            $this->variations->add($variations);
        }

        return $this;
    }
}

我遇到的问题是我的所有业务逻辑都存在于我的模型的特定 Eloquent ORM 实现中。

我怎么可能把它分开呢?我能看到的唯一真正的依赖是我需要某种类型的集合类?或者也许我可以只使用普通的旧数组?

我只是不想将我的所有逻辑链接到特定的 ORM 我想保持框架不可知。

最佳答案

只需从 Eloquent ORM 中删除所有逻辑即可。

您只需要一个 ORM 就可以更轻松地从数据库中保存和检索数据。您应该使用普通的旧 php 对象编写所有业务逻辑。然后,您可以创建一些通用 PersistenceGateway 接口(interface),供您的所有业务逻辑模型使用,例如

interface PersistenceGatway {

   public function saveGatewayData($id, array $data);

   public function retrieveGatewayData($id)
}

您的解耦业务逻辑使用此接口(interface)来保存检索数据。然后您需要做的就是使用您选择的 ORM 实现接口(interface)(或者您可能还需要创建一些适配器类来帮助您)。现在,您可以插入任何您喜欢的 ORM,只要它实现 PersistenceGateway 接口(interface)即可。

看看Uncle Bobs Clean Architecture 。像 Laravel 这样的 Web 框架应该是您的应用程序/业务逻辑的插件,而不是相反。

编辑:非常基本的示例。

class SomeBusinessLogic {

   // Note: Class depends on the PersistenceGateway. Any class
   // that implements this interface can be passed in. This is
   // essentially how you decouple logic from ORMS. You can now 
   // implement this interface with any ORM you like and pass it in
   public __construct(PersistenceGateway $gateway){
      $this->gateway = $gateway;
   } 

   public function someLogicMethod($id){
      // do something and save state to the gateway
      $this->gateway->saveGatewayData($id, ['some_state'=>'value']);
   }

   public function someDataReturnMethod($id){
      return $this->gateway->retrieveGatewayData($id);
   }

}

// Im extending from Eloquent here, but you can do a similar thing
// with any ORM.
class SomeEloquentModel extends Eloquent implements PersistenceGateway {

   public function saveGatewayData($id, array $data){
       $model = $this->find($id);
       // call eloquent save method
       $model->save($data);
   }

   public function retrieveGatewayData($id){
       // retrieve the data. Important to return
       // an array NOT an eloquent model, otherwise
       // we are still coupled. I think toArray() is
       // the correct method to call on eloquent model
       return $this->find($id)->toArray();
   }
}

class SomeController {

    class someControllerMethod {
       // Your controller decides on the implementation of PersistenGateway
       // to use. You could also use an IoC container which would be a slightly
       // cleaner solution
       $logic = new SomeBusinessLogic(new SomeEloquentModel());
       $logic->someLogicMethod(Input::get('id'));
       return $logic->someDataReturnMethod(Input::get('id'));
    }

}

关于php - 将 Eloquent 模型与业务逻辑分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27495823/

相关文章:

python - Django ORM 魔法。错误还是功能?

php - mysql:将默认值存储为变量

php - 带有选择字段问题的联系表

php - 获取两个表之间的差异?

laravel - 为什么在用 spatie/browsershot 生成的 pdf 文件中没有标题并且任何页面的最后一行都被切断?

php - preg_match编译失败:字符类中的无效范围

laravel - DataTables时刻按自定义格式排序

php - MySQL,使用预准备语句插入时 DEFAULT 不起作用

java - Hibernate 和子对象(添加与清除)

python - 在 SQLAlchemy 中为分片动态设置 __tablename__?