基于输入指令的任务选择执行架构优化方案咨询
Great question! That long chain of if-else or switch statements can quickly become a maintenance nightmare—especially as you add more tasks down the line. Let’s look at a couple of cleaner, more scalable approaches to replace that conditional mess:
1. Dictionary/Hash Map Mapping
This is the simplest, most straightforward upgrade for your use case. You can create a dictionary that maps each TaskExecutor.TasksEnum value directly to its corresponding execution method. This turns your messy conditional checks into a single lookup, making the code easier to read and maintain.
Example in C#:
First, initialize the dictionary once (ideally in your class constructor):
private readonly Dictionary<TaskExecutor.TasksEnum, Action> _taskExecutionMap; public YourTaskHandler(TaskExecutor taskExecutor) { _taskExecutionMap = new Dictionary<TaskExecutor.TasksEnum, Action> { { TaskExecutor.TasksEnum.One, taskExecutor.ExecuteTaskOne }, { TaskExecutor.TasksEnum.Two, taskExecutor.ExecuteTaskTwo }, { TaskExecutor.TasksEnum.Three, taskExecutor.ExecuteTaskThree } // Just add a new line here when you need to support a new task }; }
Then, processing tasks becomes a breeze:
var task = _taskProvider.GetNextFromQueue(); if (_taskExecutionMap.TryGetValue(task.id, out var executeTask)) { executeTask(); } else { // Handle unknown tasks (log an error, throw a meaningful exception, etc.) }
This approach follows the Open/Closed Principle—you can add new tasks without modifying the core task-processing logic.
2. Command Pattern (For Complex Tasks)
If your tasks require parameters, setup/teardown logic, or you want to enforce better separation of concerns, the Command Pattern is a robust choice. Each task gets its own dedicated class that encapsulates all logic related to executing it.
Example:
First, define a base command interface:
public interface ITaskCommand { void Execute(); }
Then create concrete command classes for each task:
public class TaskOneCommand : ITaskCommand { private readonly TaskExecutor _taskExecutor; // Inject any dependencies the task needs here public TaskOneCommand(TaskExecutor taskExecutor) { _taskExecutor = taskExecutor; } public void Execute() { _taskExecutor.ExecuteTaskOne(); // Add any extra logic (logging, validation, etc.) here } } // Repeat for TaskTwoCommand, TaskThreeCommand, etc.
Next, set up a factory or dictionary to resolve commands:
private readonly Dictionary<TaskExecutor.TasksEnum, Func<ITaskCommand>> _commandFactory; public YourTaskHandler(TaskExecutor taskExecutor) { _commandFactory = new Dictionary<TaskExecutor.TasksEnum, Func<ITaskCommand>> { { TaskExecutor.TasksEnum.One, () => new TaskOneCommand(taskExecutor) }, { TaskExecutor.TasksEnum.Two, () => new TaskTwoCommand(taskExecutor) }, { TaskExecutor.TasksEnum.Three, () => new TaskThreeCommand(taskExecutor) } }; }
Processing tasks now looks like this:
var task = _taskProvider.GetNextFromQueue(); if (_commandFactory.TryGetValue(task.id, out var commandCreator)) { var command = commandCreator(); command.Execute(); } else { // Handle unknown tasks }
This pattern shines when tasks grow in complexity—each command class keeps its logic isolated, making debugging and testing easier.
Quick Recommendation
- Use the dictionary mapping if you’re just calling simple methods with no extra logic. It’s lightweight and easy to implement.
- Use the Command Pattern if your tasks need dependencies, parameters, or you want to encapsulate more behavior per task.
内容的提问来源于stack exchange,提问作者CorellianAle

