解釋器模式
? ? ? ?在我們給定一個(gè)語(yǔ)言,并定義它的語(yǔ)法和一個(gè)解釋器,這個(gè)解釋器用來(lái)標(biāo)識(shí)語(yǔ)言中的句子,就是所謂的解釋器模式。例如我們做一些字符串的替換,或者進(jìn)行一些密文的解密,像特定的字符替換頻率足夠高的話,那么可以使用這種解釋器模式來(lái)解決這種問(wèn)題。

? ? ? ?圖中我們定義了抽象解釋器類Expression,聲明一個(gè)抽象的解釋操作。TerminalExpression是繼承抽象表達(dá)式的終結(jié)表達(dá)式,例子中是最后將所有字符轉(zhuǎn)換成小寫(xiě)字符并輸出,定義的NoterminalExpression是將"*"的符號(hào)替換成"@"符號(hào),也就可以理解為這個(gè)類是處理非終結(jié)符解釋器。我們使用這種模式更多的是對(duì)場(chǎng)景的具體使用,如果要解釋的內(nèi)容很多的話,需要?jiǎng)?chuàng)建很多的非終結(jié)符解釋器類,易引起類的膨脹,一些復(fù)雜的文法解釋會(huì)比較難以維護(hù)。使用這種模式可以很好的進(jìn)行解釋擴(kuò)展,只需新增解釋器類,在一些簡(jiǎn)單的文法上比較容易實(shí)現(xiàn)。
? ? ? ?TerminalExpression的實(shí)現(xiàn)
- (NSString *)interpretStr:(NSString *)string
{
return [string lowercaseString];
}
? ? ? ?NoterminalExpression的實(shí)現(xiàn)
- (NSString *)interpretStr:(NSString *)string
{
return [string stringByReplacingOccurrencesOfString:@"*" withString:@"@"];
}
本節(jié)工程示例
迭代器模式
? ? ? ?迭代器模式主要用于順序訪問(wèn)集合對(duì)象的元素,不需要知道集合對(duì)象中的底層表示。將數(shù)據(jù)存儲(chǔ)和遍歷的職責(zé)分離,增加新的迭代器和數(shù)據(jù)都很方便,無(wú)須修改原有代碼,我們也可以自己定義數(shù)據(jù)的遍歷方式。

? ? ? ?圖中我們定義了兩個(gè)抽象類,迭代器抽象類Iterator定義了遍歷的方式,容器抽象類Container定義了獲取迭代器的接口,具體的實(shí)現(xiàn)由FruitsIterator類來(lái)完成。這個(gè)例子我們?cè)谕獠拷o容器類進(jìn)行的賦值,我們可以給定內(nèi)部設(shè)置成集合類,這樣就無(wú)須暴露它的內(nèi)部表示,在迭代器類中我們可以添加方法來(lái)提供多種遍歷方式。在使用迭代器模式的時(shí)候,我們需要增加新的迭代的話,不僅要增加聚合類,也要添加相應(yīng)的迭代器類,這樣會(huì)使類的個(gè)數(shù)成對(duì)的增加,一定程度上增加的系統(tǒng)的復(fù)雜性。
? ? ? ?FruitsIterator的實(shí)現(xiàn)
- (instancetype)initWithFruits:(NSArray *)fruits
{
if (self = [super init]) {
_fruits = fruits;
_index = 0;
}
return self;
}
- (NSString *)first;
{
return self.fruits.firstObject;
}
- (NSString *)next;
{
if (self.index + 1 < self.fruits.count) {
self.index ++;
return self.fruits[self.index];
}
return nil;
}
- (NSString *)current;
{
if (self.index < self.fruits.count) {
return self.fruits[self.index];
}
return nil;
}
- (BOOL)hasNext;
{
if (self.index + 1 < self.fruits.count) {
return YES;
}
return NO;
}
- (BOOL)isFirst;
{
if (self.index == 0) {
return YES;
}
return NO;
}
- (BOOL)isLast;
{
if (self.index == self.fruits.count - 1) {
return YES;
}
return NO;
}
本節(jié)工程示例
命令模式
? ? ? ?命令模式的定義是將請(qǐng)求封裝成一個(gè)對(duì)象,從而可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化,對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷的操作。
命令模式類圖:

如圖定義了抽象的Receiver(接收者角色)和Command(命令角色),各自有自己的實(shí)際具體實(shí)現(xiàn)接收操作和命令操作,Invoker是命令的請(qǐng)求者,也是命令模式中的最重要角色,這個(gè)角色對(duì)各個(gè)命令進(jìn)行控制。
Command1的實(shí)現(xiàn)
- (instancetype)initWithReceiver:(Receiver *)receiver
{
if (self = [super init]) {
_receiver = receiver;
}
return self;
}
- (void)execute
{
[self.receiver doSomething];
}
本節(jié)工程示例
狀態(tài)模式
狀態(tài)模式是允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為,對(duì)象看起來(lái)似乎修改了它的類。在一些情況下,一個(gè)對(duì)象的行為取決于其狀態(tài)變化的屬性,當(dāng)這個(gè)對(duì)象和外部的事件產(chǎn)生互動(dòng)時(shí),它的內(nèi)部狀態(tài)會(huì)改變,同時(shí)使得系統(tǒng)的行為也發(fā)生變化。
狀態(tài)模式類圖:

圖中定義了抽象狀態(tài)類State,擁有開(kāi)始和停止?fàn)顟B(tài),Context所持有的狀態(tài)在兩種狀態(tài)的改變下,它會(huì)產(chǎn)生的行為變化。使用這種方式我們可以靈活的添加新的狀態(tài)和行為,也可以讓多個(gè)環(huán)境對(duì)象共享一個(gè)狀態(tài)對(duì)象,從而減少系統(tǒng)中的個(gè)數(shù),但使用狀態(tài)模式容易增加系統(tǒng)類和對(duì)象的個(gè)數(shù)。
其中StartState的實(shí)現(xiàn)
- (void)doSomethingWithContext:(Context *)context;
{
NSLog(@"運(yùn)動(dòng)狀態(tài)");
[context setState:self];
}
其中StopState的實(shí)現(xiàn)
- (void)doSomethingWithContext:(Context *)context;
{
NSLog(@"停止?fàn)顟B(tài)");
[context setState:self];
}
本節(jié)工程示例
備忘錄模式
備忘錄模式主要用來(lái)存儲(chǔ)另外一個(gè)對(duì)象內(nèi)部狀態(tài)的快照對(duì)象。用意是在不破壞封裝的條件下,將一個(gè)對(duì)象的狀態(tài)捕捉住,并外部化,存儲(chǔ)起來(lái),從而可以在將來(lái)合適的時(shí)候把這個(gè)對(duì)象還原到存儲(chǔ)起來(lái)的狀態(tài)。
備忘錄模式類圖:

備忘錄模式中有三個(gè)角色,一個(gè)備忘錄角色(Memento)它主要用來(lái)存儲(chǔ)備忘發(fā)起者角色的內(nèi)部狀態(tài),備忘發(fā)起角色(Originator)創(chuàng)建一個(gè)備忘錄,用來(lái)記錄此刻它的內(nèi)部狀態(tài),在需要的時(shí)候使用備忘錄恢復(fù)內(nèi)部狀態(tài),還有個(gè)備忘錄管理者角色(Caretaker),它負(fù)責(zé)保存好備忘錄,它不能對(duì)備忘錄的內(nèi)容進(jìn)行操作或者檢查。使用這種模式給用戶提供了一種可以恢復(fù)狀態(tài)的機(jī)制,使用戶能夠比較方便地回到歷史的狀態(tài),同時(shí)實(shí)現(xiàn)了信息額封裝,用戶不需要關(guān)心狀態(tài)的保護(hù)細(xì)節(jié)。保存狀態(tài)容易消耗資源,使類的成員變量過(guò)多。
其中Originator的實(shí)現(xiàn)
- (Memento *)saveStateToMemento
{
return [[Memento alloc] initWithState:_state];
}
- (void)setState:(NSInteger)state
{
_state = state;
}
- (NSInteger)getState
{
return _state;
}
- (void)getStateFromMemento:(Memento *)memento
{
_state = [memento getState];
}
本節(jié)工程示例
模板方法模式
模板模式是定義一個(gè)抽象類,它公開(kāi)定義了執(zhí)行它的方法的方式/模板,它的子類可以按需要重新寫(xiě)方法實(shí)現(xiàn),但調(diào)用將以抽象類中的定義方式進(jìn)行。
享元模式類圖:

如圖定義了一個(gè)出去旅游類,定義了一些流程模板,打包、出游、游玩、返回這些旅游過(guò)程,其中我們使用了三套方案出行、汽車、飛機(jī)和火車,它們的交通方式都不一樣,然后各自實(shí)現(xiàn)相應(yīng)的步驟。
其中Travel的實(shí)現(xiàn)部分
- (void)package
{
NSLog(@"打包");
}
- (void)goToPlace
{
NSLog(@"出發(fā)");
}
- (void)play
{
NSLog(@"游玩");
}
- (void)backHome
{
NSLog(@"回家");
}
- (void)travel
{
[self package];
[self goToPlace];
[self play];
[self backHome];
}
本節(jié)工程示例