mercredi 7 juin 2023

How to reference the correct class in a parallel class hierarchy

I have a base class that produces a text depending on its internal state. This is achieved by a state machine.

public abstract class BaseState
{
    // State functions

    public abstract string GetText();

    public abstract bool ShouldUpdateText();
}


public class ObjectBase // Context class
{
    public BaseState State;

    public string Text;

    public float Data1;

    public void UpdateText()
    {
        if(State.ShouldUpdateText())
       {
            Text = State.GetText();
       }
    }

    // State machine functions
}

State objects need a reference to the context class for its logic.

Derivations of the base context class have their own state object classes which need to work on that class.

So the class hierarchy of base context class is paralleled by the state class hierarchy.

public class DerivedObject1 : ObjectBase 
{
   public int[] Data2;
}

public class DerivedObject2 : DerivedObject1 
{
   public bool Data3;
}


/* Needs to work with an ObjectBase */
public class State1 : BaseState
{
   public override bool ShouldUpdateText()
   {
        return Data1 > 0;
   }
}

/* Needs to work with a DerivedObject1 */
public class State2 : BaseState
{
   public override bool ShouldUpdateText()
   {
        return Data2.Length > 2;
   }
}

/* Needs to work with a DerivedObject2 */
public class State3 : State2 
{
   public override bool ShouldUpdateText()
   {
        return base.ShouldUpdateText() && Data3;
   }
}

I'm trying to figure out what is the best way to provide a context reference to state classes as they all have different types although they share their highest parent.

Some options I considered

Type-casting through base class reference -- Feels like a code smell

class BaseState
{
    public ObjectBase Context;
}

public class State2 : BaseState
{
   public override bool ShouldUpdateText()
   {
        return (Context as DerivedObject1).Data2.Length > 2;
   }
}

Intermediate parent states for correct typed references

Doesn't work when there are states deriving from states, such as State2 & State3 in the initial example.

class StateForDerivedObject1 : BaseState
{
    public DerivedObject1 Context;
}

public class State2 : StateForDerivedObject1 
{
   public override bool ShouldUpdateText()
   {
        return Context.Data2.Length > 2;
   }
}

What is the best way to handle this problem?

Is there a better way to design the architecture that avoids this problem altogether?

Thanks

Aucun commentaire:

Enregistrer un commentaire