2019年5月13日 星期一

7天學會設計模式 CHAP14 狀態模式 State

7天學會設計模式
http://www.books.com.tw/products/0010750585

chap14.
狀態模式 State
目的:將物件的狀態封裝成類別,讓此物件隨著狀態改變時能有不同的能力
缺點:狀態變動太大時,物件會瘋狂生成。
package com.ssc24.chap14.demo01;
public interface State {
 void move(Warrior warrior);
}

package com.ssc24.chap14.demo01;
public class DesperateState implements State {
 public DesperateState() {
  System.out.println(">>狀態改變,背水一戰");
 }
 @Override
 public void move(Warrior warrior) {
  int hp = warrior.getHp();
  if (hp == 0) {
   warrior.setState(new UnableState());
   warrior.move();
  } else if (hp > 30) {
   warrior.setState(new FuryState());
   warrior.move();
  } else {
   System.out.println("HP=" + warrior.getHp() + " ,背水一戰 傷害增加50%, 防禦增加50%");
  }
 }
}

package com.ssc24.chap14.demo01;
public class FuryState implements State {
 public FuryState() {
  System.out.println(">>狀態改變,狂怒狀態");
 }
 @Override
 public void move(Warrior warrior) {
  int hp = warrior.getHp();
  if (hp > 70) {
   warrior.setState(new NormalState());
   warrior.move();
  } else if (hp <= 30) {
   warrior.setState(new DesperateState());
   warrior.move();
  } else {
   System.out.println("HP=" + warrior.getHp() + " 狂怒狀態 傷害增加30%");
  }
 }
}

package com.ssc24.chap14.demo01;
public class NormalState implements State {
 public NormalState() {
  System.out.println(">>狀態改變,一般狀態");
 }
 @Override
 public void move(Warrior warrior) {
  if (warrior.getHp() > 70) {
   System.out.println("HP=" + warrior.getHp() + " ,一般狀態");
  } else {
   warrior.setState(new FuryState());
   warrior.move();
  }
 }
}

package com.ssc24.chap14.demo01;
public class UnableState implements State {
 public UnableState() {
  System.out.println(">>狀態改變,無法戰鬥");
 }
 @Override
 public void move(Warrior warrior) {
  System.out.println("HP=" + warrior.getHp() + " ,無法戰鬥");
 }
}

package com.ssc24.chap14.demo01;
public class Warrior {
 private int hp;
 private State state;
 public Warrior() {
  this.hp = 100;
  state = new NormalState();
  this.move();
 }
 public void heal(int heal) {
  System.out.println("治療:" + heal);
  this.hp += heal;
  if (this.hp > 100) {
   this.hp = 100;
  }
  this.move();
 }
 public void getDamage(int damage) {
  System.out.println("受到攻擊:" + damage);
  this.hp -= damage;
  if (this.hp < 0) {
   this.hp = 0;
  }
  this.move();
 } 
 public int getHp() {
  return hp;
 }
 public void setState(State state) {
  this.state = state;
 }
 public void move() {
  state.move(this);
 }
}

package com.ssc24.chap14.demo01;
import static org.junit.Assert.*;
import org.junit.Test;
public class WarriorTest {
 @Test
 public void test() {
  System.out.println("===狀態模式測試===");
  Warrior warrior = new Warrior();
  //warrior.move();
  warrior.getDamage(30);
  //warrior.move();
  warrior.getDamage(50);
  //warrior.move();
  warrior.heal(120);
  //warrior.move();
  warrior.getDamage(110);
  //warrior.move();
 }
}

/**
===狀態模式測試===
>>狀態改變,一般狀態
HP=100 ,一般狀態
受到攻擊:30
>>狀態改變,狂怒狀態
HP=70 狂怒狀態 傷害增加30%
受到攻擊:50
>>狀態改變,背水一戰
HP=20 ,背水一戰 傷害增加50%, 防禦增加50%
治療:120
>>狀態改變,狂怒狀態
>>狀態改變,一般狀態
HP=100 ,一般狀態
受到攻擊:110
>>狀態改變,狂怒狀態
>>狀態改變,背水一戰
>>狀態改變,無法戰鬥
HP=0 ,無法戰鬥
**/