定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
略看定义,有点难懂,什么是算法族?就是实现不同业务的各种逻辑分别封装起来,就组成算法族。什么是客户?客户就是使用算法族的使用者。接下来,将用游戏角色的设计来讲解此模式。
假设,公司需要设计一款角色(Character)游戏,有国王(King),皇后(queen),骑士(Knight),妖怪(Troll),这些角色都具有攻击和防御的技能,但攻击和防御的方式各不相同。
看到需求,感觉挺简单的,写一个超类Character,类中有防御defend()和攻击fight()方法,然后让其他具体的角色去继承超类,覆写其中防御defend()和攻击fight()方法,具体角色实现其中的方法。
初始代码
package com.zengfeng.bean;
public abstract class Character {
public String name;
//角色显示类型
public abstract void display();
//攻击方法
public abstract void fight();
//防御
public abstract void defend();
}
国王
public class King extends Character{
public King(String name) {
this.name=name;
}
@Override
public void display() {
System.out.println("我是国王"+name);
}
//攻击方法
public void fight(){
System.out.println("使用斧头进行攻击");
}
//防御
public void defend(){
System.out.println("使用魔法防御");
}
}
皇后
public class Queen extends Character{
public King(String name) {
this.name=name;
}
@Override
public void display() {
System.out.println("我是皇后"+name);
}
//攻击方法
public void fight(){
System.out.println("使用斧头进行攻击"+);
}
//防御
public void defend(){
System.out.println("使用盾牌防御");
}
}
其他角色类就不实现了,经过上述代码,发现每个角色都要实现defend()和攻击fight()方法,假设有些角色的攻击和防御技能都一样,代码会有很多重复的,没有达到代码复用。当相同角色拥有不一样的技能时,上述代码根本无能为力。
接下来想想,能不能用接口来实现,接口也不能实现代码复用,具体实现还是要具体角色实现。所以还是不靠谱,现在策略模式就派上大用场了
修改后的代码
武器接口
//接口类
public interface WeaponBehavior {
//使用武器
public void useWeapon();
}
武器具体实现类
package com.zengfeng.bean;
public class AxeBehavior implements WeaponBehavior{
@Override
public void useWeapon() {
System.out.println("使用斧头进行进攻");
}
}
package com.zengfeng.bean;
public class BowAndArrowBebavior implements WeaponBehavior{
@Override
public void useWeapon() {
System.out.println("使用弓箭进行进攻");
}
}
package com.zengfeng.bean;
public class SwordBehavior implements WeaponBehavior{
@Override
public void useWeapon() {
System.out.println("使用宝剑进行进攻。");
}
}
package com.zengfeng.bean;
public class KnifeBehavior implements WeaponBehavior{
@Override
public void useWeapon() {
System.out.println("使用匕首进行进攻。");
}
}
防御接口
package com.zengfeng.bean;
public interface DefendBehavior {
//防御
public void defend();
}
防御具体实现类
package com.zengfeng.bean;
//用护牌防御
public class DefendWithbrand implements DefendBehavior{
@Override
public void defend() {
System.out.println("用护牌防御.");
}
}
package com.zengfeng.bean;
public class DefendWithMargic implements DefendBehavior{
@Override
public void defend() {
System.out.println("用魔法防御。");
}
}
package com.zengfeng.bean;
//用盾牌防御
public class DefindWithshield implements DefendBehavior{
@Override
public void defend() {
System.out.println("用盾牌防御.");
}
}
对超类进行改变,代码如下
package com.zengfeng.bean;
public abstract class Character {
public String name;
public abstract void display();
//使用武器
public WeaponBehavior weapon;
//防御
public DefendBehavior defend;
//设置攻击的类型
public void setweapon(WeaponBehavior weapon){
this.weapon=weapon;
}
//设置防御的类型
public void setDefend(DefendBehavior defend){
this.defend=defend;
}
//攻击方法
public void fight(){
weapon.useWeapon();
}
//防御
public void defend(){
defend.defend();
}
}
超类中用组合方式将 WeaponBehavior和DefendBehavior 引入。
具体的角色实现类
package com.zengfeng.bean;
public class King extends Character{
public King(String name) {
this.name=name;
}
@Override
public void display() {
System.out.println("我是国王"+name);
}
}
package com.zengfeng.bean;
public class Queen extends Character{
public Queen(String name) {
this.name=name;
}
@Override
public void display() {
System.out.println("皇后"+name);
}
}
package com.zengfeng.bean;
public class Knight extends Character{
public Knight(String name){
this.name=name;
}
@Override
public void display() {
System.out.println("骑士"+name);
}
}
package com.zengfeng.bean;
public class Troll extends Character{
public Troll(String name){
this.name=name;
}
@Override
public void display() {
System.out.println("妖怪"+name);
}
}
测试代码
package com.zengfeng.bean;
public class CharacterTest {
public static void main(String[] args) {
/* * 国王 * */
Character PJking=new King("普京");
//设置武器,要什么武器就设置什么武器
PJking.setweapon(new AxeBehavior());
//设置防御技能
PJking.setDefend(new DefendWithMargic());
PJking.display();
//进攻
PJking.fight();
//防御
PJking.defend();
System.out.println("----------------------");
/* * 妖怪 * */
Character troll=new Troll("野兽");
troll.setweapon(new KnifeBehavior());
troll.setDefend(new DefendWithbrand());
troll.display();
troll.defend();
troll.fight();
}
}
现在不同角色可以有相同的防御和攻击技能,相同的角色也可以有不同的防御和攻击技能,只要用setDefend和 setweapon设置就可以,这样就实现了代码的复用,有实现了角色类和行为解耦,不再固定了他们的行为了。
恭喜你,学会了策略模式。我们来回顾一下,什么算法族,上述代码中各种攻击和防御方法组成算法族,客户就是国王,皇后,妖怪等。