什么状态模式?就是允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
举个栗子!你有一个类GumballMachine你在它里面定义了一个枚举State,然后给State 设置了四种状态A、B、C、D。之后在你的Machine.M类中可能会这么做if(State==A){
-(void)insertQuarter;
-(void)ejectQuarter;
state= B; //大致是执行完2个方法以后改变状态为B
}else if(state==B){
-(void)turnCrank;
state = C;
}
一次类推。。。 以后可能还会出现更多的状态。
这时我们可以尝试一下改变!把状态执行的方法都放到一个协议里(接口)
@protocol custumState <NSObject>//状态映射为具体对象、可选实现的方法@optional
@required // 必须实现的方法
-(void)insertQuarter;
-(void)ejectQuarter;
-(void)turnCrank;
-(void)dispense;
@end
这时我们把枚举类型的各个状态分别对应着一个类,而这个类必须实现我们上面的这个接口,而这个类里执行的方法就是我们原来state==A下面执行的方法,例如A 对应 类MySoldState , 其实通过栗子可以看出,状态类里方法的实现和状态的切换其实是通过GumballMachine 类来实现的。
#import "custumState.h"
#import "GumballMachine.h"
@interface MySoldState : NSObject<custumState>
-(instancetype)initWithMachine:(id)gumballMachine; //这里参数用id 而不用GumballMachine* 是因为GumballMachine类里会含有MySoldState的对象,为了避免循环引用所以用id.
@end
它的实现:
#import "MySoldState.h"
@interface MySoldState()
@property(nonatomic,strong)GumballMachine * gbm;
@end
@implementation MySoldState
-(instancetype)initWithMachine:(id)gumballMachine{
self= [super init];
if (self) {
self.gbm = gumballMachine;
}
return self;
}
- (void)dispense {
[self.gbm releaseBall];
if (self.gbm.count>0) {
[self.gbm setState:self.gbm.noQuarterState];
}
else{
[self.gbm setState:self.gbm.soldOutState];
}
}
- (void)ejectQuarter {
NSLog(@"noThing");
}
- (void)insertQuarter {
NSLog(@"you inserted a quarter");
}
- (void)turnCrank {
NSLog(@"noThing");
}
主要的类
GumballMachine.h
#import "custumState.h"
#import "MySoldState.h" //举例子用的其中一个 下面的三个和这个一样
#import "SoldOutState.h"
#import "NoQuarterState.h"
#import "HasQuarterStates.h"
@interface GumballMachine : NSObject
@property(nonatomic) id<custumState> state; //相当于枚举类型的 变量
@property(nonatomic,strong) id<custumState> soldState; //实现协议的对象 相当于枚举类型里的具体类型
@property(nonatomic,strong) id<custumState> soldOutState;
@property(nonatomic,strong) id<custumState> noQuarterState;
@property(nonatomic,strong) id<custumState> hasQuarterStates;
@property(nonatomic)int count;
-(void)setState:(id<custumState>)state; //用来实现状态的转换
-(void)releaseBall;
-(instancetype)initWithQuarter:(int)numberGumballs; //用于初始化此类
@end
GumballMachine.m
@implementation GumballMachine
-(instancetype)initWithQuarter:(int)numberGumballs{
self = [super init];
if (self) {
_soldOutState = [[SoldOutState alloc] initWithMachine:self]; //初始化状态类
_noQuarterState = [[NoQuarterState alloc] initWithMachine:self];
_hasQuarterStates = [[HasQuarterStates alloc] initWithMachine:self];
_soldState = [[MySoldState alloc] initWithMachine:self];
_count = numberGumballs;
_state = _soldOutState; //把状态对象 赋予相应的实际值
if (_count>0) {
_state = _noQuarterState;
}
}
return self;
}
//投进5分钱
-(void)insertQuarter{
[_state insertQuarter];
}
//退回5分钱
-(void)ejectQuarter{
[_state ejectQuarter];
}
//转动曲柄
-(void)turnCrank{
[_state turnCrank];
[_state dispense];
}
-(void)setState:(id<custumState>)state{
_state = state;
}
-(void)releaseBall{
NSLog(@"a gumball comes rolling out the solt..");
if (_count!=0) {
_count= _count-1;
}
}
@end