策略模式

定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

略看定义,有点难懂,什么是算法族?就是实现不同业务的各种逻辑分别封装起来,就组成算法族。什么是客户?客户就是使用算法族的使用者。接下来,将用游戏角色的设计来讲解此模式。

假设,公司需要设计一款角色(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();

    }
}

测试结果
策略模式_第1张图片

现在不同角色可以有相同的防御和攻击技能,相同的角色也可以有不同的防御和攻击技能,只要用setDefend和 setweapon设置就可以,这样就实现了代码的复用,有实现了角色类和行为解耦,不再固定了他们的行为了。

恭喜你,学会了策略模式。我们来回顾一下,什么算法族,上述代码中各种攻击和防御方法组成算法族,客户就是国王,皇后,妖怪等。

你可能感兴趣的:(设计模式)