views:

102

answers:

1

Here is the design problem in pseudo example:

It is ASP.NET User control (UC) which uses the "Food" object as data source and this object has property FoodType - "Veg" || "Nonveg".

The user control changes UI display depending upon FoodType property. In code-behind class of User Control, some methods have same if/then/else condition: if(Food.FoodType == "Veg")... else ...

Here, I would like use State-like pattern such that code-behind class of User Control will contain two inner/nested classes, i.e. "VegFood" class and "NonvegFood" class. Now, lets say, NonvegFood class will contain its own logic implementation.

But having one interface, two instance classes (as nested) which will be used in this user control only, could be overdesign. In addition to that, UC does not have driver method where I can call related methods in one if block, like they are "DataBound" and "ItemCreated".

Still, is it possible to have State like pattern inside UC class? Probably two instance inner classes inside UC and somehow if I can delegate call to one of these inner class?

class UC : UserControl
{

    class VegFood
    {
        string DisplayName
        {
          get
          {
            return "Rice";
          }
        }       
    }

    class NonvegFood
    {
        string DisplayName
        {
          get
          {
            return "Chicken";
          }
        }       
    } 

    protected string DisplayName
    {
        get
        {
            return Instance.DisplayName;
        }
    }

    /*********** MAGIC Property ****************/
    private ? Instance
    {
        get
        {
           return ?;
        }
    }
}
A: 

I do not think that having three nested classes is not design overkill if it makes the code easier to maintain.

I would suggest an abstract base State class which defines the contract of your states. Each state would inherit from this.

Extended your code sample:

class UC : UserControl
{

protected string DisplayName
{
    get
    {
        return Instance.DisplayName;
    }
}

/*********** MAGIC Property ****************/
private FoodState _instance = null;

private FoodState Instance
{
    get
    {
       if (_instance == null)
       {
           if (FoodType == "Veg")
           {
                 _instance = new VegFood();
           }
           else
           {
                 _instance = new NonvegFood();
           }
       }

       return _instance;
    }
}


abstract class FoodState
{
    abstract public string DisplayName {get;}
}

class VegFood : FoodState
{
    public string DisplayName
    {
      get
      {
        return "Rice";
      }
    }       
}

class NonvegFood : FoodState
{
    public string DisplayName
    {
      get
      {
        return "Chicken";
      }
    }       
}

}

You probably don't need the protected DisplayName property on the UserControl directly, as Instance.DisplayName could be used directly by the aspx page.

Mark Glasgow
Thank you Mark. But as I mentioned, actually I am looking for alternate solution of this. A User Control class having (small) class hierarchy inside class, hmmm....
the decision between the user control having its own class hierarchy versus using <% if (FoodType == "Veg") %> statements in the user control would depend on how many parts of the user control are conditional to the food type. if a lot, then a class hierarchy (even though private) makes sense because it reduces the amount of code over all). if not, then perhaps the if statements make more sense.
Mark Glasgow
but the user of a private class hierarchy in the user control could point to some possible refactoring of the domain model instead? Maybe Food needs to be refactored? Or instead of having a single user control, is it better represented as two user controls (which maybe inherit from an abstract control)?
Mark Glasgow