亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS App的設計模式開發中對State狀態模式的運用

2020-07-26 03:24:06
字體:
來源:轉載
供稿:網友

1.概述

在軟件開發過程中,應用程序可能會根據不同的情況作出不同的處理。最直接的解決方案是將這些所有可能發生的情況全都考慮到。然后使用if... ellse語句來做狀態判斷來進行不同情況的處理。但是對復雜狀態的判斷就顯得“力不從心了”。隨著增加新的狀態或者修改一個狀體(if else(或switch case)語句的增多或者修改)可能會引起很大的修改,而程序的可讀性,擴展性也會變得很弱。維護也會很麻煩。那么我就考慮只修改自身狀態的模式。

例子1:按鈕來控制一個電梯的狀態,一個電梯開們,關門,停,運行。每一種狀態改變,都有可能要根據其他狀態來更新處理。例如,開門狀體,你不能在運行的時候開門,而是在電梯定下后才能開門。

例子2:我們給一部手機打電話,就可能出現這幾種情況:用戶開機,用戶關機,用戶欠費停機,用戶消戶等。 所以當我們撥打這個號碼的時候:系統就要判斷,該用戶是否在開機且不忙狀態,又或者是關機,欠費等狀態。但不管是那種狀態我們都應給出對應的處理操作。

2.問題

對象如何在每一種狀態下表現出不同的行為?
3.解決方案

狀態模式:允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。

在很多情況下,一個對象的行為取決于一個或多個動態變化的屬性,這樣的屬性叫做狀態,這樣的對象叫做有狀態的(stateful)對象,這樣的對象狀態是從事先定義好的一系列值中取出的。當一個這樣的對象與外部事件產生互動時,其內部狀態就會改變,從而使得系統的行為也隨之發生變化。

4.示例
先給出這個例子的類結構圖。

2016330155229600.jpg (557×279)

上面的類結構圖并不復雜,首先是抽象出一個狀態的父類,通過工作類對時間點的設置來切換不同的狀態。

邏輯結構并不復雜,還是給出簡易的代碼,大家可以慢慢體會一下。

注意:本文所有代碼均在ARC環境下編譯通過。

Work類接口

復制代碼 代碼如下:

#import <Foundation/Foundation.h>

@class State;
@interface Work :NSObject{
    State *current;
}
@property double Hour;
@property BOOL TaskFinished;
-(void)SetState:(State*)s;
-(void)WriteProgram;
@end


Work類實現
復制代碼 代碼如下:

#import "Work.h"
#import "State.h"
#import "ForenoonState.h"

@implementation Work
@synthesize Hour =_Hour;
@synthesize TaskFinished =_TaskFinished;

-(id)init{
    if (self == [superinit]) {
        current= [[ForenoonState    alloc]init];
    }
    return self;
}
-(void)SetState:(State *)s{
    current = s;
}
-(void)WriteProgram{
    [current WriteProgram:self];
}
@end


State類接口
復制代碼 代碼如下:

#import <Foundation/Foundation.h>

@class Work;
@interface State:NSObject
-(void)WriteProgram:(Work*)w;
@end


State類實現
復制代碼 代碼如下:

#import "State.h"
#import "Work.h"

@implementation State

-(void)WriteProgram:(Work *)w{
    NSLog(@"當前時間:%f點下班回家了",[w    Hour]);
}
@end


ForenoonState類接口
復制代碼 代碼如下:

#import    "State.h"

@interface    ForenoonState :State
@end


ForenoonState類實現
復制代碼 代碼如下:

#import "ForenoonState.h"
#import "Work.h"
#import "NoonState.h"

@implementation ForenoonState

-(void)WriteProgram:(Work *)w{
    if ([w Hour] < 12) {
        NSLog(@"當前時間:%f點上午工作,精神百倍", [w Hour]);
    }
    else {
        [w SetState:[NoonState new]];
        [w WriteProgram];
    }
}
@end


NoonState類接口
復制代碼 代碼如下:

#import "State.h"

@interface NoonState:State
@end


NoonState類實現
復制代碼 代碼如下:

#import "NoonState.h"
#import "Work.h"
#import "AfternoonState.h"

@implementation NoonState

-(void)WriteProgram:(Work *)w{
    if([w Hour] <13)
        NSLog(@"當前時間:%f點餓了,午飯;犯困,午休",[w Hour]);
    else {
        [w SetState:[[AfternoonState    alloc]init]];
        [w WriteProgram];
    }
}
@end


AfternoonState類接口
復制代碼 代碼如下:

#import "State.h"

@interface AfternoonState :State
@end


AfternoonState類實現
復制代碼 代碼如下:

#import "AfternoonState.h"
#import "Work.h"
#import "EveningState.h"

@implementation AfternoonState

-(void)WriteProgram:(Work *)w{
    if ([w Hour] <17) {
        NSLog(@"當前時間:%f點下午狀態還不錯,繼續努力", [w Hour]);
    }
    else {
        [w SetState:[[EveningState alloc]init]];
        [w WriteProgram];
    }
}
@end


EveningState類接口
復制代碼 代碼如下:

#import "State.h"

@interface EveningState:State
@end


EveningState類實現
復制代碼 代碼如下:

#import "EveningState.h"
#import "Work.h"
#import "RestState.h"
#import "SleepingState.h"

@implementation EveningState

-(void)WriteProgram:(Work *)w{
    if ([w TaskFinished]) {
        [w SetState:[[RestState alloc]init]];
        [w WriteProgram];
    }
    else {
        if([w Hour] <21)
            NSLog(@"當前時間:%f點加班哦,疲憊之極", [w Hour]);
        else {
            [w SetState:[[SleepingState alloc]init]];
            [w WriteProgram];
        }
    }
}
@end


SleepingState類接口
復制代碼 代碼如下:

#import "State.h"

@interface SleepingState :State
@end


SleepingState類實現
復制代碼 代碼如下:

#import "SleepingState.h"
#import "Work.h"

@implementation SleepingState
-(void)WriteProgram:(Work *)w{
    NSLog(@"當前時間:%f點不行了,睡著了", [w Hour]);
}
@end


RestState類接口
復制代碼 代碼如下:

#import "RestState.h"
#import "Work.h"

@implementation RestState
-(void)WriteProgram:(Work *)w{
    NSLog(@"當前時間:%f點下班回家了", [w Hour]);
}
@end


Main方法調用
復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "Work.h"

int main (int argc,const char  *argv[])
{
    @autoreleasepool{
        Work *emergencyProjects = [[Work alloc]init];
        [emergencyProjects setHour:9];
        [emergencyProjects WriteProgram];
        [emergencyProjects setHour:10];
        [emergencyProjects WriteProgram];
        [emergencyProjects setHour:12];
        [emergencyProjects WriteProgram];
        [emergencyProjects setHour:13];
        [emergencyProjects WriteProgram];
        [emergencyProjects setHour:14];
        [emergencyProjects WriteProgram];
        [emergencyProjects setHour:17];
        [emergencyProjects WriteProgram];
        [emergencyProjects setTaskFinished:NO];
        [emergencyProjects setHour:19];
        [emergencyProjects WriteProgram];
        [emergencyProjects setHour:22];
        [emergencyProjects WriteProgram];
    }
    return 0;
}


上面是用Objective C語言實現的簡單代碼。

通過這個例子,可以看到,狀態模式通過把各種狀態轉移邏輯分布到State的子類之間,來減少相互間的依賴。當一個對象的行為取決于它的狀態,并且它必須在運行時刻根據狀態改變它的行為時,就可以考慮使用狀態模式了。
5.適用性

在下面的兩種情況下均可使用State模式:
1) • 一個對象的行為取決于它的狀態, 并且它必須在運行時刻根據狀態改變它的行為。
2) • 代碼中包含大量與對象狀態有關的條件語句:一個操作中含有龐大的多分支的條件(if else(或switch case)語句,且這些分支依賴于該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常 , 有多個操作包含這一相同的條件結構。 State模式將每一個條件分支放入一個獨立的類中。這使得你可以根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴于其他對象而獨立變化。
6.結構

2016330155313791.jpg (594×265)

7.模式的組成

環境類(Context):  定義客戶感興趣的接口。維護一個ConcreteState子類的實例,這個實例定義當前狀態。
抽象狀態類(State):  定義一個接口以封裝與Context的一個特定狀態相關的行為。
具體狀態類(ConcreteState):  每一子類實現一個與Context的一個狀態相關的行為。
8.效果

State模式有下面一些效果:
狀態模式的優點:
1 ) 它將與特定狀態相關的行為局部化,并且將不同狀態的行為分割開來: State模式將所有與一個特定的狀態相關的行為都放入一個對象中。因為所有與狀態相關的代碼都存在于某一個State子類中, 所以通過定義新的子類可以很容易的增加新的狀態和轉換。另一個方法是使用數據值定義內部狀態并且讓 Context操作來顯式地檢查這些數據。但這樣將會使整個Context的實現中遍布看起來很相似的條件if else語句或switch case語句。增加一個新的狀態可能需要改變若干個操作, 這就使得維護變得復雜了。State模式避免了這個問題, 但可能會引入另一個問題, 因為該模式將不同狀態的行為分布在多個State子類中。這就增加了子類的數目,相對于單個類的實現來說不夠緊湊。但是如果有許多狀態時這樣的分布實際上更好一些, 否則需要使用巨大的條件語句。正如很長的過程一樣,巨大的條件語句是不受歡迎的。它們形成一大整塊并且使得代碼不夠清晰,這又使得它們難以修改和擴展。 State模式提供了一個更好的方法來組織與特定狀態相關的代碼。決定狀態轉移的邏輯不在單塊的 i f或s w i t c h語句中, 而是分布在State子類之間。將每一個狀態轉換和動作封裝到一個類中,就把著眼點從執行狀態提高到整個對象的狀態。這將使代碼結構化并使其意圖更加清晰。

2) 它使得狀態轉換顯式化: 當一個對象僅以內部數據值來定義當前狀態時 , 其狀態僅表現為對一些變量的賦值,這不夠明確。為不同的狀態引入獨立的對象使得轉換變得更加明確。而且, State對象可保證Context不會發生內部狀態不一致的情況,因為從 Context的角度看,狀態轉換是原子的―只需重新綁定一個變量(即Context的State對象變量),而無需為多個變量賦值

3) State對象可被共享 如果State對象沒有實例變量―即它們表示的狀態完全以它們的類型來編碼―那么各Context對象可以共享一個State對象。當狀態以這種方式被共享時, 它們必然是沒有內部狀態, 只有行為的輕量級對象。
狀態模式的缺點:
1) 狀態模式的使用必然會增加系統類和對象的個數。
2) 狀態模式的結構與實現都較為復雜,如果使用不當將導致程序結構和代碼的混亂。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美日本精品| 国模吧一区二区三区| 国产精品白嫩初高中害羞小美女| 国产视频观看一区| 国自产精品手机在线观看视频| 蜜月aⅴ免费一区二区三区| 久久精品视频播放| 亚洲欧美日本伦理| 亚洲人成电影在线观看天堂色| 欧美黄网免费在线观看| 国产成人久久久精品一区| 欧美成人午夜影院| 欧美成在线视频| 在线日韩日本国产亚洲| 国产精品自产拍在线观看| 成人女保姆的销魂服务| 亚洲精品福利在线观看| 欧美亚洲在线观看| 色综合色综合久久综合频道88| 日韩av电影在线免费播放| 国产视频亚洲视频| 在线看片第一页欧美| 国产精品男人爽免费视频1| 久久久999精品视频| 97国产精品视频| 日韩精品黄色网| 亚洲xxxx做受欧美| 中文字幕亚洲无线码在线一区| 午夜剧场成人观在线视频免费观看| 国产精品久久久久久av福利软件| 国产成人一区二| 亚洲伦理中文字幕| 一本色道久久综合亚洲精品小说| 欧美日韩亚洲视频一区| 国产精品欧美激情在线播放| 国产精品久久久久久网站| 亚洲在线视频福利| 亚洲激情在线观看| 精品亚洲va在线va天堂资源站| 精品久久久91| 成人免费午夜电影| 国产婷婷97碰碰久久人人蜜臀| 欧美性猛交xxxx乱大交| 欧美激情高清视频| 欧美在线影院在线视频| 性日韩欧美在线视频| 日韩av三级在线观看| 国产成人亚洲综合青青| 久久亚洲精品成人| 91中文在线视频| 国产精品久久久久久一区二区| 国产精品99久久久久久久久| 日本久久亚洲电影| 久久久久久国产免费| 欧美日韩国产麻豆| 日韩大片免费观看视频播放| 日本一欧美一欧美一亚洲视频| 清纯唯美亚洲激情| 欧美日韩亚洲一区二区| 国产精品免费一区豆花| 日韩三级影视基地| 美女国内精品自产拍在线播放| 国产精品视频在线播放| 欧美理论在线观看| 久久久精品日本| 国产精品丝袜高跟| 国产精品国产自产拍高清av水多| 亚洲精品第一页| 日韩一中文字幕| 91av免费观看91av精品在线| 成人免费观看a| 亚洲午夜性刺激影院| 久久免费视频网站| 国产精品色婷婷视频| 久久久精品国产| 久久精品2019中文字幕| 国产97免费视| 日韩精品欧美激情| 欧美二区在线播放| 91av视频导航| 亚洲欧美在线播放| 日韩欧美一区视频| 亚洲美腿欧美激情另类| 欧美性猛交xxxxx水多| 97精品国产aⅴ7777| 在线观看中文字幕亚洲| 97碰碰碰免费色视频| 欧美激情亚洲综合一区| 成人国产在线激情| 欧美一级bbbbb性bbbb喷潮片| 97精品在线视频| 美女黄色丝袜一区| 日韩av一卡二卡| 国产精品久久久久久久天堂| 欧美成年人视频网站欧美| 久久久久久国产精品三级玉女聊斋| 日本精品va在线观看| 欧美日韩在线第一页| 欧美精品做受xxx性少妇| 国产aⅴ夜夜欢一区二区三区| 国产69久久精品成人| 日韩专区在线播放| 91干在线观看| 色诱女教师一区二区三区| 色综合导航网站| 欧美亚洲成人xxx| 日韩av免费观影| 丝袜亚洲另类欧美重口| 91精品国产沙发| 精品magnet| 91精品国产自产在线观看永久| 日韩美女视频中文字幕| 一区二区三区视频在线| 久久免费视频在线| 国产精品普通话| 亚洲大胆美女视频| 国产精品视频免费在线观看| 91久久久久久久一区二区| 色哟哟网站入口亚洲精品| 亚洲97在线观看| 国产精品海角社区在线观看| 成人国产精品av| 亚洲国产精品专区久久| 精品国产网站地址| 成人精品一区二区三区电影黑人| 亚洲一二在线观看| 亚洲视频第一页| 精品国产网站地址| 国产精品视频免费观看www| 91亚洲国产成人久久精品网站| 国产精品欧美日韩一区二区| 亚洲视频在线观看| 日韩欧美在线视频观看| 麻豆乱码国产一区二区三区| www.久久色.com| 亚洲最大成人在线| 日韩美女免费观看| 黄色精品一区二区| 亚洲欧美另类中文字幕| 精品中文字幕在线| 91夜夜揉人人捏人人添红杏| 2021久久精品国产99国产精品| 亚洲春色另类小说| 国产精品美女久久久久av超清| 欧美激情国产日韩精品一区18| 成人av.网址在线网站| www.亚洲男人天堂| 成人a级免费视频| 亚洲精品乱码久久久久久金桔影视| 国产精品video| 一级做a爰片久久毛片美女图片| 亚洲人成欧美中文字幕| 成人国产精品免费视频| 国产精品三级美女白浆呻吟| 欧美第一淫aaasss性| 亚洲图片欧洲图片av| 亚洲在线观看视频| 久久资源免费视频| 国产97免费视| 欧美亚洲第一区| 久久久日本电影| 亚洲成av人片在线观看香蕉| 91在线观看免费高清| 国产精品91在线观看|