设计模式——状态模式
(1)目的:当一个对象状态表达式过于复杂时,把状态的判断转移到表示不同状态的一系列类中,把复杂的逻辑简化。
(2)如何实现:
1.让不同的具体状态类(ConcreteState)继承于基类抽象状态类(AbstracState),重写抽象状态类中与Context类相关的虚接口。
2.Context类内部包含一个ConcreteState的子类实例,这个类定义当前的状态。
(3)优点:
1.将不同状态进行分割,将特定状态相关的行为局部化。
2.消除庞大的条件分支语句,将各种状态转移逻辑转移到各个具体状态的子类之间,减少相互间的依赖。
(4)缺点:
1.每新增一个状态要新增一个类,开发成本较大。
2.较容易产生相互引用,开发比较复杂。
│ abstract_state.cpp
│ abstract_state.h
│ concrete_state1.cpp
│ concrete_state1.h
│ concrete_state2.cpp
│ concrete_state2.h
│ StateModel.cpp
│ work.cpp
│ work.h(Context)
#pragma once
#include "abstract_state.h"
class AbstractState;
class Work
{
private:
AbstractState* state = nullptr;
int hour = 0;
public:
int GetHour();
void SetHour(int);
void GetState();
void SetState(AbstractState*);
};
│ abstract_state.h(AbstracState)
#pragma once
#include <iostream>
#include "work.h"
class Work;
class AbstractState
{
public:
virtual void GetState(Work*) = 0;
};
│ concrete_state1.h(ConcreteState1)
#pragma once
#include "abstract_state.h"
class ConcreteState1 :
public AbstractState
{
public:
void GetState(Work*);
};
│ concrete_state2.h(ConcreteState2)
#pragma once
#include <iostream>
#include "abstract_state.h"
class ConcreteState2 :
public AbstractState
{
public:
void GetState(Work*);
};
│ work.cpp
#include "work.h"
int Work::GetHour()
{
return hour;
}
void Work::SetHour(int tem)
{
hour = tem;
}
void Work::GetState()
{
state->GetState(this);
}
void Work::SetState(AbstractState* tem)
{
state = tem;
}
│ abstract_state.cpp
#include "abstract_state.h"
│ concrete_state1.cpp
#include "concrete_state1.h"
#include "concrete_state2.h"
void ConcreteState1::GetState(Work* work)
{
if (work->GetHour() <= 18)
std::cout << "现在时间为" << work->GetHour() << "点,在打工中" << std::endl;
else
{
work->SetState(new ConcreteState2());
work->GetState();
}
}
│ concrete_state2.cpp
#include "concrete_state2.h"
#include "concrete_state1.h"
void ConcreteState2::GetState(Work* work)
{
if (work->GetHour() > 18)
std::cout << "现在时间为" << work->GetHour() << "点,在下班中" << std::endl;
else
{
work->SetState(new ConcreteState1());
work->GetState();
}
}
│ StateModel.cpp
#include <iostream>
#include "concrete_state1.h"
#include "concrete_state2.h"
int main()
{
Work tem;
tem.SetState(new ConcreteState1());
tem.SetHour(16);
tem.GetState();
tem.SetHour(17);
tem.GetState();
tem.SetHour(18);
tem.GetState();
tem.SetHour(19);
tem.GetState();
tem.SetHour(20);
tem.GetState();
}