欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS App的設計模式開發(fā)中對State狀態(tài)模式的運用

 更新時間:2016年03月30日 16:00:23   作者:Snow Liang  
這篇文章主要介紹了iOS App的設計模式開發(fā)中對State狀態(tài)模式的運用,示例代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下

1.概述

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

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

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

2.問題

對象如何在每一種狀態(tài)下表現(xiàn)出不同的行為?
3.解決方案

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

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

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

2016330155229600.jpg (557×279)

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

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

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

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類實現(xiàn)
復制代碼 代碼如下:

#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類實現(xiàn)
復制代碼 代碼如下:

#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類實現(xiàn)
復制代碼 代碼如下:

#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類實現(xiàn)
復制代碼 代碼如下:

#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類實現(xiàn)
復制代碼 代碼如下:

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

@implementation AfternoonState

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


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

#import "State.h"

@interface EveningState:State
@end


EveningState類實現(xiàn)
復制代碼 代碼如下:

#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類實現(xiàn)
復制代碼 代碼如下:

#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語言實現(xiàn)的簡單代碼。

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

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

2016330155313791.jpg (594×265)

7.模式的組成

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

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

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

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

相關文章

  • iOS中block的定義與使用

    iOS中block的定義與使用

    蘋果官方文檔聲明,block是objc對象。下面這篇文章主要給大家介紹了關于iOS中block的定義與使用,文中通過示例代碼介紹的非常詳細,對各位iOS開發(fā)者具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • ios中Deep Linking實例分析用法

    ios中Deep Linking實例分析用法

    本篇文章給大家分享了在IOS中Deep Linking的用法以及代碼實例,有興趣的朋友跟著學習下吧。
    2018-01-01
  • iOS App開發(fā)中通過UIDevice類獲取設備信息的方法

    iOS App開發(fā)中通過UIDevice類獲取設備信息的方法

    UIDevice最常見的用法就是用來監(jiān)測iOS設備的電量了,然后再實現(xiàn)電池狀態(tài)通知非常方便,除此之外還有傳感器等信息的獲取,這里我們就來總結一下iOS App開發(fā)中通過UIDevice類獲取設備信息的方法:
    2016-07-07
  • iOS中SQLite使用教程

    iOS中SQLite使用教程

    sqlite是嵌入式的和輕量級的sql數(shù)據(jù)庫。sqlite是由c實現(xiàn)的。廣泛用于包括瀏覽器(支持html5的大部分瀏覽器,ie除外)、ios、android以及一些便攜需求的小型web應用系統(tǒng)
    2016-03-03
  • iOS實現(xiàn)文字轉化成彩色文字圖片

    iOS實現(xiàn)文字轉化成彩色文字圖片

    這篇文章主要為大家詳細介紹了iOS文字轉化成彩色文字圖片的實現(xiàn)方法,可以實現(xiàn)不同字體,漸變的效果,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Objective-C與Swift之間的互相調用和跳轉

    Objective-C與Swift之間的互相調用和跳轉

    這篇文章主要給大家介紹了關于Objective-C與Swift之間的互相調用和跳轉的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-05-05
  • iOS UIAlertController中UITextField添加晃動效果與邊框顏色詳解

    iOS UIAlertController中UITextField添加晃動效果與邊框顏色詳解

    這篇文章主要給大家介紹了關于iOS UIAlertController中UITextField添加晃動效果與邊框顏色的相關資料,實現(xiàn)后的效果非常適合在開發(fā)中使用,文中給出了詳細的示例代碼,需要的朋友可以參考借鑒,下面隨著小編來一起看看吧。
    2017-10-10
  • iOS11和iPhoneX適配的一些坑

    iOS11和iPhoneX適配的一些坑

    前陣子項目開發(fā)忙成狗,就一直沒做iOS11的適配,直到XcodeGM版發(fā)布后,我胸有成竹的在iPhoneX上跑起項目,整個人都涼透了...下面總結一下我遇到的坑,感興趣的朋友一起看看吧
    2017-09-09
  • iOS通過攝像頭圖像識別技術分享

    iOS通過攝像頭圖像識別技術分享

    本篇文章給大家詳細講述了讓IOS開發(fā)中通過攝像頭進行圖像識別的相關技術,對此有興趣的朋友參考學習下吧。
    2018-02-02
  • iOS10適配問題收集整理

    iOS10適配問題收集整理

    本文是小編給大家收集整理些有關iOS10適配問題的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09

最新評論