1、定义:
允许一个对象在其状态改变时改变他的行为。
2、模式结构
3、协作角色
Context 定义客户感兴趣的接口和定义当前状态
State: 定义一个接口以封装与Context的一个特定状态相关的行为
ConcreteState* 实现一个与Context的一个状态相关的行为
4、适用性:
对象的行为决定于其行为,且需要在运行时根据状态的改变他的行为。
多个操作依赖一个相同的条件结构。
5、实例:
1、需求:(引用head first 设计模式上的一个例子)自动糖果机,需求如下图所示:
实现:
gumball.h
#ifndef __GUMBALL_H__
#define __GUMBALL_H__
typedef enum {
MACHINE_SLOD_OUT,
MACHINE_NO_QUARTER,
MACHINE_HAS_QUARTER,
MACHINE_SLOD,
}MACHINE_STATE;
typedef struct {
MACHINE_STATE state;
unsigned int count;
}machine;
int gumball_init(unsigned int count);
int gumball_insertQuarter(void);
int gumball_ejectQuarter(void);
int gumball_turnedCrank(void);
#endif
gumball.c
#include <stdio.h>
#include <string.h>
#include "gumball.h"
machine this_machine;
static int gumball_setState(MACHINE_STATE state)
{
this_machine.state = state;
}
static unsigned int gumball_deCount()
{
this_machine.count--;
return this_machine.count;
}
static int gumball_dispense()
{
unsigned int count;
switch(this_machine.state)
{
case MACHINE_HAS_QUARTER:
printf("No gumball dispensed.\n");
break;
case MACHINE_NO_QUARTER:
printf("You need pay first.\n");
break;
case MACHINE_SLOD_OUT:
printf("No gumball dispensed.\n");
break;
case MACHINE_SLOD:
printf("A gumball comes rolling out the slot.\n");
count = gumball_deCount();
if(count == 0)
{
gumball_setState(MACHINE_SLOD_OUT);
}
else
{
gumball_setState(MACHINE_NO_QUARTER);
}
break;
default:
//never ~
break;
}
return 0;
}
int gumball_init(unsigned int count)
{
memset((void *)&this_machine, 0, sizeof(machine));
this_machine.count = count;
this_machine.state = MACHINE_SLOD_OUT;
if(count > 0)
{
gumball_setState(MACHINE_NO_QUARTER);
}
return 0;
}
int gumball_insertQuarter(void)
{
switch(this_machine.state)
{
case MACHINE_HAS_QUARTER:
printf("You could not insert another quarter.\n");
break;
case MACHINE_NO_QUARTER:
gumball_setState(MACHINE_HAS_QUARTER);
printf("You insert a quarter.\n");
break;
case MACHINE_SLOD_OUT:
printf("You could not insert a quarter , as this machine is sold out.\n");
break;
case MACHINE_SLOD:
printf("Please wait ,we are already giving you a gumball.\n");
break;
default:
//never ~
break;
}
return 0;
}
int gumball_ejectQuarter(void)
{
switch(this_machine.state)
{
case MACHINE_HAS_QUARTER:
printf("quarter returned\n");
gumball_setState(MACHINE_NO_QUARTER);
break;
case MACHINE_NO_QUARTER:
printf("You have not inserted a quarter.\n");
break;
case MACHINE_SLOD_OUT:
printf("You could not insert a quarter , as this machine is sold out.\n");
break;
case MACHINE_SLOD:
printf("you could not eject. You have not inserted a quarter yet.\n");
break;
default:
//never ~
break;
}
return 0;
}
int gumball_turnedCrank(void)
{
switch(this_machine.state)
{
case MACHINE_HAS_QUARTER:
printf("your turned ...\n");
gumball_setState(MACHINE_NO_QUARTER);
break;
case MACHINE_NO_QUARTER:
printf("You turned but there is no quarter.\n");
break;
case MACHINE_SLOD_OUT:
printf("You turned, but there art no gumball.\n");
break;
case MACHINE_SLOD:
printf("Turning twice does not get you another gumball.\n");
break;
default:
//never ~
break;
}
return 0;
}
client.c
#include <stdio.h>
#include "gumball.h"
int main()
{
gumball_init(5);
printf("first test\n");
gumball_insertQuarter();
gumball_turnedCrank();
printf("second\n");
gumball_insertQuarter();
gumball_ejectQuarter();
gumball_turnedCrank();
printf("third\n");
gumball_insertQuarter();
gumball_ejectQuarter();
gumball_turnedCrank();
gumball_ejectQuarter();
printf("last\n");
gumball_insertQuarter();
gumball_turnedCrank();
gumball_insertQuarter();
gumball_turnedCrank();
gumball_insertQuarter();
gumball_turnedCrank();
gumball_ejectQuarter();
printf("over\n");
return 0;
}