設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。毫無疑問,設計模式於己於他人於系統都是多贏的;設計模式使代碼編制真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構一樣。
生活中大家一定遇到這樣的情況了:比如說我要買一包紙,不妨就是心相印的吧,那一般人的話我應該不是去心相印的工廠裏面直接去買吧,而是我們在心相印專賣店或者什麼超市啊,這些地方購買,這些地方實際上就是心相印紙的代理。這其實和我們OO中的代理模式是很相似的。
當對象A發生了一些行爲,想告知對象B(讓對象B成爲對象A的代理對象)
對象B想監聽對象A的一些行爲(讓對象B成爲對象A的代理對象)
當對象A無法處理某些行爲的時候,想讓對象B幫忙處理(讓對象B成爲對象A的代理對象)
案例:
有一個嬰兒,他本身不會自己吃飯和洗澡等等一些事情,於是嬰兒就請了一個保姆,於是嬰兒和保姆之間商定了一個協議,協議中寫明瞭保姆需要做什麼事情,而保姆就是這個代理人,即:嬰兒和保姆之間有個協議,保姆遵守該協議,於是保姆就需要實現該協議中的條款成爲代理人
代碼實現
Baby.h
#import <Foundation/Foundation.h>
//1.聲明嬰兒是一個類
@class Baby;
//2.聲明代理,寫代理要幫嬰兒做的事,將嬰兒傳給代理,注意代理格式
@protocol BabyDelegate <NSObject>
//喂嬰兒吃飯
- (void)babyEat:(Baby *)baby;
//哄嬰兒睡覺
- (void)babySleep:(Baby *)baby;
@end
@interface Baby : NSObject
@property (nonatomic, assign) NSInteger hurgryValue;
@property (nonatomic, assign) NSInteger sleepValue;
//3.將代理作爲屬性,類型限定代理遵守協議
@property (nonatomic, assign) id <BabyDelegate> delegate;
//4.聲明方法,方法裏調用代理,調用代理實現的協議方法,讓代理幫嬰兒吃飯,睡覺
//嬰兒餓了要吃飯
- (void)hurgry;
//嬰兒醒了要睡覺
- (void)wake;
@end
Baby.m
#import "Baby.h"
#import "Nurse.h"
@implementation Baby
//5.實現調用代理者的方法
- (void)hurgry{
// 6.判斷代理是否實現了協議中的方法
if ([self.delegate respondsToSelector:@selector(babyEat:)]) {
//7.如果代理實現了協議中的方法,就調用
[self.delegate babyEat:self];
}
}
- (void)wake{
if ([self.delegate respondsToSelector:@selector(babySleep:)]) {
[self.delegate babySleep:self];
}
}
- (void)dealloc
{
NSLog(@"%s",__func__);
}
@end
Nurse.h
#import <Foundation/Foundation.h>
//8.導入代理
@protocol BabyDelegate ;
//9.遵守代理
@interface Nurse : NSObject <BabyDelegate>
@end
Nurse.m
#import "nurse.h"
#import "Baby.h"
@implementation Nurse
//10.實現協議中的方法,(喂嬰兒,讓嬰兒吃飯,拿到嬰兒才能給嬰兒做事)
- (void)babyEat:(Baby *)baby{
baby.hurgryValue += 10;
NSLog(@"喂嬰兒吃飯!飢餓值:%lu", baby.hurgryValue);
}
- (void)babySleep:(Baby *)baby{
baby.sleepValue += 5;
NSLog(@"搖嬰兒睡覺!疲勞值:%lu", baby.sleepValue);
}
- (void)dealloc
{
NSLog(@"%s",__func__);
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Baby.h"
#import "Nurse.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//11.創建所需對象
Baby *b = [[Baby alloc]init];
Nurse *n = [[Nurse alloc]init];
//12.將代理對象作爲接受代理者的代理
//(讓保姆作爲嬰兒的代理)
b.delegate = n;
//設定嬰兒初始飢餓值,疲勞值
b.hurgryValue = -5;
b.sleepValue = -5;
//13.接受代理者調用代理者的方法
//(嬰兒餓了,醒了,需要吃飯和哄一鬨)
[b hurgry];
[b wake];
}
return 0;
}