SitePoint Sponsor

User Tag List

Page 1 of 5 12345 LastLast
Results 1 to 25 of 118

Thread: The MVC's model

  1. #1
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Location
    Sydney, Australia
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    The MVC's model

    Hi,

    After reading various topics on this forum and other blog posts on other sites, I'm curious about how a model should look in an application when using the MVC pattern.

    In particular, after reading:


    I too have found that I am guilty of using a "fat controller" within my applications when attempting to use an MVC. I have simply used a model for the purpose of accessing information in the database, whilst is incorrect.I'm pretty sure this idea was based from what I have previously read on the internet in terms of implementing a model.

    So, after reading the above thread and blog post, I'm curious of how the model should should be implemented within a application using the MVC pattern.

    Would it be possible for anyone to provide, or link me to actual code examples of how it should be implemented, even if only very brief?

    Thanks.

  2. #2
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    Well, the biggest issue is that MVC doesn't actually specify implementation details. It stats what the model is used for and not specifics on how it works. Technically any 'model' is correct (provided it is a model and not a controller :P )

    Here's a trivial example, but again, any implementation details I've included here are irrelevant in terms of MVC and are there for ease of demonstration only.


    PHP Code:
    <?php

    class UserModel extends Model {
        
        public function 
    create($registrationDetails) {
            
    //This is included as an example of the kind of logic people erroneously put in controllers
            
    if ($this->validate($registrationDetails)) {
                
    $user = new User;
                
    $user->populate($registrationDetails);
                
    $this->save($user);
            }
        }
        
        protected function 
    validate($registrationDetails) {
            if (
    $this->findByUsername($registrationDetails['username'])) {
                return 
    false;
            }
            else {
                
    //check email address, validate other form fields...
            
    }
        }
        
        protected function 
    save(User $user) {
            
    //take the user object and insert it into the DB 
        
    }
        
        protected function 
    findByUsername($name) {
            
    //... fetch a User object with username of $name or return null.
        
    }
        
        
        public function 
    find($criteria) {
            
    //query the database based on criteria. This will be called by the view, not the controller.
        
    }
        
        
    }

    ?>
    Essentially the goal is just to move the logic out of the controller. All the controller should be doing is passing the user-supplied details to the model.

    An interesting sub-topic is, should models have a state? (e.g. should they be working based around a specific User object which is stored as a property of the model) In my opinion, no, but it does make it easier in some cases.

  3. #3
    SitePoint Zealot
    Join Date
    Feb 2009
    Location
    Bristol
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A good rule of thumb with the Model is that (in a perfect world) it should be decoupled enough that you could lift it from one MVC (i.e. Zend) into another (i.e. CakePHP) with minimal fuss. The Model should only contain rules pertaining to the domain represent.

    In practice however, Models tend to be tightly coupled to framework specific components, often via data access. You can either refuse to implement those in your Model or provide them with Dependency Injection (Containers) to facilitate this kind of portability.

  4. #4
    PHP/Rails Developer Czaries's Avatar
    Join Date
    May 2004
    Location
    Central USA
    Posts
    806
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Stop naming your database access classes "Model". Just stop. It's the root problem for all the confusion going on. The "Model" is the entire domain logic layer. This represents far more than the database, and is never confined or accurately represented in a single class. Stop naming your classes Model. Now.

  5. #5
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Czaries View Post
    Stop naming your database access classes "Model". Just stop. It's the root problem for all the confusion going on. The "Model" is the entire domain logic layer. This represents far more than the database, and is never confined or accurately represented in a single class. Stop naming your classes Model. Now.
    Except MVC is nothing to do with that and has no stipulation on how the data is accessed. You can put all your (domain related) database access and data processing in one class and it's still a perfectly valid model in MVC (not that it's the best approach of course). The problem occurs when people take a step back from this and assume that model == entity* (1 record in the system). This naturally forces all the processing into the controller.

    *I was guilty of this too. It's a logical, but erroneous, assumption. Especially when you're learning about OOP and Design Patters such as Active Record and Data Mapper at the same time. I also blame the majority of articles about MVC wandering off into irrelevant implementation details, such as data access.

  6. #6
    SitePoint Zealot
    Join Date
    Feb 2009
    Location
    Bristol
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do you think that's because of Active Record's popularity (and simplicity)?

  7. #7
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    Well firstly I think it's the way objects are generally explained in OOP. Take the classic Animals or employee/manager OOP examples. You see 1 object == 1 entity. Which, in the scope of the examples is correct. When you apply it to MVC, however, it then seems alien having a "Employee model" being the part of the system which deals with all the processing related to employees rather than "An instance of an employee". Active Record makes it worse because it's easy to understand/learn and can now act like a MVC model in some scenarios.

  8. #8
    PHP/Rails Developer Czaries's Avatar
    Join Date
    May 2004
    Location
    Central USA
    Posts
    806
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TomB View Post
    Except MVC is nothing to do with that and has no stipulation on how the data is accessed. You can put all your (domain related) database access and data processing in one class and it's still a perfectly valid model in MVC (not that it's the best approach of course).
    It's true that the class is a *part* of the model layer. But even saying that it is "a valid model" is implying that the class represents a fully self-contained Model, and it does not. The Model is an architecture layer. There are many other things in a framework or application that have behaviors of components in a model layer, but aren't labeled that way. Sessions and request data, for instance.

    Data access, control, validation, persistence, and manipulation are functions of the model layer in the MVC architecture. So any time you are performing any of those functions or even using external web services or APIs, you are technically using the Model layer to do so. The controller has a sole purpose in MVC architecture: To select a view to display based on the request. It's just an intermediary. Due to the stateless nature of the web, the controller usually takes the additional responsibility of passing request data to the model for persistence, and passing models and other data into the view. This bleed-over is kind of a compromise so the architecture can stay simple, but it often comes at the price of binding your controllers and view together in such a way that the view cannot be easily re-used elsewhere. This is also the cause of confusion for many, because by doing so, too much logic ends up in controllers instead of models.

  9. #9
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    IMHO the model should be well designed to be decoupled. I would say the model should implement not only the persistence operations, but it should also define , encapsulate and implement the business logic entities. In the MVC pattern the controller is responsible for application logic and the model for business logic.

    I would say that a well designed model layer should be decoupled well enough to be able to be reused in a non MVC pattern implementation.

  10. #10
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,146
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Quote Originally Posted by Czaries
    It's just an intermediary. Due to the stateless nature of the web, the controller usually takes the additional responsibility of passing request data to the model for persistence, and passing models and other data into the view. This bleed-over is kind of a compromise so the architecture can stay simple, but it often comes at the price of binding your controllers and view together in such a way that the view cannot be easily re-used elsewhere. This is also the cause of confusion for many, because by doing so, too much logic ends up in controllers instead of models.
    exactly

    In traditional programming MVC is different from that of a web driven interpretation.
    The only code I hate more than my own is everyone else's.

  11. #11
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it is important to clarify that "Model" commonly has two meanings when discussing MVC.

    In the general application sense of MVC, the Model is all the code is the layer separate from the Presentation layer (which contains all the View and Controller code). As adiian wisely points out, the Model should have no dependencies on the Presentation layer (i.e., View and Controller).

    However, when talking about a specific PHP implementation of MVC, it is common to refer to the classes loaded for a given Request as the Model, View and Controller. There may be several classes of each type instantiated for a Request. As Czaries and TomB both mention, these Model classes can take many forms -- from directly accessing the database to being more abstract Domain Model type classes. And different kinds of these Model layer classes can be used simultaneously in an application. What they have in common is that they are not Controller code (Request processing and program flow) or View code (Response generation).

    So in the general sense MVC is about separations. However when discussing an implementation MVC is typically about classes.
    Christopher

  12. #12
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TomB View Post
    All the controller should be doing is passing the user-supplied details to the model.
    Correct so far, but what about the View? Should the Model transmit its changes directly into the View, should the View extract the changes directly from the Model, or should the Controller extract from the Model and inject into the View? Actually, there is no hard and fast rule here, so any of these options would be perfectly valid..

    Quote Originally Posted by TomB View Post
    An interesting sub-topic is, should models have a state? (e.g. should they be working based around a specific User object which is stored as a property of the model) In my opinion, no, but it does make it easier in some cases.
    Of course the Model should have state! It is changes in state which are reflected by changes to the View. If the Model is a database object then state is persisted in the database.

  13. #13
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sunwukung View Post
    A good rule of thumb with the Model is that (in a perfect world) it should be decoupled enough that you could lift it from one MVC (i.e. Zend) into another (i.e. CakePHP) with minimal fuss. The Model should only contain rules pertaining to the domain represent.
    I disagree completely. It is *NOT* necessary to develop components which are independent from the framework in which they are written. The real aim should be to write components where any Model can be used with any View, and any Model can be used with any Controller. In my framework I have linked Views and Controllers into Transaction Patterns, and I can implement any Pattern with any Model.

    Quote Originally Posted by sunwukung View Post
    In practice however, Models tend to be tightly coupled to framework specific components, often via data access. You can either refuse to implement those in your Model or provide them with Dependency Injection (Containers) to facilitate this kind of portability.
    Portability between frameworks is not a requirement, so DP containers are also not a requirement.

  14. #14
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Czaries View Post
    Stop naming your database access classes "Model". Just stop. It's the root problem for all the confusion going on. The "Model" is the entire domain logic layer. This represents far more than the database, and is never confined or accurately represented in a single class. Stop naming your classes Model. Now.
    I disagree. The Model is not the entire domain logic layer. You do not create a single Model class for the entire application, you create a separate class for each entity within the application. For a database application this equates to a separate class for each database table.

  15. #15
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TomB View Post
    The problem occurs when people take a step back from this and assume that model == entity (1 record in the system). This naturally forces all the processing into the controller.
    In my framework each Model class represents a single database table, but it certainly does not represent a single record. Each table object holds as many records as it has been given, or requested to read from the database.

  16. #16
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Czaries View Post
    Data access, control, validation, persistence, and manipulation are functions of the model layer in the MVC architecture. So any time you are performing any of those functions or even using external web services or APIs, you are technically using the Model layer to do so.
    I agree 100%. None of those functions you mention should be performed in either the View or the Controller.

    Quote Originally Posted by Czaries View Post
    The controller has a sole purpose in MVC architecture: To select a view to display based on the request. It's just an intermediary.
    You are implying that the Controller can select from a range of possible Views at rutime, but that is not necessary. In my framework I link a particular Controller to a particular View (XSL stylesheet) in what I call a Transaction Pattern, so the View is always fixed within a particular Controller. In addition, the Controller within a particular Pattern has a predefined set of operations it can use on the Model.

    Quote Originally Posted by Czaries View Post
    Due to the stateless nature of the web, the controller usually takes the additional responsibility of passing request data to the model for persistence, and passing models and other data into the view.
    My framework is a combination of MVC and the Three Tier Architecture (no, they are *NOT* the same) so each Model object in the Business layer uses a separate object in the Data Access layer to communicate with the database. This is known as the Data Access Object or DAO.

    Quote Originally Posted by Czaries View Post
    This bleed-over is kind of a compromise so the architecture can stay simple, but it often comes at the price of binding your controllers and view together in such a way that the view cannot be easily re-used elsewhere. This is also the cause of confusion for many, because by doing so, too much logic ends up in controllers instead of models.
    I do not have any table or field names hard-coded in any of my Controllers or Views, so they are all completely reusable. I have over 40 Patterns, and I can implement a working transaction simply by saying "link this Pattern with that Model class (database table)". There is no business logic in any Controller, just as there is no business logic in any View.

  17. #17
    SitePoint Enthusiast
    Join Date
    Mar 2006
    Posts
    81
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think this is where I always seem to get mixed up (even on other languages, c++), having an instance of a model for every entity then held in an array or another model, what is the correct way of implementation?

    I'm aware that is massively vague and i'm sure it depends on circumstance but as a general rule, like forum -> posts or gernre -> movies or something like that, a model / class for each , or posts are a parrt of the forums model?

    argg, i understand the point of MVC but implementation is a little hazy

  18. #18
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by adiian View Post
    IMHO the model should be well designed to be decoupled. I would say the model should implement not only the persistence operations, but it should also define, encapsulate and implement the business logic entities.
    I disagree. The Model object should contain all the business logic, but all data access should be performed in a separate Data Access Object (DAO). In this way you should be able to easily swap from one database engine to another without having to change ay code in any business object.

    Quote Originally Posted by adiian View Post
    In the MVC pattern the controller is responsible for application logic and the model for business logic.
    What do you mean by "application logic"? In my framework no Controller is aware of which application it is running in. It can be employed in any application without modification, so there is no "application logic". The Controller does what it does with whatever Model and View it has been given, and all application/business logic is contained within the Model.

    Quote Originally Posted by adiian View Post
    I would say that a well designed model layer should be decoupled well enough to be able to be reused in a non MVC pattern implementation.
    I disagree. If a class has been designed to work as the Model in an MVC pattern it is unreasonable to expect it to work as anything other than the Model in an MVC pattern. The real trick is to allow any Model to work with any Controller and any View. I have achieved this in my framework. Have you done this in yours?

  19. #19
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by oddz View Post
    In traditional programming MVC is different from that of a web driven interpretation.
    Why should the MVC pattern in a desktop application be different from the MVC pattern in a web application. Of course the implementation is different, but the pattern remains the same.

  20. #20
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint View Post
    I think it is important to clarify that "Model" commonly has two meanings when discussing MVC.

    <snip>

    So in the general sense MVC is about separations. However when discussing an implementation MVC is typically about classes.
    Your description is confusing. If you have separated your application into different classes, where each class is responsible for a different entity, then you automatically have a separation of responsibilities. It is not possible to have separate classes without separation of responsibilities.

  21. #21
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by omnibreak View Post
    I think this is where I always seem to get mixed up (even on other languages, c++), having an instance of a model for every entity then held in an array or another model, what is the correct way of implementation?
    While an "object" is an instance of a "class", and a "class" is a blueprint for an "entity", there is no rule which says that an "object" can only hold a single instance of an "entity".

    Quote Originally Posted by omnibreak View Post
    argg, i understand the point of MVC but implementation is a little hazy
    In my framework I have a separate class for each database table. Within each class I do *NOT* define a separate property for each column/field within that table, I just have a single array. This array may be either associative to represent a single record, or indexed to represent a number of records.

    All my Controllers and Views deal with this array. As they do not have to mention any columns by name, no column names have to be hard-coded in any Controller or View, which makes them reusable with any database tabe class without modification.

  22. #22
    SitePoint Enthusiast
    Join Date
    Mar 2006
    Posts
    81
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So what logic in each class separates them from another if the class itself doesn't know about what fields its holding why need a separate class for each table, "other than to be neat"

    Sorry if i missed the point :S

  23. #23
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Tony Marston View Post
    Correct so far, but what about the View? Should the Model transmit its changes directly into the View, should the View extract the changes directly from the Model, or should the Controller extract from the Model and inject into the View? Actually, there is no hard and fast rule here, so any of these options would be perfectly valid..
    Well in MVC the view gets its own data from the model. Controller extracting from model and passing to the view is wrong, as we discussed in the last topic (linked in the first post). As for broadcasting changes, it doesn't really apply to PHP since the view will be refreshed anyway.

    Of course the Model should have state! It is changes in state which are reflected by changes to the View. If the Model is a database object then state is persisted in the database.
    By state I meant a does the model contain a 'current record set'. Selecting which records to show is clearly display logic (along with ordering and limiting). Basically whether the view requests a specific result set, or whether it requests the models current state. imho there are pros and cons of both.

  24. #24
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Tony Marston View Post
    In my framework I have a separate class for each database table. Within each class I do *NOT* define a separate property for each column/field within that table, I just have a single array. This array may be either associative to represent a single record, or indexed to represent a number of records.
    Then this isn't strictly a model. What about where you have a user and user address table?

  25. #25
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,146
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Quote Originally Posted by Tony Marston
    Why should the MVC pattern in a desktop application be different from the MVC pattern in a web application. Of course the implementation is different, but the pattern remains the same.
    That depends on what your going to base the definition of pattern on. If your strictly basing the pattern on the coupling than they are similar. However, the flow is what requires the different approach. For example, in a traditional Java Environment for desktop development the flow is circular whereas the flow is linear due to the stateless nature of the web. The inventors of rails didn't approach the situation the same way as a desktop application because it would be impossible given the shift in paradigm between a circular state based flow and linear non-state based flow. The need for a modified MVC approach for linear environment is a result of shift in paradigms between traditional app and web based development as Czaries pointed out very well. I just really think people need to stop referring to the web interpretation as MVC and something else entirely to create a clear distinction between the web interpretation and traditional one.
    The only code I hate more than my own is everyone else's.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •