如果用默认值(或垃圾值)实例化枚举不是什么大事
enum MessageType {
case audio(String)
case photo
case text
}
protocol SneakyEquatableMessage {
func equals(message: MessageType) -> Bool
}
extension MessageType: SneakyEquatableMessage {
func equals(message: MessageType) -> Bool {
switch (self, message) {
case (.audio(_), .audio(_)),
(.photo, .photo),
(.text, .text):
return true
default:
return false
}
}
}
class Handler {
let allowed: [MessageType]
init(_ allowed: [MessageType]) { self.allowed = allowed }
func canHandle(_ messageType: MessageType) -> Bool {
return allowed.contains { $0.equals(message: messageType) }
}
}
基本用途
let handler = Handler([.audio(""), .photo])
print(handler.canHandle(.text)) // Prints false
print(handler.canHandle(.audio("abc")) //Prints true
默认(或垃圾)值不现实
在这种情况下,这一特定部分更为具体,但
最终,从Swift 4开始,您将以某种方式分解您的枚举。
所以我的建议是:
依赖项注入
的
工厂模式
在…内
Handler
。这非常干净地解决了您的所有问题,而无需触摸处理程序或选项中的开关。
enum DisassembledMessage {
case audio
case photo
case text
}
protocol MessageTypeFactory {
func disassemble(message: MessageType) -> DisassembledMessage
func disassemble(messages: [MessageType]) -> [DisassembledMessage]
}
class Handler {
let allowed: [MessageType]
let factory: MessageTypeFactory
init(allowed: [MessageType], with factory: MessageTypeFactory) {
self.allowed = allowed
self.factory = factory
}
func canHandle(_ messageType: DisassembledMessage) -> Bool {
return factory
.disassemble(messages: allowed)
.contains { $0 == messageType }
}
}
基本用途
let audioValue: Audio = //...
let audioMessage = MessageType.audio(audioValue)
let factory: MessageTypeFactory = //...
let handler = Handler(allowed: [audioMessage, .photo], with: factory)
print(handler.canHandle(.text)) // Prints false
print(handler.canHandle(factory.disassemble(message: audioMessage))) //Prints true
你可能会问:等等。。。您刚刚创建了另一个枚举(这只是一个示例,您可以将其转换为该协议中所需的任何内容)。我说:你使用的枚举来自一个库。。。请参见我的笔记部分。此外,您现在可以在任何需要将库类型分解为其他类型的地方使用该工厂,包括内部
处理程序
。你可以很容易地扩展协议
MessageTypeFactory
将枚举转换为您创建的其他类型(希望是行为),基本上只需在需要时与库类型保持距离即可。我希望这有助于澄清我的意思!我甚至不认为你应该
MessageType
在你的课堂上。您应该存储自己的类型,它是
消息类型
喜欢
DisassembledType
。
我希望这有帮助!
注释
有几件事:
-
真的很抱歉,你的灵魂属于图书馆。
-
使用适配器模式。
Clean C++
是你
可以了解它。不要用以下代码之一污染您的整个代码库
他们的类型!这只是一个提示。
-
我知道你说过你不想用开关。。。但您正在使用枚举。。。至少它在枚举中!
-
使用您自己的类型!(我是这么说的吗?)
-
使用适配器模式!(停下来。)