OT: Design Help

OT: Design Help

Old forum URL: forums.lhotka.net/forums/t/7005.aspx


Jack posted on Wednesday, May 27, 2009

I've created an abstract base class for managing composite UI views that is working well for number of descendants and I've realized it is also very useful for some other slightly more detailed use cases I'm plugging in.  However one of the things I did at the beginning was to create a couple of initialization methods driven off of an enum.  This works great except for these new descendants which really have a different set of enum values.  I think there is a better way I could have done this and was hoping for some tips.

the Enum values are used all over so that I know what UI view I'm using, I pass it to an Init method and return in as part of a few argument classes so I can make processing
decisions based on common variables + action (ie Action-NewObject View-MasterA).


AbstractBaseClass

    enum baseViews {MasterA, MasterB, MasterC}

    protected virtual void RegisterExplorerCompononents
    {
         RegisterExplorerCompononent(baseViews.MasterA);
         RegisterExplorerCompononent(baseViews.MasterB);
    }

    protected virtual void RegisterExplorerCompononent(baseViews view)
    {
        switch(view) ...
    }

Works great for my generic descendants, I just override RegisterExplorerCompononents to initialize the subset of enum views I care about.

But in my more detailed descendants I basically have a unique set of views and a different enum


DerivedUniqueDescendantClass

    enum ChildViewsAbc {DetailA, DetailB, DetailC} or enum ChildViewsXyz {DetailX, DetailY, DetailZ}

    //I'm basically overriding the generic register to point it at a unique register method and then re-implementing a unique RegisterXyzComponents and a RegisterXyzComponentXyz(childViewEnum childView) for each unique descendants.

    protected override void RegisterExplorerCompononents
    {
         RegisterChildXyzCompononents
    }

    protected override void RegisterExplorerCompononent(baseViews view)
    {
         throw new NotImplementedException();
    }

    protected void RegisterChildXyzCompononents
    {
         RegisterChildXyzCompononents
    }

    protected override void RegisterChildXyzCompononent(childViews view)
    {
         switch(view) ...
    }


Any suggestions on a better way to do this.  It seemed a bit awkward as I've been coding although it doesn't seem that terrible as I type it out..

thanks

jack

SonOfPirate replied on Wednesday, May 27, 2009

Do you have actual classes that represent the views?  If so, then I'd use the Type to describe the views.  Then you can have the RegisterExplorerComponent method accept the Type or, if you are instantiating the Views, the base class or interface used by the Views.

Another option would be to use a class rather than an enumeration to define the various views.  Each view can be defined as a read-only property on the class.  Then you can derive this class to extend it with additional views.  Since your RegisterExplorerComponent method accepts the base type, it will accept the derived class as well.

Not knowing your full use-case, here is an example of how I've implemented something similar:

public class ViewDefinition
{
   
internal ViewDefinition(System.String name)
   
{
       
Name = name;
    }

    public System.String Name
    {
       
get;
       
private set;
    }
}

public abstract class MasterViews
{
   
public static readonly ViewDefinition View1 = new ViewDefinition("View1");
   
public static readonly ViewDefinition View2 = new ViewDefinition("View2");
}

public class CustomViews : MasterViews
{
   
public static readonly ViewDefinition NewView1 = new ViewDefinition("NewView1");
   
public static readonly ViewDefinition NewView2 = new ViewDefinition("NewView2");
}

public abstract class AbstractBaseClass
{
   
protected AbstractBaseClass()
    {
        Initialize();
   
}

    protected virtual void Initialize()
    {
        RegisterExplorerComponents(
MasterViews.View1);
        RegisterExplorerComponents(
MasterViews.View2);
    }

    protected void RegisterExplorerComponents(ViewDefinition view)
    {
       
// ...
   
}
}

public class DerivedClass : AbstractBaseClass
{
   
public DerivedClass() : base()
    { }

    protected override void Initialize()
    {
        RegisterExplorerComponents(
CustomViews.View1);
        RegisterExplorerComponents(
CustomViews.View2);
    }
}

 

Jack replied on Wednesday, May 27, 2009

perfect  - for the most part I have actual classes that match the views but I'm using the same enum for multiple purposes.  ie) enum.SomethingDetailView would be used for the readonly or the edit or the list version just depending on the use.  The example you laid out is exactly what I needed.  I basically wanted an inheritable enum which is easily represented with a class.

 

thanks.

 

jack

 

From: SonOfPirate [mailto:cslanet@lhotka.net]
Sent: May-27-09 4:33 PM
To: jaddington@alexandergracie.com
Subject: Re: [CSLA .NET] OT: Design Help

 

Do you have actual classes that represent the views?  If so, then I'd use the Type to describe the views.  Then you can have the RegisterExplorerComponent method accept the Type or, if you are instantiating the Views, the base class or interface used by the Views.

Another option would be to use a class rather than an enumeration to define the various views.  Each view can be defined as a read-only property on the class.  Then you can derive this class to extend it with additional views.  Since your RegisterExplorerComponent method accepts the base type, it will accept the derived class as well.

Not knowing your full use-case, here is an example of how I've implemented something similar:

public class ViewDefinition
{
    internal ViewDefinition(System.String name)
    {
        Name = name;
    }

    public System.String Name
    {
        get;
        private set;
    }
}

public abstract class MasterViews
{
    public static readonly ViewDefinition View1 = new ViewDefinition("View1");
    public static readonly ViewDefinition View2 = new ViewDefinition("View2");
}

public class CustomViews : MasterViews
{
    public static readonly ViewDefinition NewView1 = new ViewDefinition("NewView1");
    public static readonly ViewDefinition NewView2 = new ViewDefinition("NewView2");
}

public abstract class AbstractBaseClass
{
    protected AbstractBaseClass()
    {
        Initialize();
    }

    protected virtual void Initialize()
    {
        RegisterExplorerComponents(MasterViews.View1);
        RegisterExplorerComponents(MasterViews.View2);
    }

    protected void RegisterExplorerComponents(ViewDefinition view)
    {
        // ...
   
}
}

public class DerivedClass : AbstractBaseClass
{
    public DerivedClass() : base()
    { }

    protected override void Initialize()
    {
        RegisterExplorerComponents(CustomViews.View1);
        RegisterExplorerComponents(CustomViews.View2);
    }
}

 



Copyright (c) Marimer LLC