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


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

    一.简介

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

    六.运行结果

    结果

    七.源代码下载

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

  • 相关阅读:
    P7771 【模板】欧拉路径
    远程服务器运行代码命令(后台执行 及时输出)
    服务器显存溢出
    指定python环境下pip安装包
    语音信号处理
    Es 常用命令
    MySQL常用命令
    Mysql数据按天分区,定期删除,及分区索引
    查看Mysql正在执行的事务、锁、等待
    git忽略提交文件 IT
  • 原文地址:https://www.cnblogs.com/miaowulj/p/11458635.html
Copyright © 2020-2023  润新知