vendredi 16 février 2018

Alternative method for Switch Statements

According to some articles:

The theory says that it is easy, but in practice this is often difficult. Never mind. Let's get to the heart of this thing.

The code looks like this:

    public class SomeType
    {
        // Some properties.
    }

    public enum SomeTrigger
    {
        Loaded,
        Initial,
        Timer,
        Final
    }


    public class SomeBaseObject
    {
        // 
        // I am not allowed to change this class. It is not mine.
        //

        protected Dictionary<string, SomeType> Input;
        protected Dictionary<string, SomeType> Output;


        // Timer is evaluated every 2 sec.
        public virtual void Execute(SomeTrigger trigger, string value)
        {
            switch (trigger)
            {
                case SomeTrigger.Loaded:
                    break;
                case SomeTrigger.Initial:
                    break;
                case SomeTrigger.Timer:
                    break;
                case SomeTrigger.Final:
                    break;
                default:
                    break;
            }
        }

        // The rest of code...
    }

And the class that I want to improve:

public class SomeSpecificObject : SomeBaseObject
    {
        private bool isInitializationCompleted;
        private string connection;

        public override void Execute(SomeTrigger trigger, string value)
        {
            switch (trigger)
            {
                case SomeTrigger.Loaded:
                    this.OnLoaded();
                    break;
                case SomeTrigger.Initial:
                    this.OnInitial();
                    break;
                case SomeTrigger.Timer:
                    this.OnTimer();
                    break;
                case SomeTrigger.Final:
                    this.OnFinal(value);
                    break;
                default:
                    break;
            }
        }

        private void OnLoaded()
        {
            // Read Input and Output collection.
        }

        private void OnInitial()
        {
            // Initialization (connect to the server).
            // Bla bla bla
            this.connection = //Value from the plug-in;
            this.isInitializationCompleted = true;

        }

        private void OnTimer()
        {
            if (isInitializationCompleted)
            {
                // Do something
                // Connection is using here.
                // Calculate values on a Input collection, etc.
            }
        }

        private void OnFinal(string value)
        {
            if (isInitializationCompleted)
            {
                // something with "value"
                // Connection is using here.
                // Clear state.
            }
            else
            {
                // Connection is using here.
                // Cancel inistialization
            }
        }
    }

What should I do? Every field is using but every trigger. Additionally the one case is a little specific (OnFinalMethod needs argument). Based on the above articles, I have tried to refactor this code, but unsuccessfully.

My attempts to apply some tips: 

    public interface ITrigger
    {
        void Execute();
    }

    public class LoadedTrigger : ITrigger
    {
        public void Execute()
        {
            throw new NotImplementedException();
        }
    }

    //
    // Exactly the same class for the rest cases.
    //
    public class TriggerHandler
    {
        private Dictionary<SomeTrigger, ITrigger> triggerDictionary;

        public TriggerHandler()
        {

            triggerDictionary.Add(SomeTrigger.Loaded, new InitialTrigger());
    // and for the rest

        }

        public void HandleTrigger(SomeTrigger trigger)
        {
            triggerDictionary[trigger].Execute();
        }
    }

How the objects should communicate with each other? E.g. TimerTrigger objects needs to know that the initiation is successful. What shall I do with the special case object?

Any idea? :)

Aucun commentaire:

Enregistrer un commentaire