4

I use Zend framework and Doctrine. In many projects, business logic is built into the controller. This approach seems wrong as me.

The best setup I ever saw it is used service layers, and this is where the business logic was written. All I had to do was create a form, validate it, and use some business logic in service layer. Result validation, business logic and work with one method (for example: newProduct($postData)).

What is the right way to organize my business logic in MVC? Maybe I need to read some books, or see some examples of source code.

Anthony Rutledge
  • 6,980
  • 2
  • 39
  • 44
Dmitro
  • 1,489
  • 4
  • 22
  • 40
  • [books](http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=mvc&x=0&y=0) – ajreal Dec 24 '10 at 12:00
  • MVC Controllers and Models: http://stackoverflow.com/questions/467113/fat-models-skinny-controllers-and-the-mvc-design-pattern – Andreas Dec 24 '10 at 12:03
  • The one 'true way' of organizing MVC [isn't applicable](http://stackoverflow.com/questions/1549857/simple-php-mvc-framework) to web frameworks. So, don't try. See also [MVP](http://en.wikipedia.org/wiki/Model_View_Presenter) which has superseded ["MVC"](http://programmers.stackexchange.com/questions/2806/is-mvc-just-the-seo-of-php-programming). – mario Dec 24 '10 at 12:08
  • @mario: The pattern can be maintained fairly well with a request/response pattern sitting on top of it (providing the web presence and obscuring the more MVC-friendly domain logic beneath). But the developer needs to be acutely aware of the separation between the two. And I agree that MVC web frameworks by themselves try to hide this and make themselves something of a misnomer. It's a point I feel obligated to bring up any time a potential employer asks if I "know MVC" and I know they're talking about the ASP .NET MVC Framework :) – David Dec 24 '10 at 12:13

3 Answers3

11

I can't speak for the Zend framework (or for anything you're working on that was built using it), but in the MVC pattern in general the business logic belongs in the Models.

You may have heard the statement before that you should "keep your controllers light and your models heavy" (or some variation thereof). The idea is that the Models are your domain (your ubiquitous language) and all business logic should be encoded in them and in their interactions. The controllers are just event handlers in MVC to receive requests and translate those requests over to the Models.

Edit: (In response to your comment) - I'm afraid we're having something of a language barrier here. But, to add to the point and hopefully help you with regards to building the model yourself and data being primary, consider a quote by Eric Raymond: "Smart data structures and dumb code works a lot better than the other way around."

The idea is that the "logic" is in your data structures, whereby you build a "rich" domain model, complete with logic and functionality. This is as opposed to an "anemic" domain model, which is just flat data structures (or DTOs) that do nothing more than represent a state of data and have no functionality.

With smart data structures, the code that uses them (which will be in your controllers, as well as various other places) doesn't need to be sophisticated or complicated. It just needs to tell the Models what's going on and direct them to do what they need to do. The Models have all the know-how to actually do it.

This is preferred over "smart code and dumb data structures" where the Models are anemic DTOs (which have their use, don't get me wrong) and all of the logic is in a more procedural format where each procedure needs to have all of the know-how to perform the business task at hand. This leads to, among other things, lots of code duplication.

I hope this helps. As I said, I'm having a hard time understanding the full scope of your question.

Edit: Another thing to consider, since I'm not sure where you were going with the "data is primary" concern. There is a difference between "data structures" and "data persistence" and that difference is absolutely critical here. Your data structures are your Models, enriched with business logic. Your data persistence is the data in the database.

Very often (all too often, if you ask me), these notions are confused in programming. In most auto-generated code and helpful frameworks and all that stuff, "Models" have a tendency to be direct mappings to database tables and simply represent a record in those tables. This isn't always wrong, but it is misleading.

The business logic isn't in the database. It isn't in the flat representation of the data. Sure, the database can contain its own persistence logic (such as referential integrity, triggers, auditing that isn't known to the business logic code, etc.) but it doesn't contain the business processes that you would normally see in a flowchart of the business logic.

These concepts may be breaking out of the mold for any given framework's standard operating procedure. As I said, I can't really speak for the framework. But personally I tend to advocate "good code" over "popular use of a given tool."

David
  • 208,112
  • 36
  • 198
  • 279
  • yes, i more interested what true way of organization heavy model? ZF makes us build model yourself. Doctrine help us in this via pattern Data Mapper + own ServiceLayer, it seems nice. But in this approach data are primary and business logic depends on data and we have problem with extension system. – Dmitro Dec 24 '10 at 12:18
  • 1
    I upvoted this earlier and just read this question randomly - want to upvote again! Great answer :-) – richsage Dec 24 '10 at 14:35
  • 1
    @richsage: Thanks. I kind of feel like I was gaining some momentum with this one. Perhaps I should continue to revise it and turn it into a blog post. – David Dec 24 '10 at 14:39
  • 1
    @David - please do, it would be good. I've started migrating from Doctrine 1 to Doctrine 2, and the data structure/persistence is now separate as per your answer. Slightly confusing coming from the Doctrine 1 "model-is-a-db-record" philosophy! – richsage Dec 24 '10 at 14:41
  • @richsage: Keep in mind that true persistence ignorance in the domain design is dangerous, because you could logically paint yourself into a corner and lose a lot of performance. When designing a project, I find the best approach is to design the business domain first of course, but to occasionally step back and think about persistence and other dependencies to look for any compromises that need to be made. – David Dec 24 '10 at 14:45
  • @David thanks for great answer, it will be great post in your blog, but also interesting topic as the continuation of this topic is building mvc modular application with inheritance of modules – Dmitro Dec 24 '10 at 16:14
  • One of the great tragedies of the ActiveRecord approach is how easily it can lead to confusion between business objects and their persistence. For that reason, I'm a big fan of the DataMapper pattern. In particular, Doctrine2 does - IMO - a good job of allowing business objects to represent real life business entities and leaving the persistence largely in the hands of the EntityManager (despite the common practice of using entity docblock annotations to define the mappings necessary for persistence). – David Weinraub Dec 18 '12 at 16:04
6

I'll provide some of my opinions about the MVC pattern coding. For the lazy programmers it's really easy to mess up the codes between the controllers and models.

Below were my folder structure:

  1. Controllers : should be light and clean, the only thing here is to determine which models or views should be loaded to response the request.
  2. Views: Even thought it can access the models directly, but I prefer to do it through controllers. And keep the html clean.
  3. Models: done all the things but divide into folders.
    • Classes/Objects : contains all objects based on database schema.
    • Repository/Factory : includes query, insert, update and delete method. Only map one file to one table.
    • Services : Business logic, login, logout, or everything which's not related to the database or even join the table together and return the results.
    • Utils : Static method for Views based on Repository/Factory.

Hope this help! and welcome any suggestions.

Tee Wu
  • 569
  • 2
  • 9
-1

I will say the Business layer is part of the Controller since its consists of all the components that enable the user to interact with both the View and the Model alike. From the retrieval, processing, transformation and even management of application data and business rules.