Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design pattern for command line software with multiple functionalities

I'm developing a program that is going to be called from the command line. The software will be a sort of 'kit' with differing functionality based on the different flags defined while calling the program. Some of this functionality is wildly differing from others and the only similarity is the type of file that it operates on.

I was wondering what the best design pattern is to implement this kind of functionality? I've read about the facade design pattern which splits each module into a different sub-system. Building each piece of functionality under a different facade would keep it modular and would allow me to build a single class to handle which facade to call.

Is this the best way to go about it, or would you recommend something different?

Thanks, Sam

like image 657
Sam Avatar asked Oct 26 '17 14:10

Sam


2 Answers

Because this is a command line application, I think the Command pattern could be useful for you. Personally, I believe this is a good way to structure console apps.

This is a possible implementation (in c#) to support multiple commands:

// The main class, the entry point to the program
internal class Program
{
    private static void Main(string[] args)
    {
        var p = new Processor();
        p.Process(args);
    }
}

/* The command processor class, its responsibility is to take its input parameters to create the command and execute it. */
public class Processor
{
    private CommandFactory _commandFactory;

    public Processor()
    {
        _commandFactory = new CommandFactory();
    }

    public void Process(string[] args)
    {
        var arguments = ParseArguments(args);
        var command = _commandFactory.CreateCommand(arguments);

        command.Execute();
    }

    private CommandArguments ParseArguments(string[] args)
    {
        return new CommandArguments
        {
            CommandName = args[0]
        };        
    }
}

/* Creates a command based on command name */
public class CommandFactory
{
    private readonly IEnumerable<ICommand> _availableCommands = new ICommand[]
                    {
                        new Command1(), new Command2(), .....
                    };

    public ICommand CreateCommand(CommandArguments commandArguments)
    {
        var result = _availableCommands.FirstOrDefault(cmd => cmd.CommandName == commandArguments.CommandName);
        var command = result ?? new NotFoundCommand { CommandName = commandArguments.CommandName };
        command.Arguments = commandArguments;

        return command;
    }
}

public interface ICommand
{
    string CommandName { get; }
    void Execute();
}

/* One of the commands that you want to execute, you can create n implementations of ICommand */
public class Command1 : ICommand
{
    public CommandArguments Arguments { get; set; }

    public string CommandName
    {
        get { return "c1"; }
    }

    public void Execute()
    {
        // do whatever you want to do ...
        // you can use the Arguments
    }
}


/* Null object pattern for invalid parametters */
public class NotFoundCommand : ICommand
{
    public string CommandName { get; set; }

    public void Execute()
    {
        Console.WriteLine("Couldn't find command: " + CommandName);
    }
}
like image 103
Jairo Alfaro Avatar answered Nov 10 '22 22:11

Jairo Alfaro


You might want to check out the strategy pattern:

the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime

like image 24
Bit33 Avatar answered Nov 10 '22 22:11

Bit33