What is the best MVC, Doctrine2, Datamapper practice? - php

I am looking into using Doctrine2 with my Zend Framework setup. I really like the datamapper pattern, mainly because it seperates my domain models with my database.
My question is what is the best practice for using Doctrine and DQL with my controllers?
controllers uses Doctrine
DQL/EntityManager directly for
saving/loading my domain models?
create my own classes in the
datamapper pattern for
saving/loading my domain models, and
then use Doctrine internally in
my own classes?
The pros. for #1 is of course that I don't need to create my own datamapper models, but again, with #2 I can later replace Doctrine (in theory)
What would you do?

Regarding your abstraction question, I'd say it really depends on the lifetime of this project and how portable your code needs to be. If it's a one-off website that will need minimal maintenance, it would probably save you some time to forego the additional abstraction layer and just write Doctrine code in your controllers. However, if you're planning to reuse this code, move it to different platforms, or maintain it for a long period of time, I'd take the time to add that abstraction because it will give you a lot more flexibility.
If you're still researching frameworks, take a look at Kohana. It's basically a lightweight rewrite of CodeIgniter written for PHP5.

I second the advice from pix0r. The additional abstraction is only worth it if it is a larger project with a potentially long lifetime and maybe with many developers on it. This is pretty much the guideline I follow, too, be it in php with doctrine2 or in java with jpa (since doctrine2 heavily resembles jpa).
If you want the additional abstraction, doctrine2 already ships with the possibility to use repositories (repositories are very similar or even equal to DAOs, maybe with a stronger focus on the business terms and logic). There is a base class Doctrine\ORM\EntityRepository. Whenever you call EntityManager#getRepository($entityName) Doctrine will look whether you configured a custom repository class for that entity. If not, it instantiates a Doctrine\ORM\EntityRepository. You can configure a custom repository class for an entity in the metadata, for example in docblock annotations: #Entity(..., repositoryClass="My\Project\Domain\UserRepository"). Such a custom class should inherit from EntityRepository and call the parent constructor appropriately. The base class already contains some basic find* functionality.
Roman

Also consider Symfony in your research. It will let you use ORM(propel/doctrine) or you may write your own data model. You can also bypass the data relationship and use direct SQL if needed.
To address your concern on 1 or 2, I personally go with ORM in my projects and bypass it if need arises. And better yet with symfony, you may switch between doctrine and propel or your own classes if you ever need to.
Pros:
1) faster development. easier to maintain. generally more secure and consistent. easy to switch databases should you ever need to.(from MySQL to Oracle, etc).
2) Faster runtime. Less dependency.
Cons:
1) Slower runtime and larger memory footprint. Dependency on other projects.
2) (reverse the pros for #1)

My thoughts are similar to pix0r's response. However, if your project is small enough that you could use the EntityManager/DQL directly in controllers then Doctrine 2 is possibly overkill for your project and maybe you should consider a smaller/simpler system.

In my experience writing persistence layer logic in the controller has always come back to haunt me in the form of technical debt. This seemingly small decision now will likely cause unavoidable and potentially large scale re-factoring in the future even on small projects. Ideally we would love to be able to copy and paste extremely thin controllers reconfigured with the appropriate models to prevent us from having to repeatedly create CRUD controllers over and over, but to allow also for customization of these controllers. In my opinion this can only be accomplished by being disciplined and keeping the persistence layer abstracted away from our application as much as possible. Since the overhead of doing that especially on a clean room controller is minimal, I can't see any good reason to advice you not to.

Related

Symfony project design pattern

The symfony 2 installer gives a best practice directory structure, but not a lot is said about how these directories should be used, where does each piece of code belong, sure the symfony framework narrows it down to views, entities and controllers, services etc. but more often then not, programmers end up putting a DQL query inside a controller and some logic to handle a specific task, while this does the job, there has to be a better method, even beyond symfony's out of the box directory structure, currently on a quest for better design pattern that would modularize and reuse as much as possible
On this quest, found a couple good articles on the interwebz, and spent a day on it, came up with a plan to separate all DB interactions to repositories, all logic to services, and keeping the controller 'thin' which acts as a central point for calling methods from repository and calling services. sounds good, will be modular and code can be reused.... BUT
This somehow moves away from OOP concepts and right into procedural programming, not that there is anything wrong with it, its just not leveraging the powerful concepts of OOP
Could making the objects more 'powerful' by adding in more functionality make it better? the services by definition should do a unit of task, will my approach make them big and ugly
a few good points on this blog here but could't really make out what they were trying to suggest as a solution
In general, the more behavior you find in the services, the more
likely you are to be robbing yourself of the benefits of a domain
model. If all your logic is in services, you've robbed yourself blind
-Martin Fowler
to summarize is Service oriented approach not leveraging the concepts of OOP? and how could this be supplemented
One of most important thoughts which you can find in Fowler's "Patterns of Enterprise Application Architecture", is that you should use right tools for your job. Depending on the complexity of your problem and domain, one or the other design pattern/architectural pattern may perform better. And following that way, in contrast to old frameworks (ZF1, SF1), SF2+ doesn't force you to go for any architectural pattern or organizing your business logic in specific way. You can even put everything outside bundles structure. So the best thing, which you can do, is to try learn more about design patterns (generally). And then, when you need, you will be able to pick one which will work best for your case.
You may want to look at:
mentioned earlier "Patterns of Enterprise Application Architecture", especially chapter: "Domain Logic Patterns".
The Four Architectures that will inspire your programming short review of different architectures.
any of books covering DDD, like: E.Evans "Domain-Driven Design", V.Vernon "Implementing Domain-Driven Design" or S.Millett and N.Tune "Patterns, Principles and Practices of Domain-Driven Design"
Domain-Driven Design in PHP decent book covering implementation of DDD patterns in PHP application, with some examples based on SF.
The Clean Architecture in PHP implementation of The Clean Architecture for PHP, focusing a lot on framework independence (with examples for ZF2 and Laravel).
With Domain Driven Design it creates fat model layers, and also calling a lot of services inside your controller may modularize your code, it still has its own set of challenges, it makes the design harder to create, and at some point there will be too many service calls inside the controller, what can actually be done is to use a few concepts from DDD.
two things to remember before starting DDD is :-
cohesion - modules that change together
coupling - modules that are dependent on each other
You need to lessen the coupling and recognize the cohesion and design the project according to it, main goal is to allow adding and removing or enable/disable/recombining of modules in future, in case you decide to alter the project
instead of having bundles depend on each other use interfaces instead
namespace MyProject\UserBundle\Activity ;
use MyProject\NotificationBundle\Notification;
use MyProject\MailBundle\Mail;
where UserBundle is coupled with NotificationBundle and MailBundle use interfaces that abstract the bundles instead
namespace MyProject\UserBundle\Activity ;
use MyProject\ServiceBundle\NotificationInterface;
use MyProject\ServiceBundle\MailInterface;
Main concepts of DDD are
value objects - an object that holds some data and is passed back and forth and does not focus identity but rather on the data that it holds, value objects can be used in symfony using embeddables
Entity - an object that holds some data but is dependent on an identity value rather than its data value
Repository - use of repository classes to make database operations make it possible to change the implementation later on, as it is centralized to one place
Aggregate - when several object belong together like a number of things that belong to a single category (eg: songs that belong to a genre), the entire collection of objects are treated as one and to make alteration to these objects would be thought on single aggregate object
Domain Events - any change in the state of the domain/data is regarded as an event, in symfony there are Event Listeners and Subscribers which can stand in for domain events, this is one of the most important concepts of DDD, filter also a great deal of improvement to the code
services - services are callable modules of code that do a unit of work, services allow code to be reused and are easier for testing and updating, services in symfony should contain the domain logic and the service layer can get pretty fat, this along with events make the code faster and more maintainable
Factory patter - this patter uses a 'factory' object that generates a different object, by doing this the name of the second object is abstracted, this helps when refactoring the code
these are generalized concepts that need to be applied to code that is highly situational, proper DDD requires the code to be modular which is a challenging task to achieve and need some experience on the engineer's part.
as already stated by others, books by 'martin fowler', ' V.Vernon' design patterns by ' gang of four' etc would be a good read
First of all there are best practices where to place files/components: http://symfony.com/doc/current/cookbook/bundles/best_practices.html.
Secondly http://symfony.com/doc/current/best_practices/business-logic.html:
In Symfony applications, business logic is all the custom code you write for your app that's not specific to the framework (e.g. routing and controllers). Domain classes, Doctrine entities and regular PHP classes that are used as services are good examples of business logic.
So you are not forced to use any architecture for your business logic.
Regarding your question - you can implement objects with operations and declare them as services (or use them directly, but in this case when you want to replace some functionality you'll need to rework more code).
there are always a lot of principles of software designing and we select what we think is more correct and makes more sense for a project and Symfony doesn't force us to use some special design pattern.

Model architecture without ORM or Framework for API

Let me first say that I realize this question is vague and does not have a single answer. Nonetheless, I would greatly appreciate the insight of the StackOverflow community. To the purpose of this site, an answer will be chosen based on adherence to the specification and its address of roadblocks.
Overview
I am starting a project that will largely be a RESTful API, currently with about a half dozen models. However, their will also be a website. The goal is loosely to follow an MVC architecture so that the site and API utilize the same codebase. My plan is to heavily utilize Models, and light (or not at all) on Controllers. The views will vary between JSON (API) and HTML (website).
Specification
No ORM. I'm married to MySQL + PHP at the moment. While this may change later, I'm comfortable committing to the two and therefore don't need an ORM.
Balanced Abstraction. I do believe in Fat Models. However, per the above, I don't need queries written for me. Nonetheless, I still want to encapsulate the model properties.
Speed. As the site will largely utilize the API, speed is a cornerstone. With respect, I'd rather avoid the weight of a full-stack framework.
Roadblocks
If models are custom classes, what would be the best way to load multiple. I'd prefer to lazy load, but not at the expense of performance. Without pre-optimizing, what would be a clean approach for loading multiple models without the a half dozed require() statements at the top of every page.
Balancing abstraction, I don't want to create getX() methods in each Model for every possible query. Yet, I would like to avoid writing queries in my views. So how can I cleanly balance this between abstraction and still respect MVC paradigm?
If something exists that focuses on Model abstraction, which it probably does, please point me in that direction. However, I am familiar with CakePHP, Frapi, Code Ignitor and have read up on Doctrine. I believe these don't meet the specification.
Check out Eric Evans' Domain-Driven Design, or the free online redux Domain-Driven Design Quickly.
Specification
You don't need to use an ORM if you don't want to. Or you can use an ORM sometimes, or custom SQL other times as needed. Whatever code you write within those methods to query a database is an implementation detail and should be abstracted by the public-facing interface of the Model class.
You should write Model methods to encapsulate logical operations pertaining to your application. That is, your classes and methods are based on higher-level business requirements, not as low-level CRUD operations.
There's no need to have a Framework with a capital F to utilize Models. Check out the Page Controller pattern, which IMHO fits the PHP convention better than the Front Controller pattern that is so common among frameworks.
Roadblocks
Regarding lazy-loading, try the autoloading feature of PHP.
Avoid tedious getters and setters by designing your Model classes to higher-level interfaces, according to business goals, not low-level CRUD. A Model method could return a PHP hash array of other Model object instances. For simple object fields, you could simply make object member variables public.

Using Doctrine with Domain Driven Design

I'm thinking of implementing a Domain Driven Design approach (similar to the one described here), but want to integrate it with the Doctrine ORM. Has anyone had any success doing anything like this?
My initial instinct was to use Doctrine as the DAO layer, but it seems a a bit convoluted for Doctrine to map my database fields, and my entity objects map to (essentially) the same set of fields on the Doctrine object.
My original goal was to separate all my DQL/query logic from my domain Entities, but now I'm feeling a little lost in design-pattern land at the moment.
I know Doctrine 2 is supposed to provide a much more friendly approach to DDD techniques, but I'm not sure I want to wait that long. Does what I want to do make sense, or should I find another approach?
Thanks.
Doctrine is, in my opinion, imperfect for DDD because of the lack of a Repository class. Doctrine supports patterns such as Table Data Gateway and Active Record which, whilst good patterns for certain problems, aren't necessarily the best choice for 'classic' DDD. You can, however, work around these deficiencies.
One option is to derive from Doctrine_Table and use that as a poor man's repository. For example, if you have a class called 'BlogPost', you might have a table class 'BlogPostTable', inheriting from Doctrine_Table. You can then add methods such as 'findByCategory' to the BlogPostTable class, keeping such logic separate from your domain objects (which inherit from Doctrine_Record). It's not exactly the same as the patterns advocated by 'pure' DDD, but it's close enough.
Even without the exact same design patterns, you can still use the central insights of DDD. The main one is the Ubiquitous Language, the concept of trying to describe your domain using precise language that is readable by domain experts and developers alike.

PHP data access design patterns to complement an ORM

I've currently got a site that depends on an Active Record pattern using the Doctrine ORM in PHP. I'm generally a fan of this approach - it's very straightforward and works well for managing for simple CRUD apps. But as this site grows, I think my need for more robust domain functionality will grow as well. I was wondering what other kinds of data design patterns work well in conjunction with an ORM.
My basic problem right now is that Doctrine seems to work best as a fancy querying language, so my models are littered with methods like:
function getBySomeClassfication($classification)
{
return Doctrine_Query::create()
->select('stuff')
->from('ModelClass')
->where('something = ?', $classification)
->execute();
}
or if I want to access a model class directly:
Doctrine::getTable('ModelClass')->findAll();
This means I end up working with Doctrine's object wrappers instead of directly on my domain objects. I feel like all this should exist at a lower level of abstraction.
I'm just not quite sure what the best approach is. I feel like the ORM is an excellent layer for querying single tables and dealing with relationships. But I'd like to have more flexibility in creating domain objects that work across multiple models/tables.
I've read up on using the Repository pattern, but still have a few hesitations:
I don't want to just create a pointless layer of abstraction that simply bubbles up the original problem.
I don't want to re-create or render useless the whole point of using an Active Record ORM.
Any thoughts or suggestions?
You need to work with the object wrappers (Data Access Objects) at some point and at some point your calls will be implementation (here Doctrine-) specific. It mainly depends on your current architecture on how many layers you want to put in between, but I would say - as less as possible. Is there any specific problem you have that Doctrine doesn't solve?
I sometimes don't see the point in having to deal with database specifics (e.g. one Domain Entity spreading over several tables) at all when using the ORM as a tool for (from scratch) Object Oriented Domain Model development.
I recently answered a more Java specific question here, but maybe it helps you, too for the architecture idea.
You might have a look at the Zend Framework ORM implementation(if you haven't already) where it is also possible to define relationships across multiple tables.
I hope that helps.

activerecord as model, is this a good idea?

Recently thanks to rails' popularity, many people start using activerecord as model. however, before I heard of rails (my peer group was not a fan of open source stuff, we were taught in a .NET school...) and while I was doing my final year project, i found this definition for a model
The model represents enterprise data and the business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the model.
it doesn't say the model should represent one table as what activerecord does. And normally within a transaction, one may have to query a few unrelated tables and then manipulate data from different tables... so if activerecord is used as model, then either one would have to cram all the logic code into the controller (which is kinda popular in some php frameworks) that makes it difficult to test or hack the activerecord model so that it performs database operation on not only the table it maps to, but also other related tables as well...
so, what is so great about abusing (IMHO) activerecord as the model in a MVC architectural pattern?
Martin Fowler described this pattern in Patterns of Enterprise Application Architecture together with two other patterns or architectures. These patterns are good for different situations and different amounts of complexity.
If you want to so only simple stuff you can use Transaction Script. This is an architecture you saw in lot's of old ASP and PHP pages where a single script contained the business logic, data-access logic and presentation logic. This falls apart fast when things get more complicated.
The next thing you can do is add some separation between presentation and model. This is activerecord. The model is still tied to the database but you've a bit more flexibility because you can reuse your model/dataccess between views/pages/whatever. It's not as flexible as it could be but depending on your data-access solution it can be flexible enough. Frameworks like CSLA in .Net have a lot of aspects from this patterm (I think Entity Framework looks a bit too much like this too). It can still handle a lot of complexity without becoming unmaintainable.
The next step is separating your data-access layer and your model. This usually requires a good OR mapper or a lot of work. So not everyone wants to go this way. Lot's of methodologies like domain driven design perscribe this approach.
So it's all a matter of context. What do you need and what is the best solution. I even still use transaction-script sometimes for simple single use code.
I've said many times that using Active Record (or ORM which is almost the same) as Business Models is not a good idea. Let me explain:
The fact that PHP is Open Source, Free (and all that long story...) provides it with a vast community of developers pouring code into forums, sites like GitHub, Google code and so on. You might see this as a good thing, but sometimes it tends not to be "so good". For instance, suppose you are facing a project and you wish to use a ORM framework for facing your problem written in PHP, well... you'll have a lot of options to choose for:
Doctrine
Propel
QCodo
Torpor
RedBean
And the list goes on and on. New projects are created regularly. So imagine that you've built a full blown framework and even a source code generator based on that framework. But you didn't placed business classes because, after all, "why writing the same classes again?". Time goes by and a new ORM framework is released and you want to switch to the new ORM, but you'll have to modify almost every client application using direct reference to your data model.
Bottom line, Active Record and ORM are meant to be in the Data Layer of your application, if you mix them with your Presentation Layer, you can experience problems like this example I've just laid.
Hear #Mendelt's wise words: Read Martin Fowler. He's put many books and articles on OO design and published some good material on the subject. Also, you might want to look into Anti-Patterns, more specifically into Vendor Lock In, which is what happens when we make our application dependent on 3rd party tools. Finally, I wrote this blog post speaking about the same issue, so if you want to, check it out.
Hope my answer has been of any use.
The great thing about using the Rails ActiveRecord as a model in MVC is that it gives you an automatic ORM (Object Relational Mapper) and easy way to create associations between models. As you have pointed out, MVC can sometimes be lacking.
Therefore, for some complex transaction involving many models, I'd suggest to use a Presenter in between your controller and your models (Rails Presenter Pattern). The Presenter would aggregate your models and transactional logic and would remain easily testable. You definitely want to strive to keep all of your business logic in your models or presenters, and out of your controllers (Skinny Controller, Fat Model).

Categories