Using phpspec to test two-way relationships that require pass by reference - phpspec

I'm using phpspec to test my zend 2 module and having issues with testing pass-by-reference. I've read other topics about this that state it's bad design if you are having to do this. I disagree that this a blanket statement.
I need to represent a two-way relationship between classes where two classes have references two each other.
Is there a way for me to get phpspec to test this or is there a better design I need to consider.

I want to ensure that Class A can return Class B and vice versa.
This is not really a behaviour, but state verification. PhpSpec focuses on behaviour, but what you need to do is still possible:
class ASpec extends ObjectBehavior
{
function it_exposes_B(B $b)
{
$this->beConstructedWith($b); // or $this->setB($b);
$this->getB()->shouldReturn($b);
}
}
The BSpec would look similar:
class BSpec extends ObjectBehavior
{
function it_exposes_A(A $a)
{
$this->beConstructedWith($a); // or $this->setA($a);
$this->getA()->shouldReturn($a);
}
}

Related

Repeat Mutators

I'm using several mutators that are basically the same on different models and within the same models, for different fields. eg: to tidy dates:
public function getStartShortDateAttribute()
{
return $this->start_time->format('d-m-y');
}
Is there a standard way to reuse the same mutator for several fields across models?
Use a trait, which is a way to reuse code across classes.
trait HasStartTimes {
public function getStartShortDateAttribute()
{
return $this->start_time->format('d-m-y');
}
}
Now you can use this trait in your class, with the use statement. When done it will include the traits function, in the classes that uses the trait. This is an design approach that is used already in Laravel, see AuthenticatesUsers.
class YourModel {
use HasStartTimes;
}

Symfony and Domain Driven Design

In Symfony 3, how would you differentiate the following based on Domain Driven Design (DDD)?
Service (the one that is defined in config service file)
Doctrine Repository (\Doctrine\ORM\EntityRepository)
Entity (a class in entity folder)
I'm aware that doctrine is decoupled from Symfony (i.e. it can be completely omitted). But then which one is the repository in a Symfony project without Doctrine? Or perhaps Symfony (without Doctrine) is actually not really following DDD ?
Edit
I try to mock up a scenario below to make my question clearer
A controller has a function to return all available managers for a project
class ManagementController
public function getAvailableManagers(Array $project)
{
...
}
}
Available managers means that they have no projects on their hand and the project falls within their specialised domain (e.g. customer service, business relations, logistics, etc)
However due to poor design, the speciality domain is not stored in the database but instead needs to be called to a separate HR system via API call. Later on it will be integrated to the database
I would have thought (feel free to correct me) that the Manager should be a repository class because it currently get its information from 2 different sources. The question is ... should I use Doctrine Repository for this? Or maybe it should be just a normal entity or a perhaps a service?
class ReplacementInstructionRepository extends \Doctrine\ORM\EntityRepository
{
private $id;
private $name;
private $speciality;
private $projects;
}
I need a guide on how to split this. Thank you
Cheers,
Although I don't understand well the question, here you have some examples of projects applying DDD principles with Symfony.
https://github.com/PhpFriendsOfDdd/state-of-the-union/blob/master/README.md
EDIT
After your last description I think I can give a better answer :-).
I would say that the Specification Pattern fits well in your scenario. Specification Pattern allows you to keep business rules in your Domain layer. In this case you mentioned an important business rule:
Available managers means that they have no projects on their hand and the project falls within their specialised domain (e.g. customer service, business relations, logistics, etc)
In this case, you mentioned a poor design we need to deal with. In a greenfield project I would save the manager's specialised domain within the manager, so everything would live within the same Aggregate Root, the Manager.
In your case, I would integrate the external party (HR system) via Repository like you can see below:
nampespace xxx\infrastructure\persistence
class ManagersRepository
{
public function __construct(HrApiClient $apiClient)
{
$this->apliClient = $apiClient;
}
public function findWithoutProjects()
{
$sqlQuery = //find all managers without project
$managers = $this->execute($sqlQuery);
foreach ($managers as $manager) {
$projects = $this->apliClient->findProjectsOfManagerId($manager->id());
$manager->specialisedIn($projects); //This should be done with reflection
}
return $managers;
}
public function selectSatisfying(Specification $specification)
{
return $specification->satisfyingElementsFrom($this);
}
}
namespace xxx\Domain
class ManagersAvailableSpecification implements Specification
{
public function __construct($aNewProject)
{
$this->aNewProject = $aNewProject;
}
public function isSatisfiedBy($manager)
{
// business rules here...
if ($manager->isSpecialisedIn($this->aNewProject)) {
return true;
}
return false;
}
public function satisfyingElementsFrom(ManagersRepository $managersRepository)
{
$managers = $managersRepository->findWithoutProjects();
return array_filter(
$managers,
function (Manager $manager) {
return $this->isSatisfiedBy($manager);
}
);
}
}
Notice that the first class, as it is an concrete implementation of the repository (using MySql, Postgre, etc), lives in the infrastructure layer. While the second one, as it depends just on interfaces it lives in the Domain along with the business rules that defines an available manager.
Now you can have a Service like:
class FindAvailableManagersService
{
private $managersRepository;
public function __construct(ManagersRepository $managersRepository)
{
$this->managersRepository = $managersRepository;
}
public function execute(FindAvailableManagersRequest $request)
{
$managersAvailable = $this->managersRepository->selectSatisfying(
new ManagersAvailableSpecification($request->project())
);
return $managersAvailable;
}
}
Notice also that if in the future you migrate the specialized domains from the third party to your own database, you just need to modify one class but nothing else gets touched :-)
The question is ... should I use Doctrine Repository for this?
I think this is the most classic misunderstanding related to DDD. The ORM respository and entity is completely different than the DDD repository and entity. They just have the same name but that's all, you should not confuse them.
The DDD entity lives in the domain and does not depend on classes outside of the domain. The DDD repository interface is defined in the domain and the implementation is in the infrastructure and can depend on other parts of the infrastructure. So to implement the DDD repository interface you can use an ORM repository if you want, but you can use completely different data storage solutions than relational databases, for example noSQL databases.

Doctrine 2 Value Objects

I have been implementing value objects as custom DBAL types in Doctrine 2 and it's been working OK. However I have been wondering if this is the best way. I've thought about using the Post Load listener to instantiate the Value Objects. Also instantiating them through Entity accessors when requested, the advantage with the latter would be that I would not instantiate more objects than I need.
My question is: which method is best? Or is there a better way to do it? Are there any gotchas or unreasonable performance hits with the above?
IMHO, both approaches are equally valuable, while waiting for native support for value objects.
I personally favor the second approach (instantiating them through accessors when requested) for two reasons:
As you mentioned, it offers better performance as the conversion is only done when needed;
It decouples your application from Doctrine dependency: you're writing less code that is Doctrine-specific.
An example of this approach:
class User
{
protected $street;
protected $city;
protected $country;
public function setAddress(Address $address)
{
$this->street = $address->getStreet();
$this->city = $address->getCity();
$this->country = $address->getCountry();
}
public function getAddress()
{
return new Address(
$this->street,
$this->city,
$this->country
);
}
}
This code will be fairly easy to refactor when Doctrine will offer native VO support.
About custom mapping types, I do use them as well, for single-field VO (Decimal, Point, Polygon, ...) but would tend to reserve them for general-purpose, reusable types that can be used across multiple projects, not for project-specific single-field VO where I would favor the approach above.

Can I include a convenience query in a Doctrine 2 Entity Method?

I'd like to include some additional functions in my Doctrine 2 entities to contain code that I'm going to have to run quite frequently. For example:
User - has many Posts
Post - has a single user
I already have a function $user->getPosts(), but this returns all of my posts. I'm looking to write a $user->getActivePosts(), which would be like:
$user->getPosts()->where('active = true') //if this were possible
or:
$em->getRepository('Posts')->findBy(array('user'=>$user,'active'=>true)) //if this were more convenient
As far as I can tell, there's no way to get back to the entity manager though the Entity itself, so my only option would be
class User {
function getActivePosts() {
$all_posts = $this->getPosts();
$active_posts = new ArrayCollection();
foreach ($all_posts as $post) {
if ($post->getActive()) {
$active_posts->add($post);
}
}
return $active_posts;
}
However, this requires me to load ALL posts into my entity manager, when I really only want a small subset of them, and it requires me to do filtering in PHP, when it would be much more appropriate to do so in the SQL layer. Is there any way to accomplish what I'm looking to do inside the Entity, or do I have to create code outside of it?
I think you should implement the method on the PostRepository rather than on the entity model.
I try to keep all model related logic in the repositories behind "domain specific" methods. That way if you change the way you represent whether a post is active or not, you only have to change the implementation of a single method instead of having to find all the active = true statements scattered around in your application or making changes in an "unrelated" entity model.
Something like this
PostRepository extends EntityRepository {
public function findActiveByUser($user){
// whatever it takes to get the active posts
}
}

How do you share common methods in different grails controllers?

Currently when I need to share a method like processParams(params) between different controllers, I use either inheritance or services.
Both solution has some inconvenients :
With inheritance, you cannot use multiple inheritance which means that you need to have all of your controller utility methods in one place. And also, there is a bug in grails that does not detect any code changes in Base Controller classes in development mode (you need to restart the app)
With services, you don't have access to all injected properties like params, session, flush...
So my question is : is there any other way to use some common methods accessible for multiple controllers ?
One option I like is to write the common methods as a category, then mix it into the controllers as necessary. It gives a lot more flexibility than inheritance, has access to stuff like params, and the code is simple and understandable.
Here's a tiny example:
#Category(Object)
class MyControllerCategory {
def printParams() {
println params
}
}
#Mixin(MyControllerCategory)
class SomethingController {
def create = {
printParams()
...
}
def save = {
printParams()
}
}
Common functionality is a call for a new class, not necessarily common ancestor. The question formulation is missing responsibility statement for it. Needless to say, it's a single responsibility that we create a new class for. I take further decisions basing on class responsibility.
I prefer a hybrid of robbbert's and Jared's answers: I construct extra classes, passing them necessary controller internals as parameters. Sometimes the classes develop from method objects.
Like:
def action = {
def doer = SomeResponsibilityDoer(this.request, this.response)
render doer.action()
}
Not so brief, but lets you get code under tests and keep coupling low.
As SomeResponsibilityDoer is only going to have couple of fields - request an response - it's not a big deal constructing it with every request.
It's also not a big deal having SomeResponsibilityDoer not reloaded on controller change in dev, because:
Initially, you can declare it in some of Controller files - it will be reloaded. After you complete it, hopefully it won't change often, so move it to src/groovy.
Even more important, it's faster and better for design to develop under unit tests than under application running and reloading a Contoller.
This doesn't help the restarting in development mode issue you have, but it's the way I've solved this problem. It's ugly and probably not good practice, but I factor common code into classes as closures. Then I can do something like:
new ControllerClosures().action(this)
and from with in the controllerClosures class
def action={
it.response.something
return [allYourData]
}
You can use the Delegation design pattern:
class Swimmer {
def swim() { "swimming" }
}
class Runner {
def run() { "running" }
}
class Biker {
def bike() { "biking" }
}
class Triathlete {
#Delegate Swimmer swimmer
#Delegate Runner runner
#Delegate Biker biker
}
def triathlete = new Triathlete(
swimmer: new Swimmer(),
runner: new Runner(),
biker: new Biker()
)
triathlete.swim()
triathlete.run()
triathlete.bike()
In case of a controller, assign the helper class directly at the instance field (or in the nullary constructor):
class HelperClass {
def renderFoo() { render 'foo' }
}
class FooController {
private #Delegate HelperClass helperClass = new HelperClass()
def index = { this.renderFoo() }
}
The delegate's type information gets compiled into the containing class.
You can write all the common method in commonService
and use that service to envoke commmon method

Resources