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

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

一.简介

英雄项羽在敌方英雄的攻击下存在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();
		}
	}
}

六.运行结果

结果

七.源代码下载

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

原文地址:https://www.cnblogs.com/miaowulj/p/11458635.html