【设计模式】行为型模式-State模式

功能

允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类

解决

  • 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为
  • 何时使用:代码中包含大量与对象状态有关的条件语句
  • 如何解决:将各种具体的状态类抽象出来
  • 关键代码:状态模式的接口中有一个或者多个方法

优缺点

  • 优点:
    • 封装了转换规则
    • 枚举可能的状态,在枚举状态之前需要确定状态种类
    • 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为
    • 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块
    • 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数
  • 缺点:
    • 状态模式的使用必然会增加系统类和对象的个数
    • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
    • 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码

应用场景

  • 应用实例:打篮球的时候运动员可以有正常状态、不正常状态和超常状态
  • 使用场景:
    • 行为随状态改变而改变的场景
    • 条件、分支语句的代替者
  • 注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个

简单示例代码部分

State.hpp

#ifndef _STATE_H_ 
#define _STATE_H_ 
#include <iostream>
using namespace std;

class Context;

class State
{
public:
	State(){}
	virtual ~State(){}
	virtual void OperationInterface(Context* con)=0;
	virtual void OperationChangeState(Context*) = 0; 

protected:
	bool ChangeState(Context* con,State* st);
private:
	//bool ChangeState(Context* con,State* st); 
};


class ConcreteStateA:public State {
public:
	ConcreteStateA(){}
	virtual ~ConcreteStateA(){}
	virtual void OperationInterface(Context* ){
		cout<<"ConcreteStateA::OperationInterface......"<<endl;
	}
	virtual void OperationChangeState(Context* con);
};

class ConcreteStateB:public State {
public:
ConcreteStateB(){}
	virtual ~ConcreteStateB(){}
	virtual void OperationInterface(Context* ){
		cout<<"ConcreteStateB::OperationInterface......"<<endl;
	}
	virtual void OperationChangeState(Context*);
};


class Context{
public:
	Context(){}
	Context(State* state){
		this->_state=state;
	}
	~Context(){
		delete _state;
	}
	void OperationInterface(){
		_state->OperationInterface(this);
	}
	void OperationChangState(){
		_state->OperationChangeState(this);
	}
private:
	friend class State; //表明在State类中可以访问 Context 类的 private 字段
	bool ChangeState(State* state){
		this->_state = state;
		return true;
	}
private:
	State* _state; 
};


void State::OperationInterface(Context* con) {
	cout<<"State::.."<<endl; 
}

bool State::ChangeState(Context* con,State* st) {
	con->ChangeState(st);
	return true; 
}

void ConcreteStateA::OperationChangeState(Context* con){
	OperationInterface(con);
	this->ChangeState(con,new ConcreteStateB());
}
void ConcreteStateB::OperationChangeState(Context* con){
	OperationInterface(con);
	this->ChangeState(con,new ConcreteStateA());
}
#endif

main.cpp

#include "State.h"
#include <iostream>
using namespace std;
int main() {
	State* st = new ConcreteStateA(); 
	Context* con = new Context(st); 
	con->OperationInterface();
	con->OperationInterface (); 
	con->OperationInterface();
	if (con != NULL) delete con;
	if (st != NULL) st = NULL;
	return 0; 
}
发布了64 篇原创文章 · 获赞 3 · 访问量 6210

猜你喜欢

转载自blog.csdn.net/qazsatan/article/details/104296101