D
D
Denis_R2014-10-23 22:53:05
symfony
Denis_R, 2014-10-23 22:53:05

Should I inject a service into an entity for ease of entity interface?

There is a MapPoint entity. It has a location property. There should also be a fakeLocation property, the value of which can be calculated by different algorithms. To calculate and describe algorithms, I want to use the Strategy
pattern . There are two implementation options.
First. Inject the strategy into the entity as a service (for example, as described here ).

class MapPoint
{
    /** @var array(ширина, долгота)  */
    private $location;

    private $fakeLocationBuilderStrategy;


    public function getFakeLocation()
    {
        return $this->fakeLocationBuilderStrategy->createFakeLocation($this->location);
    }

    // прочие геттеры и сеттеры...
}

Second. Create an additional FakeLocationBuilder service. Inject FakeLocationBuilderStrategy into it. And for each entity call:
FakeLocationBuilder::setFakeLocation(MapPoint $mapPoint)
{
    $fakeLocation = $this->fakeLocationBuilderStrategy->createFakeLocation($this->location);
    $mapPoint->setFakeLocation($fakeLocation);
}

The first method seems to be contrary to generally accepted rules. But the second one looks much more cumbersome. Plus, spreading the internal behavior of an object over additional services, IMHO, is contrary to encapsulation.
Question: what are the pros and cons of both solutions? Are there other ways to solve this problem?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Denis, 2014-10-24
@prototype_denis

I would throw all the logic into the model and not use services ...
Or the model as an abstract class above another model (or service).
In fact, this model will be "Strategic"

class MapLocationModel 
{
    protected $location;
    protected $fakeLocation;
    
    public function getFakeLocation() 
    {
        if (null === $this->fakeLocation) {
            // other logic
            $fakeLocation = null;
            // $this->setFakeLocation($fakeLocation ?: $this->getLocation());
            $this->setFakeLocation($fakeLocation);
        }
        
        return $this->fakeLocation;
    }
    // public function setFakeLocation($location)
    //...
}

class MapLocation extends MapLocationModel
{
    protected $location;
    protected $fakeLocation;

    public function getFakeLocation()
    {
        return parent::getFakeLocation();
    }
}

This will allow you to completely separate the entity, not touch the controllers that use the entity, and also make the model itself more independent where all the logic will be produced.
And in order not to bind the model itself to a certain class, then implement a private method for obtaining a class that will collect "Strategic implementers" and return the "strategic method".
$result = $class->$method( $location );
My thoughts in three words: MapLocationEntity extends StrategyMapLocationModel

M
Maxim, 2014-10-24
@maxloyko

I would create a separate service and use it where needed.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question