Внедрение логики обработки данных в класс

Я хочу найти более элегантный и ценный способ ввода процессоров в класс CommandProcessorDispatcher. Или это может быть еще одно решение (цель разделяет каждую логику обработки команд на независимый класс). Возможно, здесь может быть полезен какой-то шаблон дизайна. Спасибо.

public interface ICommand { }
public class StartCommand : ICommand { }
public class StopCommand : ICommand { }

public interface ICommandProcessor<in T> where T : ICommand
{
    void Process(T command);
}

public class StartCommandProcessor : ICommandProcessor<StartCommand>
{
    public void Process(StartCommand command) { }
}

public class StopCommandProcessor : ICommandProcessor<StopCommand>
{
    public void Process(StopCommand command) { }
}

public interface ICommandProcessorDispatcher
{
    void Process(ICommand command);
}

public class CommandProcessorDispatcher : ICommandProcessorDispatcher
{
    public CommandProcessorDispatcher(Dictionary<Type, Action<ICommand>> processors)
    {
        _processors = processors;
    }

    private readonly Dictionary<Type, Action<ICommand>> _processors;

    public void Process(ICommand command)
    {
        _processors[command.GetType()](command);
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        var dict = new Dictionary<Type, Action<ICommand>>
        {
            { typeof(StartCommand), x => new StartCommandProcessor().Process((StartCommand)x) },
            { typeof(StopCommand), x => new StopCommandProcessor().Process((StopCommand)x) },
        };

        var dispatcher= new CommandProcessorDispatcher(dict);
    }
}
7 голосов | спросил Boo 14 FebruaryEurope/MoscowbSat, 14 Feb 2015 17:40:55 +0300000000pmSat, 14 Feb 2015 17:40:55 +030015 2015, 17:40:55

2 ответа


0

Я считаю, что вы можете немного упростить ситуацию, не слишком много шаблонов, сохраняя при этом безопасность some .

Надуманный пример:

public interface ICommand
{
}

#region Friends
public abstract class CommandProcessor
{
    internal abstract void Process(ICommand command);

    public abstract Type CommandType { get; }
}

public abstract class CommandProcessor<TCommand> : CommandProcessor
    where TCommand : ICommand
{
    internal override void Process(ICommand command)
    {
        Process((TCommand)command);
    }

    protected abstract void Process(TCommand command);

    public override Type CommandType { get { return typeof(TCommand); } }
}

public class CommandProcessorDispatcher
{
    public CommandProcessorDispatcher(IEnumerable<CommandProcessor> processors)
    {
        Processors = processors;
    }

    public void Process(ICommand command)
    {
        var found =
            Processors.
            FirstOrDefault
            (
                processor => processor.CommandType == command.GetType()
            );
        if (found == null)
        {
            throw new InvalidOperationException("no suitable processor found");
        }
        found.Process(command);
    }

    // (may just be protected only, depending on requirements)
    public IEnumerable<CommandProcessor> Processors { get; protected set; }
}
#endregion

public class StartCommand : ICommand
{
    public override string ToString()
    {
        return StartId.ToString();
    }

    public int StartId { get; set; }
}

public class StopCommand : ICommand
{
    public override string ToString()
    {
        return StopId.ToString();
    }

    public int StopId { get; set; }
}

public class StartCommandProcessor : CommandProcessor<StartCommand>
{
    protected override void Process(StartCommand command)
    {
        Console.WriteLine("START : " + command);
    }
}

public class EndCommandProcessor : CommandProcessor<StopCommand>
{
    protected override void Process(StopCommand command)
    {
        Console.WriteLine("STOP : " + command);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        var dispatcher =
            new CommandProcessorDispatcher
            (
                new CommandProcessor[]
                {
                    new StartCommandProcessor(),
                    new EndCommandProcessor()
                }
            );

        var start = new StartCommand { StartId = 123 };
        var stop = new StopCommand { StopId = 456 };

        dispatcher.Process(start);
        dispatcher.Process(stop);

        Console.ReadKey();
    }
}

Это делает меньше предположений о том, как хранятся командные процессоры, и не требует делегатов Action, которые я пропустил, чтобы увидеть цель в вашем примере. Наконец, я думаю, что предпочтительнее иметь downcast (от ICommand до одного его реализации) происходят только в одном месте.

ответил YSharp 5 +03002016-10-05T01:30:11+03:00312016bEurope/MoscowWed, 05 Oct 2016 01:30:11 +0300 2016, 01:30:11
-1

Сфокусируйтесь на:

  

[...], или это может быть другое решение (цель отдельно   логика обработки команд для независимого класса)

с помощью Factory может сделать вещи довольно простыми:

public interface ICommand { }
public class StartCommand : ICommand { }
public class StopCommand : ICommand { }

public interface ICommandProcessor
{
    void Process(ICommand command);
}

public class StartCommandProcessor : ICommandProcessor
{
    public void Process(ICommand command) { }
}

public class StopCommandProcessor : ICommandProcessor
{
    public void Process(ICommand command) { }
}

public class UnknownCommandProcessor : ICommandProcessor
{
    public void Process(ICommand command) { }
}

public class CommandProcessorDispatcher
{
    public void Process(ICommand command)
    {
        var processor = CommandProcessorFactory.GetCommandProcessor(command);
        processor.Process(command);
    }
}

public static class CommandProcessorFactory
{
    public static ICommandProcessor GetCommandProcessor(ICommand command)
    {
        if (command is StartCommand)
            return new StartCommandProcessor();
        else if (command is StopCommand)
            return new StopCommandProcessor();
        else
            return new UnknownCommandProcessor();
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        var dispatcher = new CommandProcessorDispatcher();            
        dispatcher.Process(new StartCommand());
        dispatcher.Process(new StopCommand());
        Console.ReadLine();
    }
}
ответил dpant 29 AMpSun, 29 Apr 2018 09:40:44 +030040Sunday 2018, 09:40:44

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132