我可以多次使结构或类符合通用协议吗?

时间:2016-10-30 21:17:48

标签: swift generics cqrs swift-protocols

假设我有这些协议:

protocol Command {}

protocol CommandHandler
{
    associatedtype T: Command
    func handle(command: T) throws
}

我想创建一个可以处理多个命令的命令处理程序,如下所示:

class InventoryCommandHandler: CommandHandler
{
    func handle(command: AddItemCommand) {
        // do something
    }

    func handle(command: RemoveItemCommand) {
        // do something
    }

    func handle(command: SomeOtherCommand) {
        // do something
    }
}

但是当我尝试它时,它说InventoryCommandHandler不符合CommandHandler协议。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:2)

您应该像这样定义CommandHandler

protocol CommandHandler {
    func handle(command: Command) throws
}

现在给出这3个命令

struct AddItemCommand: Command { }
struct RemoveItemCommand: Command { }
struct SomeOtherCommand: Command { }

您可以创建InventoryCommandHandler

class InventoryCommandHandler: CommandHandler {
    func handle(command: Command) throws {
        switch command {
        case let add as AddItemCommand: handle(command: add)
        case let remove as RemoveItemCommand: handle(command: remove)
        case let other as SomeOtherCommand: handle(command: other)
        default: break
        }
    }

    private func handle(command: AddItemCommand) {
        // do something
    }

    private func handle(command: RemoveItemCommand) {
        // do something
    }

    private func handle(command: SomeOtherCommand) {
        // do something
    }
}

答案 1 :(得分:1)

尝试实现可以​​使用当前解决方案处理多个命令的命令处理程序的问题是

你的协议定义了一个函数handle(command:),但你在InventoryCommandHandler中声明了三个 - 即使你拿走了当前的'协议一致性'错误也会引发错误,因为你实际上是在编写相同的方法在InvertoryCommandHandler三次。尽管AddItemCommandRemoveItemCommandSomeOtherCommand可能符合相同的协议(Command),但编译器找出差异的方式太过模糊,因为它会查看这三者基本上是相同的功能。

推荐的方法是为InventoryCommandHandler协议中的每个命令定义一个函数。

protocol CommandHandler
{
    func handle(command: AddItemCommand) throws
    func handle(command: RemoveItemCommand) throws
    func handle(command: SomeOtherCommand) throws

    //add more as more commands made
}

您的问题有很多解决方案,而这只是其中之一。