Reputation: 51
Okay, so this is not a specific "what am I doing wrong" coding question, sorry. If it's better suited to one of the other stack* sites, let me know.
Today I was fired from a contracting gig where they're using Symfony2 and Doctrine. I'm a senior programmer, but not very experienced in either of these two frameworks - though I felt sure I could get up and running fast. After all, it's PHP - what could go wrong?</cynicism>
My assigned teammate (brought on as a "Symfony expert", so I was at first perfectly happy to watch and learn) kept insisting that 'entities should be immutable, and all custom business logic should go in repositories'. Reading the documentation (the getting started guide, no less) this simply seems to be untrue - repositories are for 'custom getters', but data manipulation goes in entities (Doctrine-speak for models). Made perfect sense to me (a database can't know if bitflag 1 means 'active' and 2 'confirmedEmail'), but the guy was adament. When pressed for an example of how I should add custom data editing methods in a repository (since I fooled around for a bit but couldn't get Symfony to see them without going through hoops and manually replacing entities with repositories), he sent a code sample implementing a more or less manual update query. Then why use an ORM in the first place?
He also repeatedly stated that one should never touch entities, since changes might get overwritten when they're regenerated. Apart from the fact that Doctrine seems to normally assume you write entities and generate the database scheme from those - not the other way around - unless my knowledge of the English language is mysteriously failing, the manual seems to clearly state that when (re)generating entities, existing methods are left alone so it's perfectly safe.
End of story, client decided we couldn't work together and chose the other guy. They also had this weird argumentation where I was "the most expensive guy on the project" and I "wasn't providing enough seniorness". I did point out that telling others they're simply wrong and getting yelled at for it (true story, well, they were typing in ALL CAPS which counts as yelling in my book) didn't make me very happy either, so that was that - I wished them the best of luck and we went seperate ways.
Am I losing my mind here? Am I missing something glaringly obvious? Or is the other guy simply misguided (my current working theory) as to what belongs in entities and what in repositories? Anyone experienced in Doctrine/Symfony care to elaborate? I'd be happy to provide more specific examples of what we were supposed to be building. I'm mostly extremely curious to learn the "right way"(tm) of doing things in these frameworks (for future reference, they didn't quite whet my appetite yet), if there indeed is a better way to abstrahate model code away from entities.
Upvotes: 2
Views: 984
Reputation: 3070
Symfony2 is built to allow you to choose how you answer these questions. It's structured to be modular, allowing you to pick and use only the components you need. There are many common design patterns but obviously a team needs to pick one and stick with it. If you guys couldn't do that, it is probably good that you didn't try to complete a project together.
I consider it good practice in Symfony2 to keep the entities and controllers as sparse and easy to read as possible. I put almost nothing in repositories that is not building queries and running them. Pretty much everything else should go in a service of one kind or another. How you enforce separation of concerns among services is left as an exercise to the development team.
Here's an article talking about a set of common design patterns: http://www.ricardclau.com/2012/02/where-is-the-model-in-symfony2-entities-repositories-and-services/
Another good thing to look at when getting a handle on how to do things and where to put thins, is take a through some of the core/big symfony bundles, see where they put things and how much the different styles of organization make sense for different purposes (some do it better than others).
His specific claims:
1) entities should be immutable
This seems to cause you to lose out of much of the functionality provided by Doctrine's EntityManger and UnitOfWork. If you then update them only using manual queries, you will have to reload your entities to get them to match the updated DB state. I guess this makes sense if you want to load one state at the start of a request and progressively process updates to the DB based solely on the original data. (Doctrine does provide functionality in the EntityManger to mark Entities as read-only so that changes to them will not be persisted.)
2) all custom business logic should go in repositories
In Symfony, replace 'repositories' with 'services' and this would be pretty much 100% correct. Repositories should generally only hold code for re-usable complicated queries beyond what Doctrine's findBy methods get you.
3) He also repeatedly stated that one should never touch entities, since changes might get overwritten when they're regenerated.
True...ish as far as the overwriting goes. Whenever you add changes to your entities from a schema file using doctrine command line tools this 'could' happen so backups are made. However, the tool is fairly smart and I haven't seen any of my changes overwritten.
Your specific claims:
1) but data manipulation goes in entities (Doctrine-speak for models)
Entities are not the 'M' in 'MVC' but are generally just the part of the 'M' where the state is stored. The related logic is generally kept separate in forms, data transformers, validators and other services.
2) he sent a code sample implementing a more or less manual update query. Then why use an ORM in the first place?
Even if you only update data through manual queries rather than using the EntityManger, Doctrine provides many other advantages: Programatic Query Generation, Input Cleaning, Entity Hyrdation, Query/Result Caching, Nested Transactions, ETC.
Just hearing your side of the story, it sounds like a more senior developer with less framework experience working with a less senior developer with more framework experience. I would guess that the other developer had never worked solo/lead on a greenfield Symfony2 project and was just parroting the design decisions made by his prior Senior developer.
Neither of you sounds completely 'right' and both of you were wrong in that you got bogged down in an argument that had to be adjudicated by your client. Maybe if you had been less keen on showing yourself right, and been more willing to utilize and explore your partner's experience by delving into the the reasons behind the practices he was advocating you might have been able to turn this into a success.... Or perhaps the other developer was just a tool and you saved yourself a boatload of stress and drama trying to cover his ass :)
Upvotes: 2