views:

237

answers:

1

In my applications I always end up implementing a Model-View-Presenter pattern and usually end up scrapping my View object from the screen with a get property.

For example

Person IBasicRegistration.Person
{
 get
 {
  if (ViewState["View.Person"] == null)
   ViewState["View.Person"] = new Person();

  var Person = (Person) ViewState["View.Person"];

  Person.Email = txtEmail.Text.Trim();
  Person.FirstName = txtFirstName.Text.Trim();
  Person.LastName = txtLastName.Text.Trim();
  Person.Zip = txtZip.Text.Trim();
  Person.Phone = txtPhone.Text.Trim();
  Person.ResidentPersonLicenseState = 
        EnumerationParser.Parse<States?>(ddState.SelectedValue);

  return Person;
 }
}

However during debugging I've noticed when I access IBasicRegistration.Person in my Presenter/Model that I get quite a few traversals of my get { } property.

I started thinking this pattern seems to very similar to the INotifyPropertyChanged pattern and I started thinking about implementing a similar pattern and having each textfield implement an OnChanged event that would update it's related value in the person object that sits in the view state however the further I thought on that it require numerous server requests every time a person mouses out of a field and seems like it could lead to scalability issues at some point.

My next thought would it just make sense to create an IsDirty flag and wrap my code where it touches the fields similar to:

Person IBasicRegistration.Person
{
 get
 {
  if (ViewState["View.Person"] == null)
   ViewState["View.Person"] = new Person();

  var Person = (Person) ViewState["View.Person"];

  if(IsDirty)
  {
      Person.Email = txtEmail.Text.Trim();
      ...others

      IsDirty = false;
  }

  return Person;
 }
}

And set on any method that invokes a post back, (ie usually just the submit button) to set IsDirty = true and then it will skip repeating alot of work for no reason.

Has anyone come up with something more elegant for this task?

+2  A: 

I think where the disconnect is happening is that you typically implement a view while in your get you are create the view. A typical scenario is that a form implements a view interface and then register itself (or is registered) within the application object. Then anytime you need to find out what has been entered for a person you use the various properties of the view.

For example to find out what you entered for the first name you would go

 myVariable = PersonView.FirstName();

In your example you are pulling the STATE of the view every time you access person. Even if you just wanted the email you are pulling everything and putting it in a state variable.

Now this if the data structure Person was part of your model. Then this could be OK. You pull the person out once when it is changed. Modify or add it to the model then everything else (reports ,etc) would be looking at the model.

However your question suggests that that it is being hit over and over again. Which leads me to think that Person is being accessed directly from the view for a variety of reasons. In this case I would put properties on the view allowing access to the individual members.

Or I would refactor the design so that everything uses the model for the data with the model being updated everytime the view changes. I suspect you probably don't want to do this at this point and hence the best way is to use individual properties.

RS Conley
The down side to exposing everything as just Properties: PersonFirstName, PersonLastName and etc is that all it will do is delay rolling them all into a person object or make my model methods to be replaced from using the person objects and take in huge parameter lists. I guess I could accept going back to packing my views with property lists instead of a single object those properties represent if someone could make a compelling argument to why this breaks any modern design convention.
Chris Marisic
Your person object resides in the model somewhere. Your Presenter should be smart enough to pull from the view and update the model. It doesn't matter if it pulling a person object or a just a single property. The advantage is that allowing property access is that you can pull as much or as little as you want from the view. With your current method you are stuck with pulling a entire person object from the view. You can still have that function for commands where they make sense. But with properties you have a clear way of pulling out just one thing when you just want one thing.
RS Conley