MyClass
给定一个通过类与 API/Datalayer/external-something 通信的 Objective-C 类Connection
,MyClass
应该(取决于周围的拱门)Connection
在构造函数中接收和实例,或者Connection
应该将实例传递给每个需要联系。这种方式MyClass
可以封装应用程序逻辑并且保持对连接细节的无知。
MyClass
要在不同的外部组件中重用逻辑或进行单元测试MyClass
,使用协议 ( ConnectionProtocol
) 而不是类是正确的Connection
。这样,不同的类(比如 ConnectionHttp、ConnnectionAPI2、ConnectionTestingEmulateProxyIssue 等)MyClass
只要实现ConnectionProtocol
.
现在,假设开发人员有一段代码在 , 中重复MyClass
,MyOtherClass
并执行一系列操作ConnectionProtocol
。这违反了DRY原则,因此是不可接受的。
由于
MyClass
、MyOtherClass
和 不共享公共基类(NSObject 除外),因此开发人员不能简单地将功能合并到基类中。添加一个方法再次
ConnectionProtocol
违反DRY,因为需要在ConnectionProtocol
.使该方法成为
@optional
成员ConnectionProtocol
仍然不起作用,因为- 该方法经常使用,并且需要在每个实现中实现,并且
- 方法逻辑特定于应用程序,而不是违反SoC的连接。
开发人员考虑向 NSObject 添加一个类别,该类别检查传递的对象是否实现协议
ConnectionProtocol
,然后执行所需的操作。这有缺点:- NSObject 的方法空间被使用该类别的文件中的所有对象污染,
- 错误调用类别方法的错误在运行时被捕获,并且开发人员出于某种原因选择了强类型语言
ConnectionProtocol
使用类别进行扩展。这不违反 DRY 原则并尊重 SoC。然而,它确实违反了 Objective-C 规范。@implementation id< ConnectionProtocol > (AppLogicMethods) -(void)specialMethod:(NSObject*)myParam { // Do Stuff } @end