从王者荣耀看设计模式(六.状态模式)

从王者荣耀看设计模式(状态模式)

一.简介

英雄项羽在敌方英雄的攻击下存在3种不同的状态。
1.在健康生命值下——普通状态,在每次被攻击时,当前生命值=剩余生命值-敌方英雄伤害值
2.在生命值低于某一特定的值——被动状态,在每次被攻击时,当前生命值=剩余生命值-敌方英雄伤害值/2
3.英雄项羽生命值低于0——死亡状态

二.状态模式

状态模式:又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式,状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像 是改变了它的类一样

  • 这其中的设计原则有:
  1. 状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。
  2. 状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变
  3. 状态模式所涉及到的角色有:

    环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
    抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
    具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

  • 状态模式的优点:
  1. 面向接口式编程,将实现细节巧妙封装在各个不同的状态类中,状态转换交给状态类自己去实现,外部无需关心;
  2. 将由大量业务、大量逻辑判断的代码去除,状态类内部通过状态的转换实现相关逻辑,代码可读性更好;
  • 组合模式模式的缺点
  1. 增加新的状态时会增加状态类,而且在增加新的状态类之后,环境类需要做相应的修改,不太符合开闭原则

三.结构图

结构图

四.设计类图

类图

五.代码实现

LifeState类(抽象状态类)

package com.game.LifeState;
import com.game.LifeManager.LifeManager;
/*
 * 英雄项羽的游戏状态接口
 * @param life 当前生命值
 * @param lifeManager 状态上下文,用来在实现状态对应的功能处理的时候,可以回调上下文的数据
 */

public interface LifeState {
    //英雄项羽被攻击的状态
    public abstract void beAttacted(int life, LifeManager lifeManager);
}

NormalBeAttackedState类(具体状态类)——正常生命值状态

package com.game.LifeState.impl;

import com.game.LifeManager.LifeManager;
import com.game.LifeState.LifeState;
/*
 * 英雄项羽在健康生命值下被攻击的状态
 */

public class NormalBeAttackedState implements LifeState {
    public void beAttacted(int life, LifeManager lifeManager) {
        //当前生命值=之前生命值-敌方英雄的攻击力
        int newLife=lifeManager.getLife()-lifeManager.getHeroHurt();
        System.out.print("英雄项羽正受到"+lifeManager.heroHurt+"点伤害,");
        System.out.println("当前生命值为"+newLife);
        //设置当前生命值
        lifeManager.setLife(newLife);
    }
}

AttactedUnderPassiveState类(具体状态类)——被动状态下

package com.game.LifeState.impl;

import com.game.LifeManager.LifeManager;
import com.game.LifeState.LifeState;
/*
 * 当项羽生命值小于500,激发被动状态,所受伤害减半
 */

public class AttactedUnderPassiveState implements LifeState {

    public void beAttacted(int life, LifeManager lifeManager) {
        //设置在被动下项羽所受伤害值
        int newHeroHurt=lifeManager.getHeroHurt()/2;
        //设置被动状态下遭受攻击后当前血量
        int newLife=lifeManager.getLife()-newHeroHurt;
        //判断:在被动状态下如果生命值低于0,英雄死亡
        if(newLife>0) {
            System.out.println("英雄项羽激发被动陷阵之志,所受伤害减半");
            System.out.print("英雄项羽正受到"+newHeroHurt+"点受害,");
            System.out.println("当前的生命值为:"+newLife);
            lifeManager.setLife(newLife);
        }else {
            System.out.println("英雄项羽已经死亡");
        }
    }

}

dieState类(具体状态类)——死亡状态

package com.game.LifeState.impl;

import com.game.LifeManager.LifeManager;
import com.game.LifeState.LifeState;
/*
 * 英雄死亡状态
 */

public class dieState implements LifeState {

    public void beAttacted(int life, LifeManager lifeManager) {
        System.out.println("英雄项羽已经死亡");
    }

}

LifeManager类(环境类)

package com.game.LifeManager;

import com.game.LifeState.LifeState;
import com.game.LifeState.impl.AttactedUnderPassiveState;
import com.game.LifeState.impl.NormalBeAttackedState;
import com.game.LifeState.impl.dieState;

/*
 * 环境类
 */

public class LifeManager {
    //持有状体处理对象
    private LifeState state = null;
    //项羽的初始生命值
    private int life=1000;
    //项羽收到敌方攻击的伤害值
    public int heroHurt=0;
    
    //构造方法初始化伤害值
    public LifeManager(int heroHurt) {
        this.heroHurt=heroHurt;
    }

    //get,set
    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }
    
    public int getHeroHurt() {
        return heroHurt;
    }

    public void setHeroHurt(int heroHurt) {
        this.heroHurt = heroHurt;
    }

    public void beAttacked() {
        if(life>500) {
            state=new NormalBeAttackedState();
        }else if(life>0 && life<=500) {
            state=new AttactedUnderPassiveState();
        }else if(life<=0) {
            state=new dieState();
        }
        //转调状态对象执行相应操作
        state.beAttacted(life, this);
    }   
}

LifeManagerTest类(测试类)

package com.game.test;

import com.game.LifeManager.LifeManager;
/*
 * 测试类
 */

public class LifeManagerTest {
    public static void main(String [] args) {
        //设置项羽受到每次126的伤害
        LifeManager lm=new LifeManager(126);
        
        //设置项羽被相应伤害值攻击的次数
        for(int i=0;i<15;i++) {
            lm.beAttacked();
        }
    }
}

运行结果
结果

猜你喜欢

转载自www.cnblogs.com/miaowulj/p/11458635.html