Behavior driven development

You may know that Propel allows to define behaviors. Up to recently, I used to think behaviors just added cool features to my models. It took me time to realize that in fact, behaviors allow my models to have a uniform API. In this article, I'll expose how to define application scoped behaviors, but also how you should extend existing behaviors.

Extending existing behaviors

Versionable is definitely a cool feature. It's easy to use, quite transparent, and it does its job : keep track of the entity modifications. But how can you keep track of who made the changes? Should you set the created_by fields in every place your application saves an object? And what about the behavior configuration? Should you repeat it in every table?

The answer is obviously no, remember the DRY principle. So, how can you centralise this code and configuration in a better place than in MyApplicationVersionableBehavior?

Extend the original behavior, override the parameters property, define a preSave() method retrieving the current user, and from now on just focus on your business logic!

Creating application behaviors

If you use an ORM and a framework, it usualy means that your application requires a specific business logic. Most of the time you may feel like repeating yourself in different models, for pieces of logic concerning resource access policy, object image...

These are perfect candidates to become behaviors, as the API will be unified for every objects. The good thing is that logic is coded once, tested once, and available everywhere...

Oh, and if your behavior can be shared, just do it, it might avoid people from reinventing the wheel. Who knows, if there are enough shared behaviors, maybe Propel2 will provide a way to simply manage external behaviors!

Posted by Julien Muetton 

4 comments

Feb 07, 2012
mhitza said...
Haha, how weird. I was already thinking about implementing Mandatory Access Control through a Propel behavior, when this post pops up.
Feb 07, 2012
Julien Muetton said...
That's a great idea !
maybe you can find something interesting in https://github.com/Carpe-Hora/ClassifiableBehavior that is a Resource Access Layer.
Feb 07, 2012
mhitza said...
Thanks @Julien, I'll definitely have to look into that throughout the following weeks.
Feb 09, 2012
Daniel Richter said...
Nice idea overall, but what concerns me a bit these days is the part about "retrieving the current user".. at that point I'm in the model, so getting that user will most likely involve a static call to somewhere, which reduces testability or usage across different contexts. I'm actually much more in favor of an even driven setup where the the model fires a pre-save event and a listener with access to my user management can pick that up.. It's not that I like everything about Doctrine(2) but that part I think they got right and we may want to encourage that line of thinking more than encouraging per-project code generation to work around this issue. Just my 2 cents.

Leave a comment...