Skip to content

[Workflow] added a TransitionsCollectionBuilder so DefinitionBuilder doesn't need Transition objects #20498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

HeahDude
Copy link
Contributor

@HeahDude HeahDude commented Nov 12, 2016

Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? yes
Deprecations? no
Tests pass? yes
Fixed tickets #20451
License MIT
Doc PR symfony/symfony-docs#6871

I suggest to not construct Transition object repeatedly in user land code, ortherwise we can just create our own Definition, let's abstract it in the builder.

ping @lyrixx @Nyholm

@xabbuh
Copy link
Member

xabbuh commented Nov 12, 2016

What about supporting both ways (we would still need to think about good method names). That would not force the user to deconstruct already existing Transition instances.

By the way, you also need to update the constructor's docblock.

@HeahDude
Copy link
Contributor Author

I'm not a fan of supporting both, but why not? I tend to prefer the BC break though, the commit has only three days and this is a lot nicer to me. I get used to not have any new in my code as much as possible :D.

@xabbuh
Copy link
Member

xabbuh commented Nov 12, 2016

I was more thinking about use cases where you are reusing parts on an existing workflow definition.

@HeahDude
Copy link
Contributor Author

I understood #20451 was giving two possibilities. Either use one builder per definition, or keep using the same builder to add some transitions making the first a subset of the second. So I don't see the need to support what you're thinking about.

@xabbuh
Copy link
Member

xabbuh commented Nov 12, 2016

If the definition wasn't build through the builder there is nothing you could based the next definition on (except we made it possible to initialise the builder with an existing definition).

@HeahDude
Copy link
Contributor Author

Ok got you, I'm going to fix this.

Status: needs work.

@HeahDude
Copy link
Contributor Author

Status: needs review

@xabbuh
Copy link
Member

xabbuh commented Nov 12, 2016

Can you make fabbot happy too? :)

* @param string[] $places
* @param Transition[] $transitions
* @param string[] $places
* @param (Transition|array)[] $transitions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this deserves some explanation about how such an array must be composed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this simply be @param Transition[] $transitions?

@@ -79,15 +79,36 @@ public function addPlaces(array $places)
}
}

/**
* @param (Transition|array)[] $transitions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}
}

/**
* @param Transition $transition
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed

}
}

/**
* @param Transition $transition
*/
public function addTransition(Transition $transition)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this method not support an array too?

* @param string[]|string $froms
* @param string[]|string $tos
*/
public function createTransition($name, $froms, $tos)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure this method belongs to the builder to be honest

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the method name is misleading, because it does not only create the Transition (which would return it for usage) but instead it creates it internally and then adds it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok go for a polymorph addTransition.

* @param string[]|string $froms
* @param string[]|string $tos
*/
public function createTransition($name, $froms, $tos)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the method name is misleading, because it does not only create the Transition (which would return it for usage) but instead it creates it internally and then adds it

array('t4', 'd', 'f'),
array('t5', 'e', 'g'),
array('t6', 'f', 'g'),
));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why changing all these tests ? They are unrelated to your change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally removed the possibility to pass instances, and then I did not change back the tests because I found them much more readable like this, don't you?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Na, I do not think it is more readable. Sorry =)

But it is a matter of taste.

@HeahDude HeahDude force-pushed the workflow-definition-factory branch 2 times, most recently from 58d4884 to 3562fad Compare November 12, 2016 13:05
@HeahDude
Copy link
Contributor Author

Ok comments addressed here, thanks!

@HeahDude HeahDude force-pushed the workflow-definition-factory branch from 3562fad to e70fdf3 Compare November 12, 2016 13:07
@HeahDude HeahDude force-pushed the workflow-definition-factory branch from e70fdf3 to f900e2b Compare November 12, 2016 13:11
Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not to sure this is needed. Is the argument only for convenience?

Anyhow, We need to validate the inputs properly so we do not cause any weird type errors.

array('t4', 'd', 'f'),
array('t5', 'e', 'g'),
array('t6', 'f', 'g'),
));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Na, I do not think it is more readable. Sorry =)

But it is a matter of taste.

if ($transition instanceof Transition) {
$this->transitions[] = $transition;
} else {
$this->transitions[] = new Transition($transition, $froms, $tos);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to validate the input here. What if some does:

$builder->addTransition('foo', 'bar');

if ($transition instanceof Transition) {
$this->addTransition($transition);
} else {
list($name, $froms, $tos) = $transition;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to validate input. What if someone does:

$builder->addTransitions([['foo', 'bar']]);

// Or
$builder->addTransitions(['foo']);

@ro0NL
Copy link
Contributor

ro0NL commented Nov 13, 2016

Cant we introduce a TransitionBuilder? Imo. we should avoid union types (see also #20167 (comment)).

@HeahDude
Copy link
Contributor Author

And I think exactly the same as you ;)

Perhaps should be avoided, but in this case (to me) it makes most sense from a configuring perspective.

@Nyholm
Copy link
Member

Nyholm commented Nov 13, 2016

But isn't this overkill just to avoid writing new Transition('foo', 'bar', 'baz)?

@ro0NL
Copy link
Contributor

ro0NL commented Nov 13, 2016

@HeahDude :)) but that affected direct user-land php configuration files, which made it considerable. And eventually the union type was avoided anyway (hence i think here it should also).

In this case we could convert arrays to transition objects in the FrameworkExtension (using its own builder).

@ro0NL
Copy link
Contributor

ro0NL commented Nov 13, 2016

Otherwise, maybe adding createTransition would be most simple..

$builder->addTransition($builder->createTransition($array));

@Nyholm
Copy link
Member

Nyholm commented Nov 13, 2016

Sorry but I fail to understand why...

$builder->addTransition($builder->createTransition($array))

// or
$builder->addTransition($builder->createTransition('foo', 'bar', 'baz'))

... is better/simpler/more convenient than:

 $builder->addTransition(new Transition(foo', 'bar', 'baz'));

@ro0NL
Copy link
Contributor

ro0NL commented Nov 13, 2016

It's not. But it could be useful to have it when transforming configs into objects.

@Nyholm
Copy link
Member

Nyholm commented Nov 13, 2016

You mean this line in FrameworkExtension would be:

 $transitions[] = array($transitionName, $from, $to);

Is that the only win for this PR?

@ro0NL
Copy link
Contributor

ro0NL commented Nov 13, 2016

Agree. I was already looking at it... this isnt actually needed to improve that.

So, we have a definition builder for user-land, what about a transition builder as well?

$t = (new TransitionBuilder())
  ->addTos($tos)
  ->addTo($to)
  ->build();

@HeahDude
Copy link
Contributor Author

I've taking your comments into account already and started to work on it, I'm pushing it soon.

@Nyholm
Copy link
Member

Nyholm commented Nov 13, 2016

Again, why is

$t = (new TransitionBuilder())
  ->addTos($tos)
  ->addTo($to)
  ->build();

better/simpler than just:

$t = new Transition(foo', 'bar', 'baz');

@ro0NL
Copy link
Contributor

ro0NL commented Nov 13, 2016

Again.. it's not :) guess it's matter of preference? Imo. it would be just as useful for having the DefinitionBuilder?

Maybe we should re-consider that one first 😕 Ie. if we default the initial place to first available place directly in the Definition constructor, im not sure we really need a DefinitionBuilder as well.

As it was already removed from the framework extension for the same reason; overkill. Basically saying; it's practically not needed.

@fabpot
Copy link
Member

fabpot commented Nov 13, 2016

Reading the comments, I agree that we should keep things simple. I still don't understand which problems this PR is trying to solve... but I do understand it adds complexity to the code. 👎

@HeahDude
Copy link
Contributor Author

@Nyholm that's not what I've in mind, tests are failing, but I've pushed my concept.

@HeahDude
Copy link
Contributor Author

@fabpot I've just totally refactored it, one file to hold a new responsibility and a few lines changed.

@HeahDude HeahDude force-pushed the workflow-definition-factory branch from cf0c1b5 to 4814896 Compare November 13, 2016 15:15
@fabpot
Copy link
Member

fabpot commented Nov 13, 2016

I still fail to understand the issue and why this is a better than what we have today. Can you explain?

@HeahDude
Copy link
Contributor Author

HeahDude commented Nov 13, 2016

When using a DefinitionBuilder the code gets full of new Transition() instances, that feels wrong to me, but it's not really an issue.

But by introducing this transitions collection factory some tests are now failing because we use some definitions with invalid transitions and this actually looks like an issue IMHO.

@HeahDude HeahDude changed the title [Workflow] Made the DefinitionBuilder instantiate the Transition objects [Workflow] added a TransitionsCollectionBuilder so DefinitionBuilder doesn't need Transition objects Nov 13, 2016
@fabpot
Copy link
Member

fabpot commented Nov 13, 2016

So, you're saying that it' better to use an abstraction and hide the Transition class, which is a configuration instance. In any case, behind the scene, there is anyway a bunch of Transition instances that should be created. So, I prefer to be explicit an use Transition directly. Transition is a data object, it is its goal to help configuration. Still very much 👎 in this change.

@HeahDude HeahDude force-pushed the workflow-definition-factory branch from 25f7813 to c8a5882 Compare November 13, 2016 15:37
@HeahDude HeahDude force-pushed the workflow-definition-factory branch from c8a5882 to 1530498 Compare November 13, 2016 15:38
@HeahDude
Copy link
Contributor Author

Ok then, closing here. Thanks everyone for the feedback.

@HeahDude HeahDude closed this Nov 13, 2016
@xabbuh
Copy link
Member

xabbuh commented Nov 13, 2016

I am still not completely against this change, but I would rather provide two different methods. One were you pass a Transition instance and when that accept the plain values. This way we would make it possible to add transitions in both ways without the added complexity in the builder class. But we would still have to come up with some meaningful names to distinguish which method is responsible for what.

@lyrixx
Copy link
Member

lyrixx commented Nov 14, 2016

The more I think to this PR and to the DefinitionBuilder, the more I think the DefinitionBuilder is not really needed. It does not really help to reduce the number of LOC.

Example:

$transitions = [
    new Transition('name', 'A', 'B'),
    new Transition('name2', 'B', 'C'),
];

$definition = new Definition(['A', 'B', 'C'], $transitions);


(new DefinitionBuilder())
    ->addPlaces(['A', 'B', 'C'])
    ->addTransition(new Transition('name', 'A', 'B'))
    ->addTransition(new Transition('name2', 'B', 'C'))
;

What do you think?


Note: I'm agree with @fabpot about this PR and I'm also 👎 with its current state

@HeahDude
Copy link
Contributor Author

HeahDude commented Nov 14, 2016

@lyrixx It's not about the LOC, it's about being able to add transitions without passing them to the constructor and keeping the Definition immutable, so we should keep this builder IMHO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants