Tutorial :Design problem: Get child object type information avoiding if statements in presentation layer



Question:

I have a customer hierarchy like so:

abstract class Customer {      public virtual string Name { get; set; }  }    class HighValueCustomer : Customer {      public virtual int MaxSpending { get; set; }  }     class SpecialCustomer : Customer {      public virtual string Award { get; set; }  }  

When I retrieve a Customer, I would like to show on the web form the properties to edit/modify. Currently, I use if statements to find the child customer type and show the specialized properties. Is there a design pattern (visitor?) or better way so I can avoid the "if" statements in presentation layer? How do you do it?

Further information: This is an asp.net website with nHibernate backend. Each customer type has its own user control on the page that I would like to load automatically given the customer type.


Solution:1

Can you use reflection to get the list of properties specific to an subclass (instance)? (Less error-prone.)

If not, create a (virtual) method which returns the special properties. (More error prone!)

For an example of the latter:

abstract class Customer {      public virtual string Name { get; set; }        public virtual IDictionary<string, object> GetProperties()      {          var ret = new Dictionary<string, object>();          ret["Name"] = Name;          return ret;      }  }    class HighValueCustomer : Customer {      public virtual int MaxSpending { get; set; }        public override IDictionary<string, object> GetProperties()      {          var ret = base.GetProperties();          ret["Max spending"] = MaxSpending;          return ret;      }  }     class SpecialCustomer : Customer {      public virtual string Award { get; set; }        public override IDictionary<string, object> GetProperties()      {          var ret = base.GetProperties();          ret["Award"] = Award;          return ret;      }  }  

You probably want to create sections (fieldsets?) on your Web page, anyway, so if would come into play there, making this extra coding kinda annoying and useless.


Solution:2

I think a cleaner organization would be to have a parallel hierarchy of display controls or formats. Maybe use something like the Abstract Factory Pattern to create both the instance of Customer and of CustomerForm at the same time. Display the returned CustomerForm instance, which would know about the extra properties and how to display and edit them.


Solution:3

new:

interface CustomerEdit  {      void Display();  }  

edit:

abstract class Customer {      protected CustomerEdit customerEdit; // customers have an object which allows for edit        public virtual string Name { get; set; }      public void Display() { customerEdit.Display(); } // allow the CustomerEdit implementor to display the UI elements  }    // Set customerEdit in constructor, tie with "this"  class HighValueCustomer : Customer {      public virtual int MaxSpending { get; set; }  }     // Set customerEdit in constructor, tie with "this"  class SpecialCustomer : Customer {      public virtual string Award { get; set; }  }  

usage:

Customer whichCouldItBe = GetSomeCustomer();  whichCouldItBe.Display(); // shows UI depeneding on the concrete type  


Solution:4

Have you tried something like this:

public class Customer<T>      where T : Customer<T>  {      private T subClass;      public IDictionary<string, object> GetProperties()      {          return subClass.GetProperties();      }  }  

With a subclass of:

public class FinancialCustomer : Customer<FinancialCustomer>  {  }  

This is off the top of my head so might not work. I've seen this type of code in CSLA.NET. Here's the link to the CSLA.NET class called BusinessBase.cs which has a similar definition to what I've given above.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »