gogolinsky писал(а): ↑2017.12.19, 16:54
На сайте есть каталог, в котором нужно выводить уже посчитанную цену товара с учетом скидки для человека. Есть корзина, в которую нужно класть товар с подсчитанной скидкой. В каждом случае перед удобнее же использовать getPrice() сущности Товар. Может лучше заинъектить этот калькулятор внутрь сущности и вызывать из getPrice()? Можно вообще в сущности в конструктор передавать сервисы?
На мой взгляд вы все правильно думаете, сейчас я сам бы так и сделал, хотя раньше был против внедрения через конструктор в AR и сущности, затем для себя пришел к другому выводу. В Yii внедрять через конструктор AR да, пока нельзя, но может они это исправят, посмотрел трекер - вроде пока все задачи связанные с этим закрыты:
https://github.com/yiisoft/yii2/issues/5786, а жаль.
Либо через метод (неудобно будет таскать везде сервис для вызова), либо через локатор сервисов Yii::$container. Да, тест будет посложнее, придется локатор с нужным объектом в setUp() сначала сделать.
Код: Выделить всё
interface PricingStrategy
{
public function price($product):
}
class CustomPricedProduct extends ActiveRecord
{
private $pricing_strategy;
public function init()
{
//видимо, это вместо конструктора с кастомными зависимостями и задумывалось разработчиками Yii.
//почему не прямо в price() обращаемся к локатору - потому что удобнее,
//все обращения к локатору в одном методе класса, легче понять его зависимости (сохраняет много времени и сил)
$this->pricing_strategy = \Yii::$container->get(PricingStrategy::class);
parent::init();
}
public function price()
{
//передаем объект товара, стратегии может понадобиться все что угодно - базовая цена, производитель и т.п.)
return $this->pricing_strategy->price($this);
}
}