不建立庞大的接口(即不建立多虚方法的类),应为各类建立专用的接口。
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
问题由来:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。
解决方案:将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。
举例来说明接口隔离原则:
这个图的意思是:类A依赖接口I中的方法1、方法2、方法3,类B是对类A依赖的实现。类C依赖接口I中的方法1、方法4、方法5,类D是对类C依赖的实现。对于类B和类D来说,虽然他们都存在着用不到的方法(也就是图中红色字体标记的方法),但由于实现了接口I,所以也必须要实现这些用不到的方法。
代码如下:
ImplementI1.h
@interface InterfaceI1 : NSObject -(void)method1; @end
ImplementI1.m
#import "InterfaceI1.h" @implementation InterfaceI1 -(void)method1 { } @end
ImplementI2.h
#import "InterfaceI1.h" @interface InterfaceI2 : InterfaceI1 -(void)method2; -(void)method3; @end
ImplementI2.m
#import "InterfaceI2.h" @implementation InterfaceI2 -(void)method2 { } -(void)method3 { } @end
ImplementI3.h
#import "InterfaceI1.h" @interface InterfaceI3 : InterfaceI1 -(void)method4; -(void)method5; @end
ImplementI3.m
#import "InterfaceI3.h" @implementation InterfaceI3 -(void)method4 { } -(void)method5 { } @end
ImplementB.h
#import "InterfaceI2.h" @interface ImplementB : InterfaceI2 @end
ImplementB.m
#import "ImplementB.h" @implementation ImplementB -(void)method1 { NSLog(@"b implement method1"); } -(void)method2 { NSLog(@"b implement method2"); } -(void)method3 { NSLog(@"b implement method3"); } @end
ImplementD.h
#import "InterfaceI3.h" @interface ImplementD : InterfaceI3 @end
ImplementD.m
#import "ImplementD.h" @implementation ImplementD -(void)method1 { NSLog(@"b implement method1"); } -(void)method4 { NSLog(@"b implement method4"); } -(void)method5 { NSLog(@"b implement method5"); } @end
A.h
@interface A : NSObject -(void)depend; @end
A.m
#import "A.h" #import "ImplementB.h" @implementation A -(void)depend { ImplementB *Ib = [[ImplementB alloc]init]; [Ib method1]; [Ib method2]; [Ib method3]; } @end
C.h
@interface C : NSObject -(void)depend:(id)aId; @end
C.m
#import "C.h" #import "ImplementD.h" @implementation C -(void)depend:(ImplementD *)aId { [aId method1]; [aId method4]; [aId method5]; } @end
AppDelegate.m
#import "AppDelegate.h" #import "A.h" #import "C.h" #import "ImplementD.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; //................................................. A *a = [[A alloc]init]; [a depend]; C *c = [[C alloc]init]; [c depend: [[ImplementD alloc]init]]; //................................................ [self.window makeKeyAndVisible]; return YES; }