Swift协议如何封装属性:仅对实现者可见而不暴露给使用者
Swift协议中封装实现细节的解决方案(Command模式场景)
要解决协议中属性对使用者隐藏、仅对实现类和协议扩展可见的问题,可以通过拆分协议+访问控制的方式实现,核心是把需要隐藏的实现细节放到一个内部协议中,对外只暴露包含必要接口的公开协议。
具体实现步骤
- 定义对外公开的核心协议
只保留使用者需要调用的方法,不包含任何实现细节属性:
protocol Command { func execute() func undo() }
- 定义内部协议封装实现细节
创建一个fileprivate(或internal,根据模块需求调整)的协议,包含需要在实现类和扩展中访问的属性:
fileprivate protocol CommandInternal { var target: CommandTarget { get } var savedState: Int? { get set } }
- 让具体命令类同时遵守两个协议
具体的命令类需要同时实现公开协议和内部协议,既能对外提供接口,又能在内部访问所需属性:
class OneCommand: Command, CommandInternal { let target: CommandTarget var savedState: Int? init(target: CommandTarget) { self.target = target } func execute() { savedState = target.number target.number = 1 } }
- 基于内部协议扩展实现通用逻辑
针对CommandInternal协议扩展实现undo方法,让所有遵守该内部协议的类都能复用逻辑,同时不会对外暴露属性:
extension Command where Self: CommandInternal { func undo() { guard let savedState else { return } target.number = savedState } }
效果说明
- 协议使用者仅能看到
Command协议的execute和undo方法,完全接触不到target和savedState这些实现细节; - 具体命令类和协议扩展可以正常访问内部协议的属性,实现通用逻辑的复用;
- 如果是在模块内使用,可将
CommandInternal设为internal,保证模块内可见、模块外不可见。
内容的提问来源于stack exchange,提问作者Khawer K
相关产品推荐
相关产品推荐

