SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 36
  1. #1
    SitePoint Enthusiast jaked409's Avatar
    Join Date
    Jan 2007
    Posts
    61
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    MVC - When to use a Model and when to use something else?

    Hey, this is my first foray into developing an application with an MVC framework, and I知 a little bit confused about when to use a Model. Specifically, I have an object, and I'd like to create multiple instances of it at once (I'll be putting them in an array, but that doesn't really matter). I値l skip the attempt to abstract my question, and give the specific example.

    I知 making a little web application for my friend痴 fantasy baseball league. In the first part I知 working on, I知 simulating a draft lottery, where 鍍ickets (each of which will be represented as a Ticket object) are put into a lottery and picked at random.

    Before I started reading up, I assumed I would have a Ticket class, which would be a Model. However, once I started reading, it started to seem like that was the wrong way to do it; I知 going to have multiple separate instances of the Ticket class all at once (all contained in one array, and then picked randomly), and I think that痴 the wrong use of a Model. What should the Ticket class be?

  2. #2
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The Model is not a single class – it's the Model layer. Ticket, it seems, would belong in the Model layer. There's nothing wrong with creating multiple instances of an object in the Model layer. Notice how I'm saying Model layer all the time? I hope you'll remember the layer part.

  3. #3
    SitePoint Enthusiast jaked409's Avatar
    Join Date
    Jan 2007
    Posts
    61
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I understand that Ticket would belong in the Model layer. However, Ticket should not be a Model itself (meaning I'm not going to go "class Ticket extends Model"), right?

  4. #4
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    664
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    You should have a Ticket class (or perhaps a TicketItem class) as well as a TicketModel class. Depending on your implementation you might then create your tickets using the model class.

    PHP Code:
    $ticketModel = new TicketModel();
    $ticket $ticketModel->newItem(); 
    Ticket should most certainly not extend Model. two different concepts.

  5. #5
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jaked409 View Post
    I understand that Ticket would belong in the Model layer. However, Ticket should not be a Model itself (meaning I'm not going to go "class Ticket extends Model"), right?
    That depends entirely on what you've defined Model as. It could well be. MVC doesn't tell you there needs to be a class called Model or what that class should exactly do.

  6. #6
    SitePoint Enthusiast jaked409's Avatar
    Join Date
    Jan 2007
    Posts
    61
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    You should have a Ticket class (or perhaps a TicketItem class) as well as a TicketModel class. Depending on your implementation you might then create your tickets using the model class.

    PHP Code:
    $ticketModel = new TicketModel();
    $ticket $ticketModel->newItem(); 
    Ticket should most certainly not extend Model. two different concepts.
    Got it. So like for example, I'm using Code Igniter. Ticket should be defined in the Library, in that case?

  7. #7
    SitePoint Addict
    Join Date
    Nov 2005
    Location
    Germany
    Posts
    235
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    jaked409, the model is everything your application is modeling from the real world. E.g. baseball doesn't know about databases, and HTTP requests, it knows about players and tickets and games. These elements form a model of the real world.
    Last edited by FrlB; Mar 19, 2007 at 11:48. Reason: I misread a post and had to remove my BS

  8. #8
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would say you need a Ticket Item and either a Ticket Queue or a Ticket Collection to represent what you want to do; The Ticket Item would have knowledge of what a ticket is and nothing more, and the Ticket Queue or Ticket Collection would have the knowledge to manage those tickets, ie Generating the randomness for example.

  9. #9
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > Ticket should be defined in the Library, in that case?

    The framework library... No, this is part of your application so should be separate from the framework; If the particulars weren't (too) dependent on the framework in question, then at a later date, in theory you could swap out frameworks for something else.

    You couldn't do that if you put the class(es) in as part of the library (of the framework) that is

  10. #10
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    664
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by FrlB View Post
    I'm a little confused. Why should one have a TicketModel? What does it do except creating new instances? Why not just:
    PHP Code:
    $ticket = new Ticket(); 
    Do you really want your ticket object to have to know the details of your underlying database system?

    Suppose you want a list of tickets for a given date at a given location. Where do you put this query and where do you put the code that converts the results into ticket objects? Some systems do put this stuff in the ticket object but I think it's cleaner to use a model object.

    And what about persistence? Being able to do $ticket->save() implies again that the ticket object knows the details about the underlying storage system. Doing $ticketModel->save($ticket); moves this information to the model class allowing your ticket object to focus on being a ticket and not a database.

  11. #11
    SitePoint Enthusiast jaked409's Avatar
    Join Date
    Jan 2007
    Posts
    61
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    > Ticket should be defined in the Library, in that case?

    The framework library... No, this is part of your application so should be separate from the framework; If the particulars weren't (too) dependent on the framework in question, then at a later date, in theory you could swap out frameworks for something else.

    You couldn't do that if you put the class(es) in as part of the library (of the framework) that is
    Got it That's what I was thinking. However, now I'm lost. It shouldn't be a model (although it will be used by a model), and it shouldn't be a library. What should it be?

  12. #12
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > What should it be?

    Well, the Ticket Item to me looks like it's an Inmutable class; That is, instead of returning the object once a change has been made, you return a new instance of that class with the change made, for you? Ie

    PHP Code:
    class Item {
            private 
    $num;
            
            public function 
    __construct$num ) {
                
    $this -> num $num;
            }
            
            public function 
    add$amount ) {
                return new 
    Item$this -> num $amount );
            }
            
    // ...
        

    But anyways, the class hierarchy still remains with your application, so I would put it under the Models directory, such as...

    Code:
    + Models
    + --- ---
    + Tickets
    + --- Item
    + --- --- Interface
    + --- Queue
    + --- --- Interface
    Etc., so any other class(es) that fall under your Ticket Model would belong in the ./Tickets directory? You may find that you need utility class(es) to help manipulate that Queue for example...

  13. #13
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > Do you really want your ticket object to have to know the details of your underlying
    > database system?

    You may want to take a look at Embedded Value [Fowler] though? That's what springs to my mind anyways...

    http://www.martinfowler.com/eaaCatal...ddedValue.html

  14. #14
    SitePoint Addict
    Join Date
    Nov 2005
    Location
    Germany
    Posts
    235
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    Do you really want your ticket object to have to know the details of your underlying database system?

    And what about persistence? Being able to do $ticket->save() implies again that the ticket object knows the details about the underlying storage system. Doing $ticketModel->save($ticket); moves this information to the model class allowing your ticket object to focus on being a ticket and not a database.
    I misread your post, please excuse the confusion. One problem persists though: Using the outlined approach requires the outer code not just to know about the model class Ticket, but also about TicketModel. I would very much prefer to hide all this complexity from the outside (views and controllers, the usual suspects), but I'm not quite sure how to avoid this kind of coupling.

    Quote Originally Posted by ahundiak View Post
    Suppose you want a list of tickets for a given date at a given location. Where do you put this query and where do you put the code that converts the results into ticket objects? Some systems do put this stuff in the ticket object but I think it's cleaner to use a model object.
    I do the former and had no problems with that, if it gets too crowded I'd use a separate Finder class.

  15. #15
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    664
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by FrlB View Post
    I misread your post, please excuse the confusion. One problem persists though: Using the outlined approach requires the outer code not just to know about the model class Ticket, but also about TicketModel. I would very much prefer to hide all this complexity from the outside (views and controllers, the usual suspects), but I'm not quite sure how to avoid this kind of coupling.
    I use a model locator to try and reduce the coupling. It's reasonable for controllers and views to know a bit about the model.
    PHP Code:
    $ticketModel $this->context->models->Ticket;
    $ticket $ticketModel->find($ticketId); 
    In this case, my app does not need to know anything about specific class names. Just needs to know the name of the ticket model and needs to know that the ticket model will return ticket objects. In theory at least, there could even be several different types of ticket objects based on the context of the model.

  16. #16
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    PHP Code:
    $ticketModel $this->context->models->Ticket;
    $ticket $ticketModel->find($ticketId); 
    Since $ticketModel appears to be a collection of tickets, why not name it something like ticket-collection, ticket-gateway or even just tickets? Ticket-model isn't a very descriptive name.

    Also, I assume that $this->context is a locator/registry of sorts. Why would you have it further segregated into ->models before picking you object? Wouldn't this be as good (And a bit more fluent to read):
    PHP Code:
    $ticket $this->context->tickets->find($ticketId); 
    I'm not mentioning this just to nitpick on your programming style, but reading the code gives me a feeling that you are a bit too keen to get the word "model" in there with the API. As Ezku already mentioned, "the model" of MVC is a layer; A collection of different objects, which forms a model of the domain of the application.
    Taking the code-snippet from above, I would say that both the gateway ($ticketModel) and the record ($ticket) clearly belong to the model layer. Thus naming one of them "model" is confusing, since it implies that the other component doesn't belong to the model layer (Which is of course wrong).

    It's common to partition the model layer further into a data access layer, and a domain model, which are separated from each other (to a lesser or greater degree). I think that perhaps, what you're naming "model", is the part of your model layer which has to do with data access.

    Quote Originally Posted by ahundiak View Post
    I use a model locator to try and reduce the coupling. It's reasonable for controllers and views to know a bit about the model.
    Certainly. It's a good point to make, since people some times try to make the view ignorant of the model. That's simply not possible, and as a result can lead to view code which uses reflection or other implicit interfaces to talk with the model layer, rather than an explicit interface.

  17. #17
    SitePoint Zealot
    Join Date
    Sep 2005
    Posts
    122
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think the TicketModel in ahundiak's example is analogous to a Repository not a collection. Either way, I agree that the "model" in the name is silly and it seems like it's there to satisfy an acronym.

    Lastcraft said it best with something similar to "the model is everything else besides the controller and view". It doesn't need to be named.

    (What a redundant post )

  18. #18
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    664
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    It's entirely possible that I'm misusing the term 'Model'.

    TicketModel is not a collection of tickets. In fact, if I did need a custom class to hold multiple tickets then I would have a TicketItems class. Most of the time an array is all I need.

    TicketModel is basically a collection of methods that exposes Ticket information to the application. Methods typically include:
    find($id)
    save($item)
    delete($ids)
    newItem()
    search($searchCriteria) // This would return a collection or array of items
    pickList($searchCriteria) // Returns indexed array for building option lists

    The ticket model itself does not have to have a database tied directly to it. I have a number of models that either have all their data in the class itself or that load themselves from files of one sort or another.

    Likewise, the model does not have to be tied to a specific table. I have for example an UserModel in which the user data is actually spread across 5 or 6 tables.

    So I'm not really sure what a better term for it would be. Maybe Gateway.

  19. #19
    Put your best practices away. The New Guy's Avatar
    Join Date
    Sep 2002
    Location
    Canada
    Posts
    2,087
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Looks like a model to me. Just because it's not attached to a database table doesn't mean its not a proper model.
    "A nerd who gets contacts
    and a trendy hair cut is still a nerd"

    - Stephen Colbert on Apple Users

  20. #20
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    219
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    Maybe Gateway.
    Absolutely, I think one of the big benefits of design patterns is giving a common language for developers to talk about a class and what it does - as you've seen in this post, using generic terminology (model) confuses matters when you discuss your classes with others.

    However if you use 'Gateway' I think that you probably have your responsibilities a little clouded then, as my belief is that when using Gateways, you should seperate the responsibilities down to operations on a collection of items (TableDataGateway) or an individual item (RowDataGateway) and I would therefore seperate the find, save, search, delete methods accordingly.

    Dan.

  21. #21
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    664
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by danh2000 View Post
    Absolutely, I think one of the big benefits of design patterns is giving a common language for developers to talk about a class and what it does - as you've seen in this post, using generic terminology (model) confuses matters when you discuss your classes with others.

    However if you use 'Gateway' I think that you probably have your responsibilities a little clouded then, as my belief is that when using Gateways, you should seperate the responsibilities down to operations on a collection of items (TableDataGateway) or an individual item (RowDataGateway) and I would therefore seperate the find, save, search, delete methods accordingly.

    Dan.
    But I don't have Rows as such. Certainly not ActiveRows with built in query capability and joining capabilities. I have business objects and I really don't want them to know how to persist themselves or even where they came from. I do have TableGateway classes which the models use to access the database but I certainly don't want the application to know about tables. My Table objects work strictly with arrays.

    I guess I look at this way:
    MVC = Model/View/Controller pattern.

    No one seems to object to having view and controller classes. I wonder why having Model classes seems so strange?

  22. #22
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    No one seems to object to having view and controller classes. I wonder why having Model classes seems so strange?
    I don't think anyone is opposed to it per se. Rather, there's a lot of disagreement about what a Model should consitute (and how it should be constituted). Since there's a tacit agreement that the names of classes should be indicative of their function, it probably more a matter of what a "Model" object should be and what it should do.
    Zealotry is contingent upon 100 posts and addiction 200?

  23. #23
    SitePoint Addict
    Join Date
    Nov 2005
    Location
    Germany
    Posts
    235
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I wonder why having Model classes seems so strange?
    Kyberfabrikkens point here was that if you affix "Model" to a classname you should do it with all classes belonging to The Model.
    Quote Originally Posted by kyberfabrikken
    Thus naming one of them "model" is confusing, since it implies that the other component doesn't belong to the model layer (Which is of course wrong).
    Naming is so very important yet so hard to get right.

    Anyway, I like your solution to decouple data access from domain objects, I just wonder if you could elaborate a little about this hierarchy:
    PHP Code:
    $this->context-> 
    I gather $this is a controller, but what kind of thing is the context here?
    Thanks!

  24. #24
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    No one seems to object to having view and controller classes. I wonder why having Model classes seems so strange?
    Good question.

    Mostly because the model is a much larger part of your application than controller and view. For applications with complex interfaces, having a "view" class can become equally confusing, since the view may be segregated into templates, template engine, helpers, widgets and whatnot. All of which belong to the view.

    Controllers on the other hand tend to involve relatively few actors, and so the name is less confusing here.

    Quote Originally Posted by ahundiak View Post
    Maybe Gateway.
    I would use gateway for such a component. Although ...

    Quote Originally Posted by danh2000 View Post
    However if you use 'Gateway' I think that you probably have your responsibilities a little clouded then, as my belief is that when using Gateways, you should separate the responsibilities down to operations on a collection of items (TableDataGateway) or an individual item (RowDataGateway) and
    You're right that gateway is a bit ambiguous. Especially if we use Fowler's terminology. In code, I normally use gateway in the naming of my tabledatagateway, and I won't name the rowdatagateway anything which includes the word gateway. If you use a different data access strategy (such as activerecord or datamapper), you will probably attach different meanings to the word gateway.

  25. #25
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    664
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    So I guess the survey says "Gateway". Still have not quite convinced myself but I'll go with the flow.


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
  •