第28條:通過協議提供匿名物件

weixin_34402408發表於2018-09-23

協議定義了一系列方法,遵從了此協議的物件應該實現它們,這樣,我們可以用協議把自己所寫的API之中的實現細節隱藏起來,將返回的物件設計為遵從此協議的純id型別。這樣,想隱藏的類名就不會出現在API中了。

協議可在某種程度上提供匿名型別。具體的物件型別可以淡化成遵從某協議的id型別,協議裡規定了物件所應實現的方法。

使用匿名物件來隱藏型別名稱(或類名)

如果具體型別不重要,重要的是物件能夠響應(定義在協議裡的)特定方法,那麼可以使用匿名物件來表示。

// 協議檔案
#import <Foundation/Foundation.h>

@protocol EOCDatabaseConnection <NSObject>

- (void)connect;

- (void)disConnect;

- (BOOL)isConnect;

@end

// 遵循協議的類 標頭檔案
#import <Foundation/Foundation.h>
#import "EOCDatabaseConnection.h"

@interface EOCDBConnection : NSObject<EOCDatabaseConnection>

@end

// 實現檔案
#import "EOCDBConnection.h"

@implementation EOCDBConnection

- (void)connect
{
    NSLog(@"connect");
}

- (void)disConnect
{
    NSLog(@"disConnect");
}

- (BOOL)isConnect
{
    return YES;
}

@end

// 提供匿名函式 標頭檔案
#import <Foundation/Foundation.h>
@protocol EOCDatabaseConnection;

@interface EOCDatabaseManager : NSObject

+ (id)shareInstance;

- (id<EOCDatabaseConnection>)connectionWithIdentifier:(NSString *)identifier;

@end

// 實現檔案
#import "EOCDatabaseManager.h"
#import "EOCDBConnection.h"

@implementation EOCDatabaseManager

+ (id)shareInstance
{
    static dispatch_once_t predicate;
    static EOCDatabaseManager *sharedManager;
    dispatch_once(&predicate, ^{
        sharedManager = [[EOCDatabaseManager alloc] init];
    });
    return sharedManager;
}

- (id<EOCDatabaseConnection>)connectionWithIdentifier:(NSString *)identifier
{
    if ([identifier isEqualToString:@"test"]) {
        EOCDBConnection *connection = [[EOCDBConnection alloc] init];
        return connection;
    }
    return nil;
}

@end

// 測試例子:
EOCDatabaseManager *manager = [EOCDatabaseManager shareInstance];
id<EOCDatabaseConnection> connect = [manager connectionWithIdentifier:@"test"];
[connect connect];

相關文章