设计模式--第20篇(状态模式)

一,状态模式

状态模式:

  1. 主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转化;
  2. 当一个对象的内在状态改变时,允许改变其行为,使其看起来就像改变了其类;

二,原理类图

在这里插入图片描述
意图: 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
适用性:
一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

三,实例

Context: 环境角色,用于维护State实例,这个实例定义对应当前状态;

package com.neei.state;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  8:27
 * @Description: 游学网--抽奖活动
 * @throws:
 */
public class RaffleActivity {
    private State state;
    private int count = 0;
    State noRaffleState = new NoRaffleState(this);
    State canRaffleState = new CanRaffleState(this);
    State dispenseState = new DispenseState(this);
    State dispenseOutState = new DispenseOutState(this);
    public RaffleActivity(int count) {
        this.state = getNoRaffleState();
        this.count = count;
    }
    //扣积分
    public void deductMoney() {
        state.deductMoney();
    }
    public void raffle() {
        if (state.raffle()) {
            state.dispensePrize();
        }
    }
    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;
    }
    public State getNoRaffleState() {
        return noRaffleState;
    }
    public void setNoRaffleState(State noRaffleState) {
        this.noRaffleState = noRaffleState;
    }
    public State getCanRaffleState() {
        return canRaffleState;
    }
    public void setCanRaffleState(State canRaffleState) {
        this.canRaffleState = canRaffleState;
    }
    public State getDispenseState() {
        return dispenseState;
    }
    public void setDispenseState(State dispenseState) {
        this.dispenseState = dispenseState;
    }
    public State getDispenseOutState() {
        return dispenseOutState;
    }
    public void setDispenseOutState(State dispenseOutState) {
        this.dispenseOutState = dispenseOutState;
    }
}

State: 抽象状态角色,定义一个接口封装与context的一个特点接口相关行为;

package com.neei.state;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  8:24
 * @Description: 游学网
 * @throws:
 */
public abstract class State {
    /**
     * 扣除积分
     */
    public abstract void deductMoney();
    /**
     * 是否抽中奖品
     */
    public abstract boolean raffle();
    /**
     * 发放奖品
     */
    public abstract void dispensePrize();
}

ConcreteState: 具体的状态角色,每个子类实现一个与context的一个状态相关行为;·

package com.neei.state;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  8:26
 * @Description: 游学网-- 不能抽奖
 * @throws:
 */
public class NoRaffleState extends State {
    private RaffleActivity activity;
    public NoRaffleState(RaffleActivity activity) {
        this.activity = activity;
    }
    @Override
    public void deductMoney() {
        System.out.println("积分扣除50,可以抽奖去了~~~");
        activity.setState(activity.getCanRaffleState());
    }
    @Override
    public boolean raffle() {
        System.out.println("扣除相应积分才可以抽奖");
        return false;
    }
    @Override
    public void dispensePrize() {
        System.out.println("该状态不能发奖品");
    }
}

public class CanRaffleState extends State {
    private RaffleActivity activity;
    public CanRaffleState(RaffleActivity activity) {
        this.activity = activity;
    }
    @Override
    public void deductMoney() {
        System.out.println("该状态不扣除积分");
    }
    @Override
    public boolean raffle() {
        System.out.println("开始抽奖");
        Random random=new Random();
        int num =random.nextInt(10);
        if(num==0){
            activity.setState(activity.getDispenseState());
            return true;
        }else {
            System.out.println("很遗憾没有中奖");
            activity.setState(activity.getNoRaffleState());
            return false;
        }
    }
    @Override
    public void dispensePrize() {
        System.out.println("还未中奖,不能发放奖品");
    }
}

public class DispenseState extends State {

    private RaffleActivity activity;

    public DispenseState(RaffleActivity activity) {
        this.activity = activity;
    }

    @Override
    public void deductMoney() {
        System.out.println("该状态不能扣除积分");
    }

    @Override
    public boolean raffle() {
        System.out.println("该状态不能抽奖");
        return false;
    }

    @Override
    public void dispensePrize() {
        if (activity.getCount() > 0) {
            System.out.println("恭喜中奖了");
            activity.setState(activity.getNoRaffleState());
        }else {
            System.out.println("很遗憾,奖品发放完了");
            activity.setState(activity.getDispenseOutState());
        }
    }
}

public class DispenseOutState extends State {

    private RaffleActivity activity;

    public DispenseOutState(RaffleActivity activity) {
        this.activity = activity;
    }

    @Override
    public void deductMoney() {
        System.out.println("奖品发放完毕,后续参加");
    }

    @Override
    public boolean raffle() {
        System.out.println("奖品发放完毕,后续参加");
        return false;
    }

    @Override
    public void dispensePrize() {
        System.out.println("奖品发放完毕,后续参加");
    }
}

调用

package com.neei.state;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  8:24
 * @Description: 游学网
 * @throws:
 */
public class Client {

    public static void main(String[] args) {
        RaffleActivity activity=new RaffleActivity(10);
        for (int i = 0; i <300 ; i++) {
            System.out.println("-----第"+i+"次抽奖-----");
            //抽奖先扣除积分
            activity.deductMoney();
            //抽奖
            activity.raffle();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值