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).
Related
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.
Does MVC really means you have to separate => View aka design (html css) => controler (php code), model (mysql code into classes etc.)???
Are there not alternatives? Wondering because I would really like to avoid separating php code and mysqli as right now it's sooo easy to work on it (got used to it).
Yes, you definitely want to separate HTML and CSS from business logic.
Most frameworks use an ORM or something similar to abstract building queries but still give you the option to write plain SQL. I would recommend to use an ORM like doctrine2 for example over plain SQL. If you use any SQL directly the model would most likely the right place to put it into.
MVC exists for a reason, separation of concerns. This makes sure that your application becomes easy to maintain because every part of it should be easy to replace and not depend on each other to much. You want to avoid strong coupling. MVC is a pattern that helps you with that.
And like tttpapi said, there other ways to do it, but honestly, I personally think that specially Wordpress for example is a horrible clutter. I don't like Drupal or Joomla as well. The code base feels like working with 10 year old clutter compared to a modern well written application following the MVC pattern.
This is a little about discipline es well, I've seen totally messed up applications as well because people did not pay attention to separation of concerns and didn't follow the MVC pattern.
Does MVC really means you have to separate => View aka design (html
css) => controler (php code), model (mysql code into classes etc.)???
No.
MVC is about separation pf concerns. It separates presentation layer from model layer. And within presentation layer - it separates handling of input (controllers) from handling of output (views).
The model in MVC is not a databases abstraction or collection of queries. Instead it is a layer that contains several groups of classes. The major groups are domain objects, data mappers and services. The model in MVC is all these things taken together.
Longer explanation: here
Note: do not confuse MVC's model with domain model, which is the accumulated knowledge and vocabulary for specifica application. The part of domain model, that can be encompassed in code, is implemented using domain objects.
View is not html and css. Views in MVC are classes that contain the UI logic for the application. THey acquire data from model layer and then, based in this information, choose which templates to use for producing a response.
Longer explanation: here
Controllers are not some mystical "php code". They are part of application that takes user input, and based on that alter the state of model layer and (in rare cases) state of current view.
Are there not alternatives? Wondering because I would really like to
avoid separating php code and mysqli as right now it's sooo easy to
work on it (got used to it).
The point is NOT separating SQL from PHP.
The separation of concerns principle simply means that each part of your application should be dealing with one specific aspect.
And, if you try to implement MVC architecture, it will NOT mean that you separate sql from php, but that you separate business logic from persistence logic. Both of those would be written in PHP. But the trick is - MySQL is not the only form of storage. Data can also be stored in session, in cache, in noSQL, in files, in SOAP, etc. If you have separated business logic from persistence logic, then you can add caching to your existing application without rewriting the whole thing.
Also ...
There are more architectures then just MVC and Big Ball of Mud (which was advertised by people who talked about Drupal and Joomla).
You have MVP, MVVM, n-Tier, DCI, EDA and many others. And all these will be adhering to SoC principle .. but the result that they come up with will be different.
P.S.: If you actually want to learn about MVC, I would recommend for you to start going through materials from this list. It will start by introduction to simple concepts and gradually build up to ideas that you have to grasp to actually start working with MVC.
It is always up to you.
You always can find way how to use MVC as nonMVC. (example is Joomla here you can use just view with all code in it)
Or you can use systems that are not MVC bases such as Drupal.
But the MVC is here for some reasons.
To directly answer your question, yes MVC means exactly that.
However MVC is just a design pattern, and not a holy writ.
There are many variations available to you. I myself initially thought MVC to be restrictive and confusing, but in fact it was the particular MVC based framework i choose that had these failings.
There are many lightweight, flexable frameworks available. Take a look at https://github.com/bcosca/fatfree as a nice example, in particular the database section. You wont think mysqli is simple in comparison
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.
This is more or less a framework-centric version of a past Stack Overflow question, which is about how most introductory material on MVC applications tends to present a tight coupling between models, views, and controllers. For example, you'll have a User table that is modified by a User controller which in turn pushes filtered data to a User view. It's my impression that a lot of MVC frameworks tend to reflect this pattern as well. This is all fine and well for what it is, but it never really leads me to anything beyond building and displaying monotonous lists of things with an HTML form.
The MVC framework that looking at right now is Lithium, which seems quite interesting as a case study of clever PHP5.3 coding techniques. On one end, Lithium has a Model class that offers wrapper objects around a individual tables, and abstracts away some simple queries. On the other end, it's got a nifty convention of routing URLs to method calls on controller objects, which then render to display templates.
But in the midst of this, I find myself at a loss as to where to place all of the interesting logic that relates data in table A to data in tables B through Z. Or at least, I'm not sure where to place such logic in a manner that's consistent with the design of the framework. To my understanding, Lithium's Model abstraction doesn't do much more than eliminate some row-level insert/update/delete boilerplate, and the controller/view architecture seems mostly about user interface. I wouldn't want to put a lot of business logic in the same Controller class that is receiving routed function calls from URL requests.
My instinct would be to fill the gap with a bunch of my own code that exists more or less entirely outside of the framework. I'm not sure if I ought to expect more than that, but given how rigidly structured everything else is in Lithium, it feels somehow unsatisfying, like I could have just rolled my own boilerplate-reduction code without the overhead of grokking the source of a big framework.
What am I missing here? Is there a recommended architecture or philosophy to using this type of framework?
One thing you have to remember with Lithium is that theres no production ready release yet (although some sites are using it in production).
The main missing feature right now is model relations. With relations in place i assume your question would be partially answered as that is an important brick in the big picture of creating more complex applications.
You could check out the x-data branch where the work on relations should be ongoing.
For the second part of writing domain logic the simple answer is "in the model".
See this (rather useless) example of extending model functionality for example.
Another example to look at is the open source mini application Analogue that is one of the few working open examples of Lithium in use. The Analogue model class shows a slightly more meaty model.
And finally its a matter of connecting the dots between M, V and C.
A Lithium controller should mainly delegate jobs over to models, and perhaps restructure the input data if needed.
The simple examples of having a Post model, PostsController and views/posts/add,index,etc doesn't mean that you have to merely have Post::all() in there.
PostsController::view need to load a set of Comment models probably.
So you will toss a lot of your own code in there, of course! Else it would not be much of an application. But keep the domain logic tied to the model where it is natural.
Need to verify that blog post has a
unique title? Write a validator.
Need to ensure the user has write access to the post? Override the save method and verify it, or filter it.
But I think we need to wait for relations to land and a 1.0 release before we can fully judge how structuring applications in Lithium can be solved best.
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.