一. 舉例
一般汽車發動機工作時有四種狀態,吸氣、壓縮、做功和排氣。
在運行時,不同的狀態會有不同的行為,當前的狀態機在適當的時候會過渡到下一狀態。
其實用戶在使用時根本不知道當前的狀態,也無需知道當前的狀態。用戶只需要給發動機一個初始狀態,最後得到一個停止狀態就行了。
結構圖如下:
代碼如下:
[cpp]//狀態
class State
{
public:
virtual void Operation(Work *work) {}
};
//工作
class Work
{
private:
State *m_state; //目前狀態
int m_step; //步驟
public:
Work(State *state): m_state(state), m_step(0)
{}
~Work()
{
delete m_state;
}
int GetStep()
{
return m_step;
}
void SetStep(int step)
{
m_step = step;
}
void SetState(State *state)
{
delete m_state;
m_state = state;
}
void Operation()
{
m_state->Operation(this);
}
};
//排氣狀態
class ExhaustState: public State
{
public:
void Operation(Work *work) //排氣操作
{
if(work->GetStep() == 4)
{
cout<<"Step : "<<work->GetStep()<<"排氣操作"<<endl;
}
}
};
//做功狀態
class ActState: public State
{
public:
void Operation(Work *work) //做功操作
{
if(work->GetStep() == 3)
{
cout<<"Step : "<<work->GetStep()<<"做功操作"<<endl;
}
else
{
work->SetState(new ExhaustState());
work->Operation();
}
}
};
//壓縮狀態
class CompressState: public State
{
public:
void Operation(Work *work) //壓縮操作
{
if(work->GetStep() == 2)
{
cout<<"Step : "<<work->GetStep()<<"壓縮操作"<<endl;
}
else
{
work->SetState(new ActState());
work->Operation();
}
}
};
//吸氣狀態
class InhaleState: public State
{
public:
void Operation(Work *work) //吸氣操作
{
if(work->GetStep() == 1)
{
cout<<"Step : "<<work->GetStep()<<"吸氣操作"<<endl;
}
else
{
State *p = new CompressState();
work->SetState(p);
work->Operation();
}
}
};
//測試代碼
int main()
{
State* st = new InhaleState(); //初始狀態
Work *work = new Work(st);
for(int i = 1; i < 5; ++i)
{
work->SetStep(i);
work->Operation(); //操作
}
delete work;
return 0;
}
//狀態 www.2cto.com
class State
{
public:
virtual void Operation(Work *work) {}
};
//工作
class Work
{
private:
State *m_state; //目前狀態
int m_step; //步驟
public:
Work(State *state): m_state(state), m_step(0)
{}
~Work()
{
delete m_state;
}
int GetStep()
{
return m_step;
}
void SetStep(int step)
{
m_step = step;
}
void SetState(State *state)
{
delete m_state;
m_state = state;
}
void Operation()
{
m_state->Operation(this);
}
};
//排氣狀態
class ExhaustState: public State
{
public:
void Operation(Work *work) //排氣操作
{
if(work->GetStep() == 4)
{
cout<<"Step : "<<work->GetStep()<<"排氣操作"<<endl;
}
}
};
//做功狀態
class ActState: public State
{
public:
void Operation(Work *work) //做功操作
{
if(work->GetStep() == 3)
{
cout<<"Step : "<<work->GetStep()<<"做功操作"<<endl;
}
else
{
work->SetState(new ExhaustState());
work->Operation();
}
}
};
//壓縮狀態
class CompressState: public State
{
public:
void Operation(Work *work) //壓縮操作
{
if(work->GetStep() == 2)
{
cout<<"Step : "<<work->GetStep()<<"壓縮操作"<<endl;
}
else
{
work->SetState(new ActState());
work->Operation();
}
}
};
//吸氣狀態
class InhaleState: public State
{
public:
void Operation(Work *work) //吸氣操作
{
if(work->GetStep() == 1)
{
cout<<"Step : "<<work->GetStep()<<"吸氣操作"<<endl;
}
else
{
State *p = new CompressState();
work->SetState(p);
work->Operation();
}
}
};
//測試代碼
int main()
{
State* st = new InhaleState(); //初始狀態
Work *work = new Work(st);
for(int i = 1; i < 5; ++i)
{
work->SetStep(i);
work->Operation(); //操作
}
delete work;
return 0;
}
二. 狀態模式
定義:允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。
結構圖:
使用范圍:
(1)一個對象的行為取決於它的狀態, 並且它必須在運行時刻根據狀態改變它的行為。(上面的例子就是這種情況)
(2)一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。
作者 lwbeyond