Blue Theme Orange Theme Green Theme Red Theme
 
Ads by Lake Quincy Media
Home | Forums | Videos | Photos | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Login Close
User Id:
Password:
 
Forgot Password
Forgot Username
Why Register
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
 Resources  
Close
 Our Network  
Close
Search :       Advanced Search »
Home » C# Language » Introduction to Model View Control (MVC) Pattern using C#

Introduction to Model View Control (MVC) Pattern using C#

The benefits of using the Model-View-Control (MVC) pattern in our development projects is that we can completely decouple our business and presentation application layers. Furthermore, we will have a completely independent object to control the presentation layer.

Author Rank:
Total page views :  133222
Total downloads :  4265
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
ModelViewControllerArticle.zip
 
Become a Sponsor

Benefits

The benefits of using the Model-View-Control (MVC) pattern in our development projects is that we can completely decouple our business and presentation application layers. Furthermore, we will have a completely independent object to control the presentation layer. The independence between the objects/layers in our project that the MVC provides will make maintenance somewhat easier and code reuse very easy (as you'll see below).

As a general practice we know we want to keep the object dependencies in our projects to a minimum so changes are easy and we can reuse the code we've worked so hard on. To accomplish this we will follow a general principle of "programming to the interface, not the class" using the MVC pattern.

Our mission, if we choose to accept it...

We have been commissioned to build a ACME 2000 Sports Car business object and our task is to create a simple windows interface to (1) display the vehicle's current direction and speed, and (2) enable the end user to change direction, accelerate, and decelerate.  And of course, there will be scope creep. 

There are already rumors at ACME that if our project is successful, we will eventually a need to develop a similar interface for the ACME 2 Pickup Truck and the ACME 1 Tricycle. As developers, we also know that the ACME management team will eventually say "Hey, this is really cool. Can we see it on the company's intranet?" All of this in mind, we want to deliver a product that will be easily scalable so we can be sure to have food on our plates for some time.

So, coincidentally, we think... "This is a perfect situation to use the MVC!!".

Our Architecture Overview

Ok, now we know that we want to use the MVC, we need to figure out what the heck it is. Through our research we come up with the three parts of the MVC: The Model, Control, and View. In our system, the Model would be our car, the View would be the user interface, and the Control is what ties the two together.


 
To make any changes to the Model (our ACME 2000 sports car), we'll be using our Control. Our Control will make the request to the Model (our ACME 2000 sports car), and update our View, which is our user interface (UI).

This seems simple enough, but here's the first problem we have to solve: What happens when the end user wants to make a change to our ACME 2000 sports car, such as going faster or turning? They are going to have to do it by requesting a change using the Control, through the View (our windows form).


 
Now we are left with one last problem to solve. What if the View doesn't have the necessary information to display the current state of the Model?  We're going to have to add one more arrow to our diagram: The View will be able to request the Model's state in order to get what it needs to display the information about the state of the Model.

 

Finally, our end user (our driver) will be interacting with our entire ACME Vehicle Control system through the View.  If they want to request a change to the system, such as adding a bit of acceleration, the request will be initiated from the View and handled by the Control

The Control will then ask the Model to change and make any necessary changes to the View. For example if the ACME 2000 Sports Car has a "floor it" request from an unruly driver and is now traveling to fast to make a turn, the Control will know to disable the ability to turn in the View, thus preventing a catastrophic pileup in the middle of rush-hour (whew!).

The Model (the ACME 2000 Sports Car) will notify the View that it's speed has increased and the View will update where appropriate.

So after all that, here's the overview of what we will be building:


 
Getting Started: Parts... Parts... Parts...

Being developers who always think ahead, we want to be sure our system will have a long and prosperous life. This means being prepared for as many changes at ACME as possible. In order to do this we know to follow two golden rules... "keep your classes loosely coupled" and, in order to accomplish this... "program to the interface".

So we will make three interfaces (as you may have guessed, one for the Model, one for the View, and one for the Control).

After much research and laborious interviews with the folks at ACME, we find out more about the system specifications. We want to be sure that we can set the maximum speeds for traveling forward, backwards ,and turning. We also need to be able to speed up, slow down, and turn left and right. Our "dashboard" view must display the current speed and direction.

It's a tall order to implement all of these requirements, but we're sure we can handle it...

First, let's take care of some preliminary items.  We'll need something to represent the direction and turn requests.  We'll create two enumerables, AbsoluteDirection and RelativeDirection.

public enum AbsoluteDirection
{
North=0, East, South, West
}

public enum RelativeDirection
{
Right, Left, Back
}

Next, let's tackle the Control interface. We know the Control has to pass requests to the Model, specifically: Accelerate, Decelerate, and Turn. We'll create an IVehicleControl interface with the appropriate methods.

public interface IVehicleControl
{
void Accelerate(int paramAmount);
void Decelerate(int paramAmount);
void Turn(RelativeDirection paramDirection);
}

Now we'll put together the Model interface.  We need to know the Vehicle's name, speed, maximum speed, maximum reverse speed, maximum turn speed and direction. We also need the methods to accelerate, decelerate, and turn.

public interface IVehicleModel
{
string Name{ get; set;}
int Speed{ get; set;}
int MaxSpeed{ get;}
int MaxTurnSpeed{ get;}
int MaxReverseSpeed { get;}
AbsoluteDirection Direction{
get; set;}
void Turn(RelativeDirection paramDirection);
void Accelerate(int paramAmount);
void Decelerate(int paramAmount);
}

And Finally, we'll put together the View interface. We know the view should expose some functionality to the Control, such as enabling and disabling acceleration, deceleration, and turn requests.

public class IVehicleView
{
void DisableAcceleration();
void EnableAcceleration();
void DisableDeceleration();
void EnableDeceleration();
void DisableTurning();
void EnableTurning();
}

Now we have to make a few tweaks to our interfaces to allow them to interact. First of all, any Control should be aware of it's View and Model, so we'll add "SetModel" and "SetView" methods to our IvehicleControl interface:

public interface IVehicleControl
{
void RequestAccelerate(int paramAmount);
void RequestDecelerate(int paramAmount);
void RequestTurn(RelativeDirection paramDirection);
void SetModel(IVehicleModel paramAuto);
void SetView(IVehicleView paramView);
}

The next part is a bit tricky. We want the View to be aware of changes in the Model. To do this we'll use a GOF design pattern "Observer".

To implement the Observer pattern, we need to add the following methods to the Model (which will be "observed" by the View): AddObserver, RemoveObserver, and NotifyObservers.

public interface IVehicleModel
{
string Name{ get; set;}
int Speed{ get; set;}
int MaxSpeed{ get;}
int MaxTurnSpeed{ get;}
int MaxReverseSpeed { get;}
AbsoluteDirection Direction{
get; set;}
void Turn(RelativeDirection paramDirection);
void Accelerate(int paramAmount);
void Decelerate(int paramAmount);
void AddObserver(IVehicleView paramView);
void RemoveObserver(IVehicleView paramView);
void NotifyObservers();
}

...and add the following method to the View (which will be "observing" the Model). What will happen is the Model will have a reference to the View. When the Model changes, it will call the NotifyObservers() method and pass a reference to itself and notify the View of a change by calling the Update() method of the View. (It will become clear as mud when we wire everything up later).

public class IVehicleView
{
void DisableAcceleration();
void EnableAcceleration();
void DisableDeceleration();
void EnableDeceleration();
void DisableTurning();
void EnableTurning();
void Update(IVehicleModel paramModel);
}

So now we have our interfaces put together. We are only going to use references to these interfaces in the rest of our code to ensure we have loose coupling (which we know is a good thing). Any user interface that shows the state of a Vehicle will implement IVehicleView, all of our ACME automobiles will implement IVehicleModel, and we'll make controls for our ACME automobiles with ACME vehicle controls which will implement IVehicleControl.

Next... What things will have things in common?

We know all our vehicles should act the same, so we're going to create a common code base "skeleton" to handle their operation. This is going to be an abstract class because we don't want anyone driving around a skeleton (you can't make an instance of an abstract class). We'll call it Automobile. We'll use an ArrayList (from System.Collections) to keep track of all the interested Views (remember the Observer pattern?). We could have used a plain old array of IVehicleView references, but we're all getting fatigued at this point and want to get through this article. If you're interested, check out the implementation of the AddObserver, RemoveObserver, and NotifyObservers methods to get an idea of how the Observer pattern works by helping our IVehicleModel interact with the IVehicleView. Every time there is a change in speed or direction, the Automobile notifies all IVehicleViews

public abstract class Automobile: IVehicleModel
{
#region "Declarations "
private ArrayList aList = new ArrayList();
private int mintSpeed = 0;
private int mintMaxSpeed = 0;
private int mintMaxTurnSpeed = 0;
private int mintMaxReverseSpeed = 0;
private AbsoluteDirection mDirection = AbsoluteDirection.North;
private string mstrName = "";
#endregion
#region
"Constructor"
public Automobile(int paramMaxSpeed, int paramMaxTurnSpeed, int paramMaxReverseSpeed, string paramName)
{
this.mintMaxSpeed = paramMaxSpeed;
this.mintMaxTurnSpeed = paramMaxTurnSpeed;
this.mintMaxReverseSpeed = paramMaxReverseSpeed;
this.mstrName = paramName;
}
#endregion
#region
"IVehicleModel Members"
public void AddObserver(IVehicleView paramView)
{
aList.Add(paramView);
}
public void RemoveObserver(IVehicleView paramView)
{
aList.Remove(paramView);
}
public void NotifyObservers()
{
foreach(IVehicleView view in aList)
{
view.Update(
this);
}
}
public string Name
{
get
{
return this.mstrName;
}
set
{
this.mstrName = value;
}
}
public int Speed
{
get
{
return this.mintSpeed;
}
}
public int MaxSpeed
{
get
{
return this.mintMaxSpeed;
}
}
public int MaxTurnSpeed
{
get
{
return this.mintMaxTurnSpeed;
}
}
public int MaxReverseSpeed
{
get
{
return this.mintMaxReverseSpeed;
}
}
public AbsoluteDirection Direction
{
get
{
return this.mDirection;
}
}
public void Turn(RelativeDirection paramDirection)
{
AbsoluteDirection newDirection;
switch(paramDirection)
{
case RelativeDirection.Right:
newDirection = (AbsoluteDirection)((
int)(this.mDirection + 1) %4);
break;
case RelativeDirection.Left:
newDirection = (AbsoluteDirection)((
int)(this.mDirection + 3) %4);
break;
case RelativeDirection.Back:
newDirection = (AbsoluteDirection)((
int)(this.mDirection + 2) %4);
break;
default:
newDirection = AbsoluteDirection.North;
break;
}
this.mDirection = newDirection;
this.NotifyObservers();
}
public void Accelerate(int paramAmount)
{
this.mintSpeed += paramAmount;
if(mintSpeed >= this.mintMaxSpeed) mintSpeed = mintMaxSpeed;
this.NotifyObservers();
}
public void Decelerate(int paramAmount)
{
this.mintSpeed -= paramAmount;
if(mintSpeed <= this.mintMaxReverseSpeed) mintSpeed = mintMaxReverseSpeed;
this.NotifyObservers();
}
#endregion
}

Last but not least...

Now that our "ACME Framework" is in place, we just have to set up our concrete classes and our interface. Let's take care of the last two class first which will be our Control and our Model...

Here's our concrete AutomobileControl which implements the IVehicleControl interface. Our AutomobileControl will also set the View depending on the state of the Model (check out the SetView method which is called every time there is a request passed to the Model).

Notice, we just have references to the IVehicleModel (not the Automobile abstract class) to keep things loose and IVehicleView (not a specific View).

public class AutomobileControl: IVehicleControl
{
private IVehicleModel Model;
private IVehicleView View;
public AutomobileControl(IVehicleModel paramModel, IVehicleView paramView)
{
this.Model = paramModel;
this.View = paramView;
}
public AutomobileControl()
{
}
#region IVehicleControl Members
public void SetModel(IVehicleModel paramModel)
{
this.Model = paramModel;
}
public void SetView(IVehicleView paramView)
{
this.View = paramView;
}
public void RequestAccelerate(int paramAmount)
{
if(Model != null)
{
Model.Accelerate(paramAmount);
if(View != null) SetView();
}
}
public void RequestDecelerate(int paramAmount)
{
if(Model != null)
{
Model.Decelerate(paramAmount);
if(View != null) SetView();
}
}
public void RequestTurn(RelativeDirection paramDirection)
{
if(Model != null)
{
Model.Turn(paramDirection);
if(View != null) SetView();
}
}
#endregion
public void SetView()
{
if(Model.Speed >= Model.MaxSpeed)
{
View.DisableAcceleration();
View.EnableDeceleration();
}
else if(Model.Speed <= Model.MaxReverseSpeed)
{
View.DisableDeceleration();
View.EnableAcceleration();
}
else
{
View.EnableAcceleration();
View.EnableDeceleration();
}
if(Model.Speed >= Model.MaxTurnSpeed)
{
View.DisableTurning();
}
else
{
View.EnableTurning();
}
}
}

Here's our ACME200SportsCar class (which extends the Automobile abstract class which implements the IVehicleModel interface):

public class ACME2000SportsCar:Automobile
{
public ACME2000SportsCar(string paramName):base(250, 40, -20, paramName){}
public
ACME2000SportsCar(string paramName, int paramMaxSpeed, int paramMaxTurnSpeed, int paramMaxReverseSpeed):
base(paramMaxSpeed, paramMaxTurnSpeed, paramMaxReverseSpeed, paramName){}
}

And now for our View...

Now we have to create the last of our three ACME MVC components... the View

We'll create a AutoView user control and have it implement the IVehicleView interface. The AutoView component will have references to our control and model interfaces:

public class AutoView : System.Windows.Forms.UserControl, IVehicleView
{
private IVehicleControl Control = new ACME.AutomobileControl();
private IVehicleModel Model = new ACME.ACME2000SportsCar("Speedy");
}

We also need to wire everything up in the constructor for the UserControl.

public AutoView()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
WireUp(Control, Model);
}
public void WireUp(IVehicleControl paramControl, IVehicleModel paramModel)
{
// If we're switching Models, don't keep watching
// the old one!
if(Model != null)
{
Model.RemoveObserver(
this);
}
Model = paramModel;
Control = paramControl;
Control.SetModel(Model);
Control.SetView(
this);
Model.AddObserver(
this);
}

Next, we'll add our buttons, a label to display the status of the ACME2000 Sports Car and a status bar just for kicks and fill out the code for all the buttons. 

private void btnAccelerate_Click(object sender, System.EventArgs e)
{
Control.RequestAccelerate(
int.Parse(this.txtAmount.Text));
}
private void btnDecelerate_Click(object sender, System.EventArgs e)
{
Control.RequestDecelerate(
int.Parse(this.txtAmount.Text));
}
private void btnLeft_Click(object sender, System.EventArgs e)
{
Control.RequestTurn(RelativeDirection.Left);
}
private void btnRight_Click(object sender, System.EventArgs e)
{
Control.RequestTurn(RelativeDirection.Right);
}

Add a method to update the interface...

public void UpdateInterface(IVehicleModel auto)
{
this.label1.Text = auto.Name + " heading " + auto.Direction.ToString() + " at speed: " + auto.Speed.ToString();
this.pBar.Value = (auto.Speed>0)? auto.Speed*100/auto.MaxSpeed : auto.Speed*100/auto.MaxReverseSpeed;
}

Finally, we'll wire up the IVehicleView interface methods...

public void DisableAcceleration()
{
this.btnAccelerate.Enabled = false;
}
public void EnableAcceleration()
{
this.btnAccelerate.Enabled = true;
}
public void DisableDeceleration()
{
this.btnDecelerate.Enabled = false;
}
public void EnableDeceleration()
{
this.btnDecelerate.Enabled = true;
}
public void DisableTurning()
{
this.btnRight.Enabled = this.btnLeft.Enabled = false;
}
public void EnableTurning()
{
this.btnRight.Enabled = this.btnLeft.Enabled = true;
}
public void Update(IVehicleModel paramModel)
{
this.UpdateInterface(paramModel);
}

And we're off!!!

Now we can go for a test drive in the ACME2000 Sports Car. Everything is going as planned and then we run into an ACME executive who wants to drive a pickup truck instead of a sports car. 

Good thing we used the MVC! All we need to do is create a new ACMETruck class, wire it up, and we're in business!

public class ACME2000Truck: Automobile
{
public ACME2000Truck(string paramName):base(80, 25, -12, paramName){}
public ACME2000Truck(string paramName, int paramMaxSpeed, int paramMaxTurnSpeed, int paramMaxReverseSpeed):
base(paramMaxSpeed, paramMaxTurnSpeed, paramMaxReverseSpeed, paramName){}
}

in the AutoView, we just have to build the truck and wire it up!

private void btnBuildNew_Click(object sender, System.EventArgs e)
{
this.autoView1.WireUp(new ACME.AutomobileControl(), new ACME.ACME2000Truck(this.txtName.Text));
}

If we wanted a new Control that only allowed us to increase or decrease the speed by a maximum of 5mph, it's a snap!  Create a SlowPokeControl (same as our AutoControl, but with limits on how much a Model will be requested to accelerate)

public void RequestAccelerate(int paramAmount)
{
if(Model != null)
{
int amount = paramAmount;
if(amount > 5) amount = 5;
Model.Accelerate(amount);
if(View != null) SetView();
}
}
public void RequestDecelerate(int paramAmount)
{
if(Model != null)
{
int amount = paramAmount;
if(amount > 5) amount = 5;
Model.Accelerate(amount);
Model.Decelerate(amount);
if(View != null) SetView();
}
}

If we want to make our ACME2000 Truck a SlowPoke, we just wire it up in the AutoView!

private void btnBuildNew_Click(object sender, System.EventArgs e)
{
this.autoView1.WireUp(new ACME.SlowPokeControl(), new ACME.ACME2000Truck(this.txtName.Text));
}

And finally, if we wanted a web-enabled interface, all we have to do is create a web project and on the UserControl implement the IVehicleView interface!

In Conclusion...

As you can see, using the MVC to help build code to control interfaces that is very loosely coupled makes life much easier when it comes to change requests. It also makes the impact of changes negligible and you can reuse your interfaces and abstract classes almost anywhere. There are a couple of places where we can build some more flexibility in our project, especially in terms of requesting changes to our Model's state, but that will have to wait for next time.

In the meanwhile, keep the MVC in mind for your next project... You won't regret it.

Happy Driving.


Login to add your contents and source code to this article
 About the author
 
Matthew Cochran
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Go.NET
Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes. Supports layers, scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control. Document/View/Tool architecture with many properties&events. Optional automatic layout.
Dundas Software
Dundas Chart for .NET is the most advanced .NET charting package available today.  With an extremely complete feature set, elegant architecture and easy implementation, Dundas Chart can quickly add advanced Charting functionality to enhance and transform ASP.NET and Windows Forms applications.  Whether you are implementing charting into internal projects, or building applications for clients, Dundas Chart offers advanced technology and advanced results to get the most out of data.
Clickatell's SMS Gateway
Clickatell's Developer Solutions allow you to SMS enable any website or application via a range of API's. Learn More about our API connections.
Free access to .NET Memory Management video
Everything you need to know about Garbage Collection, Temporary Objects, Fragmentation, Finalization and common causes of memory leaks in .NET. Watch the video here.
Microsoft Visual Studio 2010 Professional
Microsoft Visual Studio 2010 Professional will launch on April 12, but you can beat the rush and secure your copy today by pre-ordering at the affordable estimated retail price of $549 (US). Pre-order now.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
Developer-Ready ASP.NET 2.0 Web Hosting with 3 MONTHS FREE
Now supporting .NET 3.0 Framework with Windows Workflow Foundation, Windows Communication Foundation (WCF), Windows Presentation Foundation (WPF), windows CardSpace (WCS)! Providing more flexibility for Developers with Web Services Support and a User/Permission Manger. Also supporting MS SQL 2005/2000 with Real-Time Backups, FREE Automated Attach .MDF Tool, FREE SQL Restore and Shrink SQL DB Tools, and SQL
 
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
ModelViewControllerArticle.zip
 
 Post a Feedback, Comment, or Question about this article
Subject:  
Comment:  
Become a Sponsor
 Comments
Good one by Bhasker On December 28, 2005
Good Article
Reply | Email | Delete | Modify | 
Observer Pattern by Tolga On April 27, 2006

Just a question :

Isn't it possible to use custom events and delegates to implement the observer pattern ?

I think it's a more comfortable and easier way to achieve "notifying".

Tolga Güler

Reply | Email | Delete | Modify | 
Re: Observer Pattern by Matthew On May 7, 2006

Definately.  Event if I were to implement the observer pattern instead of exposing events I would do so using protected or private events (check the link below).  Why re-invent the wheel, right?  I intentionally left events out of this article to keep it as simple as possible.

http://www.c-sharpcorner.com/UploadFile/rmcochran/defensiveEvents04022006105141AM/defensiveEvents.aspx?ArticleID=189a3324-9a76-45cf-a190-a8e4d423b07f

Reply | Email | Delete | Modify | 
Very helpful by toni On July 12, 2006

The article helped me to understand the details (in addition to the concept) of MVC much better than others I have read.  I liked the analogy and the programming was straightforward and easy to follow.

 

Reply | Email | Delete | Modify | 
Introduction to Model View Control (MVC) Pattern using C# by Mike On September 27, 2007
A very smart and helpfully article with a well elected example implementation. Keep it up!!
Reply | Email | Delete | Modify | 
more view by nada On November 9, 2007
how can I add / remove views from the views?
Reply | Email | Delete | Modify | 
Indentation by Jeena On December 6, 2007
Great article, man. I also added it to StumbleUpon, 'cause I think it is worth to be read by many developers. I think a better indentation could help. Reading not-formatted code is really annoying. It's a HTML issue, of course. I rate it 5, even if with that terrible indentation ;)
Reply | Email | Delete | Modify | 
How to use MVC in UserControl by semoud On January 22, 2008
How to -professionly- use MVC in creating a UC, and use this UC in an application with a global MVC architecture. -Communication between Model -M- (of the UC) and the model of the application
Reply | Email | Delete | Modify | 
Re: How to use MVC in UserControl by Matthew On January 29, 2008
http://www.c-sharpcorner.com/UploadFile/rmcochran/PassiveView01262008091652AM/PassiveView.aspx
Reply | Email | Delete | Modify | 
Good Article on MVC by Manoj On November 18, 2008
Kindly provide article on other design patterns also. This is awesome.
Reply | Email | Delete | Modify | 
?B by han On July 28, 2009
??
Reply | Email | Delete | Modify | 
hi by ashish On August 18, 2009
Very good article indeed. but i was wondering how will it maintain its state when used on web application. 
i mean we need to maintain the state of model so that its values like speed , name , maxspeed etc is maintained across posts. 
if not, ever time we click on acelerate or decelerate , the value enetere in the text box will be set as the new speed of the mdoel instead of increasing or decreasing the previous speed.

thanks in advance
Reply | Email | Delete | Modify | 

 Hosted by MaximumASP  |  Found a broken link?  |  Contact Us  |  Terms & conditions  |  Privacy Policy  |  Site Map  |  Suggest an Idea  |  Media Kit
Current Version: 5.2009.6.2
 © 2010  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.