views:

989

answers:

5

Forgive the vague title, I wasn't sure how to describe it.

If you have a generic model "Archive", how do you show different views/forms based on a user selected 'type'?

For example, the user creates a new "Archive", then gets the choice of video, book, audio etc. From there they get different forms based on the archive type.

Or would it be better to split them into different models - Video, Book, Audio?

Or can models inherit (like Video extends Archive). I guess this is basic OOP / classes, but have no idea how to apply that here.

Examples from any MVC framework are welcome!

+1  A: 

Your models Video, Book and Audio can inherit from Archive.

And each model will have a controller.

http://yourserver/Books/Edit/11

You will have to get your user to pick the type of archive they want before you create the corresponding model.

EDIT (in response to comment)

In ASP.NET MVC your model will be a class.

public class Video : Archive
{  
    public int Id {get;set}
    public string Name {get;set;}     
    ...
}

You will also have a controller

public class VideoController : Controller
{
    public object Edit(int id)
    {
        Video myVideo = GetVideo(id);
        return View("Edit", myVideo);
    }
     ...
}

And you will have a view in the Views directory for example, the page which contains

public class Edit : View<Video>
{
    ...
}

So you can call this if you had a URL which was

http://localhost/Video/Edit/11

This was all done from memory, so there may be some mistakes, but the take-home message is that you specify the inheritance at the model. The model is just a class. In your case you want to inherit from Archive. Once you've done that the model is pass around as normal.

IainMH
Thanks. Could you give an example of how to specify the model inheritance?
meleyal
A: 

Seems to me that one solid point in favor of MVC is that you may not need to customize the model (or the controller - of which you want only one) if all the user needs is a different view. Multiple models would appear only if the storage (persistence) architecture dictated a need for it. Some feature like data access objects (DAO) would potentially appear as another tier, between the controller and the model,should you require multiple models.

Take a look at the Apache Struts project for examples. As stated in Struts for Newbies, "To use Struts well, it's important to have a good grasp of the fundamentals. Start by reviewing the Key Technologies primer, and studying any unfamiliar topics."

For another resource, see Web-Tier Application Framework Design (Sun J2EE Blueprints)

Mark Jaeger
+2  A: 

To actually show a different view should be easy in any MVC framework. For example, in Microsoft ASP.NET MVC you would not just return a view from a controller like the following:

return View();

but would actually state the name of the view as a parameter:

return View("VideoArchive");

which would then show the view from Views/Archive/VideoArchive.aspx

Mladen Mihajlovic
+2  A: 

Seems like you would not want to have the type inherit from Archive. "Always favor encapsulation/containment over inheritance".

Why not create a class called Archive and give it a type property. The type can use inheritance to specialize for Audio, Video, etc.

It would seem that you would specialize Archive based on some other criteria. "FileSystemArchivce", "XMLArchive", "SQLArchive" and the type would not change. But the agilist in me says that this may not be necesscary at first, and you can always refactor the design later...

In terms of a controller, you probably get the biggest bang for the buck by encapsulating the differences of presentation for each type in the view. So only the view changes based on the type. Likely the semantics and rules for each one are the same and you would not need to have seperate controllers for each type. The views will be different for each type as it will have different attributes.

DanielHonig
A: 

The Single Responsibility Principle (PDF) states that:

THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.

Your Archive class violates this principle by handling multiple different types of archives. For example, if you need to update the video archive, you are also modifying the class that handles book and audio archives.

The appropriate way to handle this is to create separate classes for each different type of archive. These types should implement a common interface (or inherit a common base class) so that they can be treated interchangeably (polymorphically) by code that only cares about Archives, not specific archive types.

Once you have that class hierarchy in place, you just need a single controller and view for each model class.

For bonus points, the Single Responsibility Principle can even justify using a factory method or abstract factory for creating your model, view and controller objects (rather than new-ing them up inline). After all, creating an object and using that object are different responsibilities, which might need to be changed for different reasons.

Alan Ridlehoover