Simplify multiple if statements that use if (string.contains())

后端 未结 3 1515
青春惊慌失措
青春惊慌失措 2021-01-26 10:20

I am working on a personal assistant program and I have a method called input_parse() which looks at the input string and checks for words that correspond to \"commands\" the ps

3条回答
  •  时光说笑
    2021-01-26 10:31

    You have commands and input arguments which are related to each other. It seems logical to me to encapsulate these two things into one object and keep them close. You can create interface for such objects

    public interface ICommand
    {
        bool CanGetArgumentsFrom(string input);
        void Execute();
    }
    

    And commands which implement it

    public class CommandA : ICommand
    {
        public bool CanGetArgumentsFrom(string input)
        {
            return input.Contains("argA");
        }
    
        public void Execute()
        {
            /* execute command A */
        }
    }
    

    And second command

    public class CommandB : ICommand
    {
        public bool CanGetArgumentsFrom(string input)
        {
            return input.Contains("argB") && input.Contains("argC");
        }
    
        public void Execute()
        {
            /* execute command B */
        }
    }
    

    Usage is pretty readable

    ICommand[] commands = { new CommandA(), new CommandB() };
    
    foreach(var command in commands)
       if (command.CanGetArgumentsFrom(input))
           command.Execute();
    

    You even can have method

    public bool TryExecuteCommand(string input)
    {
        if (!CanGetArgumentsFrom(input))
            return false;
    
        Execute();
        return true;
    }
    

    Then execution will be even more simple and readable:

    foreach(var command in commands)
        command.TryExecute(input);
    

    If you don't want to create named commands, then you can use object which verifies input and executes some action if all required arguments are in place

    public class Command
    {
        string[] arguments;
        Action action;
    
        public Command(Action action, params string[] arguments)
        {
            this.action = action;
            this.arguments = arguments;
        }
    
        public bool TryExecute(string input)
        {
            if (!arguments.All(input.Contains))
                return false;
    
            action();
            return true;
        }
    }
    

    Now with this single class you can create commands:

    var commands = new Command[] {
        new Command(_ => /* execute A */, "argA"),
        new Command(_ => /* execute B */, "argB", "argC"),
    };
    

提交回复
热议问题