Hi,
There are a number of patterns that help you seperate logic in applications , which results in cleaner and more maintainable code. The MVP pattern is a good one to start with. It is based on defining 3 areas of responisbility i.e. MVP M = Model, V = View, P = Presenter. If you are familiar with using interfaces you will be fine, otherwise that would be a good place to start (review the basic OO priciples: Encapsulation,Abstraction, Polymorphism). The basic principle of the MVP is to put you application logic in the Presenter. The presnter talks to the view (your form) via an interface, and the view calls back to the presenter (i use a interface for this too) when the user interactions with it. The model is the solution's domain object hierarchy which implments buisiness logic and entity relationships.
Most UI patterns (MVP, MCV etc) are trying to do the same things, seperate you concerns. Tghe following is a simple example:
//The view interface
interface IUserDetailsView
{
string Username{set;get;}
string FirstName{get;set;}
string LastName{get;set;}
UserDetailsPresenter Presenter{get;set;}
void DisplayMessage(string message);
}
//The view implmentation
//A standard windows form which has text boxes, labels, combos etc , which
class UserDetailsView : Form, IUserDetails
{
public string Username{set{txtUserName.text = value;}get{return txtUserName.text;}}
public string FirstName{set{txtFirstName.text = value;}get{return txtFirstName.text;}}
public string LastName{set{txtLastName.text = value;}get{return txtLastName.text;}}
Public UserDetailsPresenter Presenter{get;set;}
public void DisplayMaessage(string message)
{
MessageBox.Show(message);
}
private void saveButton_Click(object sender, EventArgs e)
{
Presenter.SaveUserDetails();
}
}
//Presentation Logic
class Presenter UserDetailsPresenter
{
//Constructor
public userDetailsPresenter(IUserDetailsView view)
{
//Hold a reference to the view interface and set the view's presnter
_view = view;
_view.Presenter = this;
}
private IUserDetailsView _view;
DisplayUser(string userName)
{
//Get the user from some service ...
UserDetails details = service.GetUser(userName);
//Display the data vioa the interface
_view.UserName = details.UserName;
_view.FirstName = details.FirstName;
_view.LastName = details.LastName;
}
public void SaveUserDetails()
{
//Get the user dryaiols from the view (i.e. the screen
UserDetails details = new UserDetails();
details.UserName = _view.UserName;
details.FirstName = _view.FirstName;
details.LastName = _view.LastName;
//Apply some business logic here (via the model)
if(!details.IsValidUserDetails())
{
_view.DisplayMessage("Some detail outlining the issues");
return;
}
//Call out to some service to save the data
service.UpdateUser(details);
}
}
//Finally, the model
public class UserDetails
{
public UserName {get;set;}
public FirstName{get;set;}
public LastName{get;set;}
public bool IsValidUserDetails()
{
if(LastName == "Smith")
{
//We do not allow smiths, remember what happened last time ... or whatever
return false;
}
return true;
}
}
Hopefully this explains how responsibility is seperated. The form has no logic apart from display/formatting etc, it can also be stubbed out for testing . The presenter is the mediator between the view and the model and makes calls to services, the model implments your business logic. As already suggested there are variations on this pattern, which can make your code a bit slimmer and more flexible but this outlines the basic principles. I hope this helps.
:-)