Objective C 狀態模式

 狀態模式(State),當一個對象的內在狀態改變時允許改變其行爲,這個對象看起來像是改變了其類。

   其實,狀態模式主要解決的是當控制一個對象狀態轉換的條件表達式過於複雜的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。說白了,目的就是爲了消除龐大的條件分支語句。

   這次想通過一個具體的例子,和大家一起學習狀態模式。例子的內容是一天不同時間段內,不同的狀態。時間是不同狀態之間的分割點。

   好的,下面還是先給出這個例子的類結構圖。

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

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

  • Work類接口

1
2
3
4
5
6
7
8
9
10
11
#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類實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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類接口

1
2
3
4
5
6
#import <Foundation/Foundation.h>
                              
@class Work;
@interface State:NSObject
-(void)WriteProgram:(Work*)w;
@end
  • State類實現

1
2
3
4
5
6
7
8
9
#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類實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#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類接口

1
2
3
4
#import "State.h"
                       
@interface NoonState:State
@end
  • NoonState類實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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類接口

1
2
3
4
#import "State.h"
                   
@interface AfternoonState :State
@end
  • AfternoonState類實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#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類接口

1
2
3
4
#import "State.h"
               
@interface EveningState:State
@end
  • EveningState類實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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類接口

1
2
3
4
#import "State.h"
            
@interface SleepingState :State
@end
  • SleepingState類實現

1
2
3
4
5
6
7
8
9
#import "SleepingState.h"
#import "Work.h"
          
@implementation SleepingState
          
-(void)WriteProgram:(Work *)w{
    NSLog(@"當前時間:%f點不行了,睡着了", [w Hour]);
}
@end
  • RestState類接口

1
2
3
4
#import "State.h"
        
@interface RestState:State
@end
  • RestState類實現

1
2
3
4
5
6
7
8
9
#import "RestState.h"
#import "Work.h"
       
@implementation RestState
       
-(void)WriteProgram:(Work *)w{
   NSLog(@"當前時間:%f點下班回家了", [w Hour]);
}
@end
  • Main方法調用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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的子類之間,來減少相互間的依賴。當一個對象的行爲取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行爲時,就可以考慮使用狀態模式了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章