Я хочу написать дискретные рамки агностических моделей.
Я написал интерфейсы для всех этих моделей.
Проблема заключается в том, что при реализации этих интерфейсов, например, с Eloquent, я связываю всю свою бизнес-логику с ORM.
Например я хочу метод addVariation
на Product
модель.
Интерфейс
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 PersistenceGatway {
public function saveGatewayData($id, array $data);
public function retrieveGatewayData($id)
}
Ваша отделенная бизнес-логика использует этот интерфейс для save
а также retrieve
данные. Затем все, что вам нужно сделать, это реализовать интерфейс с вашим ORM по вашему выбору (или вам может понадобиться также создать некоторый класс адаптера, чтобы помочь вам). Теперь вы можете подключить любой ORM, который вам нравится, при условии, что он реализует PersistenceGateway
интерфейс.
Взгляни на Дядя Бобс Чистая архитектура. Веб-фреймворки, такие как Laravel, должны быть плагином для вашего приложения / бизнес-логики, а не наоборот.
Изменить: очень простой пример.
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'));
}
}
Других решений пока нет …