定义
状态模式(StatePattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换。
状态模式的注意事项和细节
代码有很强的可读性。状态模式将每个状态的行为封装到对应的一个类中
方便维护。将容易产生问题的if-else语句删除了,如果把每个状态的行为都放到一个类中,每次调用方法时都要判断当前是什么状态,不但会产出很多 if-else 语句,而且容易出错
符合“开闭原则”。容易增删状态
会产生很多类。每个状态都要一个对应的类,当状态过多时会产生很多类,加大维护难度
应用场景:当一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求有不同的行为的时候,可以考虑使用状态模式
实现
import java.util.Random;
/**
* 状态模式
*/
public abstract class State {
//扣除积分方法
abstract void dedeuctPoints();
//是否中奖
abstract boolean winning();
//领取奖品
abstract void awards();
}
class AwardActivity {
State state;//当前状态
int count;//奖品数量
NoAwardState noAwardState = new NoAwardState(this);
CanAwardState canAwardState = new CanAwardState(this);
DispenseAwardState dispenseAwardState = new DispenseAwardState(this);
DispenseOutAwardState dispenseOutAwardState = new DispenseOutAwardState(this);
public AwardActivity(int count) {
this.count = count;
this.state = noAwardState;
}
public void dedeuctPoints() {
state.dedeuctPoints();
}
public void winning() {
if (state.winning()) {
state.awards();
count--;
}
}
public NoAwardState getNoAwardState() {
return noAwardState;
}
public void setNoAwardState(NoAwardState noAwardState) {
this.noAwardState = noAwardState;
}
public CanAwardState getCanAwardState() {
return canAwardState;
}
public void setCanAwardState(CanAwardState canAwardState) {
this.canAwardState = canAwardState;
}
public DispenseAwardState getDispenseAwardState() {
return dispenseAwardState;
}
public void setDispenseAwardState(DispenseAwardState dispenseAwardState) {
this.dispenseAwardState = dispenseAwardState;
}
public DispenseOutAwardState getDispenseOutAwardState() {
return dispenseOutAwardState;
}
public void setDispenseOutAwardState(DispenseOutAwardState dispenseOutAwardState) {
this.dispenseOutAwardState = dispenseOutAwardState;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
//不能抽奖的状态
class NoAwardState extends State {
AwardActivity activity;
public NoAwardState(AwardActivity activity) {
this.activity = activity;
}
@Override
void dedeuctPoints() {
System.out.println("扣除50积分可以抽奖了");
activity.state = activity.getCanAwardState();
}
@Override
boolean winning() {
System.out.println("扣了积分才可以抽奖");
return false;
}
@Override
void awards() {
System.out.println("不能发放奖品");
}
}
//可以抽奖状态
class CanAwardState extends State {
AwardActivity activity;
public CanAwardState(AwardActivity activity) {
this.activity = activity;
}
@Override
void dedeuctPoints() {
System.out.println("===已经扣取过积分了===");
}
@Override
boolean winning() {
System.out.println("===正在抽奖===");
Random random = new Random();
int val = random.nextInt(10);
if (val == 1) {
activity.state = activity.getDispenseAwardState();
return true;
} else {
System.out.println("==很遗憾未中奖== "+val);
activity.state = activity.getNoAwardState();
return false;
}
}
@Override
void awards() {
System.out.println("===不能领取奖品===");
}
}
//发奖状态
class DispenseAwardState extends State {
AwardActivity activity;
public DispenseAwardState(AwardActivity activity) {
this.activity = activity;
}
@Override
void dedeuctPoints() {
System.out.println("==不能扣除积分==");
}
@Override
boolean winning() {
System.out.println("==不能抽奖==");
return false;
}
@Override
void awards() {
if(activity.getCount()>0){
System.out.println("==恭喜中奖==");
activity.setCount(activity.getCount()-1);
activity.setState(activity.getNoAwardState());
}else{
System.out.println("====抱歉,奖品发放完毕===");
activity.state = activity.getDispenseOutAwardState();
}
}
}
//奖品发放完毕状态
class DispenseOutAwardState extends State {
AwardActivity activity;
public DispenseOutAwardState(AwardActivity activity) {
this.activity = activity;
}
@Override
void dedeuctPoints() {
System.out.println("不能扣除积分");
}
@Override
boolean winning() {
System.out.println("不能抽奖");
return false;
}
@Override
void awards() {
System.out.println("抱歉,奖品已经发放完毕");
}
}
class TestState{
public static void main(String[] args) {
AwardActivity awardActivity = new AwardActivity(1);
int flag = 10;
while(flag>0){
//扣除积分
awardActivity.dedeuctPoints();
//开始抽奖
awardActivity.winning();
flag--;
}
}
}