策略模式与简单java实例
策略模式的定义:定义了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
首先看策略模式的定义,算法簇也就是一群实现了同一个接口的实现类,让它们之间可以相互替换的意思也就是要针对接口编程,而不是针对类编程。此模式让算法的变化独立于使用算法的客户是说,采用何种算法只取决于调用者。
现在说说例子:
一个格斗游戏,角色类Fighter可以使用很多武器,不同武器攻击力以及特殊效果不同,比如使用剑能有一定几率造成额外伤害,斧子有一定几率造成双倍伤害。如果不使用模式的情况下实现这个游戏的话,Fighter就应该有一些方法:attackWithSword(),attackWithAxe()。如果剑类武器又有:铁剑、霜之哀伤,又要为这两把剑写两个方法。如果有1000个武器呢?(当然实现这个的方法还有很多,尤其是笨方法很多。。。)
为了避免以上情况,我们定义一个接口:
package com.Weapon;import com.fighter.Fighter;public interface WeaponBehavior {public void attackWithWeapon(Fighter fighter); public String getName();public void setName(String name);}
package com.Weapon;import java.util.Random;import com.fighter.Fighter;//剑类武器有一定几率造成额外的伤害public abstract class Sword implements WeaponBehavior {// 普通伤害int damage;String name;// 特殊攻击的伤害int specialDamage;// 特殊攻击的触发几率int probability;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getDamage() {return damage;}public void setDamage(int damage) {this.damage = damage;}@Overridepublic void attackWithWeapon(Fighter fighter) {normalAttack(fighter);specialAttack(fighter);}protected void normalAttack(Fighter fighter) {System.out.println("用" + this.getName() + "对" + fighter.getName()+ "造成了" + this.getDamage() + "基本伤害。");fighter.loseLife(this.getDamage());}protected void specialAttack(Fighter fighter) {Random r = new Random();int i = r.nextInt(100);if (i < this.probability) {System.out.println(this.getName() + "触发了特殊效果,对" + fighter.getName()+ "造成了" + this.specialDamage + "点额外伤害。");fighter.loseLife(this.specialDamage);}}}
package com.Weapon;import com.fighter.Fighter;/* * 霜之哀伤,攻击力100,有百分之50造成额外的50点伤害。 * */public class Frostmourne extends Sword {public Frostmourne(){this.setName("霜之哀伤");this.setDamage(100);specialDamage=50;probability=50;}@Overrideprotected void specialAttack(Fighter fighter) {super.specialAttack(fighter);}}
package com.Weapon;import java.util.Random;import com.fighter.Fighter;//斧类武器有一定几率造成双倍伤害public abstract class Axe implements WeaponBehavior {// 普通伤害int damage;String name;// 特殊攻击的伤害int specialDamage;// 特殊攻击的触发几率int probability;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getDamage() {return damage;}public void setDamage(int damage) {this.damage = damage;}@Overridepublic void attackWithWeapon(Fighter fighter) {normalAttack(fighter);specialAttack(fighter);}protected void normalAttack(Fighter fighter) {System.out.println("用" + this.getName() + "对" + fighter.getName()+ "造成了" + this.getDamage() + "基本伤害。");fighter.loseLife(this.getDamage());}protected void specialAttack(Fighter fighter) {Random r = new Random();//斧子有一定几率造成双倍伤害this.specialDamage=damage*2;int i = r.nextInt(100);if (i < this.probability) {System.out.println(this.getName() + "触发了特殊效果,对" + fighter.getName()+ "造成了" + this.specialDamage + "点额外伤害。");fighter.loseLife(this.specialDamage);}}}
package com.Weapon;import com.fighter.Fighter;/* * 公正使者,攻击力100,有百分之30几率造成双倍伤害。 * */public class Axe1 extends Axe {public Axe1(){this.setName("公正使者");this.setDamage(100);probability=30;}@Overrideprotected void specialAttack(Fighter fighter) {super.specialAttack(fighter);}}
package com.fighter;import com.Weapon.WeaponBehavior;public class Fighter {private int life;private String name;private WeaponBehavior weapon;public Fighter(String name,WeaponBehavior weapon){this.weapon=weapon;this.name=name;this.life=1000;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void hit(Fighter fighter){this.weapon.attackWithWeapon(fighter);}public int getLife() {return life;}private void setLife(int life) {this.life = life;}public WeaponBehavior getWeapon() {return weapon;}public void setWeapon(WeaponBehavior weapon) {this.weapon = weapon;}public void loseLife(int damage){this.setLife(this.getLife()-damage);}public void changeWeapon(WeaponBehavior weapon){System.out.println(this.getName()+"装备了"+weapon.getName());this.setWeapon(weapon);}}
package com.main;import com.Weapon.Axe1;import com.Weapon.Frostmourne;import com.fighter.Fighter;public class Main {public static void main(String[] args) {Fighter player=new Fighter("player",new Frostmourne());Fighter computer=new Fighter("computer",new Frostmourne());player.hit(computer);System.out.println(computer.getName()+"还剩下"+computer.getLife()+"生命");player.hit(computer);System.out.println(computer.getName()+"还剩下"+computer.getLife()+"生命"); //这里更换了算法(武器)player.changeWeapon(new Axe1());player.hit(computer);System.out.println(computer.getName()+"还剩下"+computer.getLife()+"生命");player.hit(computer);System.out.println(computer.getName()+"还剩下"+computer.getLife()+"生命");player.hit(computer);System.out.println(computer.getName()+"还剩下"+computer.getLife()+"生命");player.hit(computer);System.out.println(computer.getName()+"还剩下"+computer.getLife()+"生命");}}
用霜之哀伤对computer造成了100基本伤害。霜之哀伤触发了特殊效果,对computer造成了50点额外伤害。computer还剩下850生命用霜之哀伤对computer造成了100基本伤害。霜之哀伤触发了特殊效果,对computer造成了50点额外伤害。computer还剩下700生命player装备了公正使者用公正使者对computer造成了100基本伤害。computer还剩下600生命用公正使者对computer造成了100基本伤害。公正使者触发了特殊效果,对computer造成了200点额外伤害。computer还剩下300生命用公正使者对computer造成了100基本伤害。computer还剩下200生命用公正使者对computer造成了100基本伤害。computer还剩下100生命