設(shè)計(jì)模式(四)----解釋器模式、迭代器模式、命令模式、狀態(tài)模式、備忘錄模式、模板方法模式

解釋器模式

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

解釋器模式類圖.png

? ? ? ?圖中我們定義了抽象解釋器類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ù)的遍歷方式。

迭代器模式類圖.png

? ? ? ?圖中我們定義了兩個(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)求日志,以及支持可撤銷的操作。

命令模式類圖:

命令模式類圖.png

如圖定義了抽象的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)模式類圖.png

圖中定義了抽象狀態(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)。

備忘錄模式類圖:

備忘錄模式類圖.png

備忘錄模式中有三個(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)行。

享元模式類圖:

模板方法模式類圖.png

如圖定義了一個(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é)工程示例

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,083評(píng)論 1 15
  • 1 場(chǎng)景問(wèn)題# 1.1 開(kāi)發(fā)仿真系統(tǒng)## 考慮這樣一個(gè)仿真應(yīng)用,功能是:模擬運(yùn)行針對(duì)某個(gè)具體問(wèn)題的多個(gè)解決方案,記...
    七寸知架構(gòu)閱讀 2,248評(píng)論 1 50
  • 當(dāng)你踏上南方的土地 在異鄉(xiāng)的街頭沐浴著春風(fēng) 你說(shuō)你常常想起小時(shí)候 熟悉的故園里 柳綠花紅 我依舊堅(jiān)守在北方的曠野 ...
    兔子的菜園閱讀 438評(píng)論 7 17
  • 文/蘭舟醬 蛤蟆是一種奇妙的動(dòng)物。蛤蟆的口腔中沒(méi)有銳利的牙齒,他不咬人,僅于無(wú)聲時(shí),冷不丁的,黏嗒嗒的,帶著...
    蘭舟醬閱讀 766評(píng)論 0 2
  • 你已經(jīng)是大人了 你沒(méi)有能力討好 你已經(jīng)沒(méi)有靈魂了 在乎那些有用嗎 連生命都沒(méi)什么用了 但是你身上還有重?fù)?dān) 所以,你才活著
    心不塵封閱讀 169評(píng)論 0 0

友情鏈接更多精彩內(nèi)容