每天一个设计模式之策略模式

什么是“策略模式”

策略模式是一种比较简单的模式,也叫做政策模式。
他的定义如下:
定义一组算法,将每个算法都封装起来,并且使他们可以互换。

那么,到底什么是策略模式呢?(概念和优缺点在文末,不想看例子的小伙伴可以直接跳到文末)
我们来举个例子:我们有一款游戏,游戏有四种角色:射手、刺客、狂战士、剑士, 同时也有四种武器可以提供角色进行切换和攻击,但是每次只能使用一种武器。
通过上面这段描述,学习过面向对象的我们可以很轻易地使用继承和抽象设计出以下类

    //角色的抽象类
    public abstract class Role {
        public abstract void fight();
}

然后分别新建四个类,然后继承Role,再分别实现对应的抽象方法, 在抽象方法中使用具体的武器,这么做确实是可以的。但是我们可以想想,我们现在只有四个武器,假如我们出现了十几个甚至上百个武器的时候,我们可能需要修改fight方法十几次甚至上百次,这将会产生多大的工作量。

这个时候, 策略模式就派上用场了:
我们可以将四种武器提取出来,封装成一个接口WeaponInterface, 然后再分别新建四个武器类实现这个接口。

    //武器接口
    public interface WeaponInterface {
        public void userWeapon();
    }

    public class KnifeWeapon implements WeaponInterface {
        @Override
        public void userWeapon() {
            System.out.println("使用匕首进行攻击");
        }
    }

    public class BowAndArrowWeapon implements WeaponInterface {
        @Override
        public void userWeapon() {
            System.out.println("使用弓箭进行攻击");
        }
    }

     public class AxeWeapon implements WeaponInterface {
        @Override
        public void userWeapon() {
            System.out.println("使用斧头进行攻击");
        }
    }

    public class SwordWeapon implements WeaponInterface {
        @Override
        public void userWeapon() {
            System.out.println("使用宝剑进行攻击");
        }
    }

这样一来,武器就封装好了。那么怎么使用呢?
我们可以在Role抽象类中添加这个武器的接口,并且添加setWeaponInterface的方法

    //角色的抽象类
    public abstract class Role {
        WeaponInterface weapon;
        public abstract void fight();

        public void setWeaponInterface(WeaponInterface weaponInterface) {
            this.weaponInterface = weaponInterface;
        }
}

当创建一个角色的时候,只需要实现Role抽象类即可。

    public class ShooterRole extends Role {
        public ShooterRole() {
            //设置默认的武器
            weaponInterface = new KnifeWeapon();
        }

        @Override
        public void fight() {
            System.out.print("我是射手,我");
            weaponInterface.userWeapon();
        }
    }

接下来,我们就可以进行测试了:

    public class Test {

        public static void main(String[] args){
            Role role = new ShooterRole();
            role.fight();
            role.setWeaponInterface(new AxeWeapon());
            role.fight();
        }
    }

输出结果为:

我是射手,我使用匕首进行攻击
我是射手,我使用斧头进行攻击

到此为止,我们已经实现了武器的动态切换了,同时我们假如添加了其他武器,我们也就不需要每次都去修改fight方法了,只需要使用setWeaponInterface方法就可以动态地切换武器。

那么,概念来了:
策略模式使用的就是面向对象的继承和多态机制,它有三个策略角色,分别是:
- 封装角色:例子中的Role或者是射手
- 抽象策略角色:武器的接口。策略、算法家族的抽象,通常为接口。
- 具体策略角色:各类武器(武器接口的具体实现)。实现抽象策略中的操作,含有具体的算法。

优点:

  1. 算法可以自由切换(武器可以自由切换)。
  2. 扩展性好。(增加一个武器的时候只需要实现接口就行)
  3. 避免使用多重判断语句。(切换武器)

缺点:

  1. 策略类数量增多。(增加一个武器就需要增加一个类,并且复用的可能性很小)
  2. 所有策略都必须对外暴露。(要使用一个武器,必须要知道有这个武器,了解这个武器。)这个缺点可以使用其他模式来进行修正,比如工厂方法模式、代理模式等等。

感谢阅读本博客。

欢迎关注我的博客:https://li-weijian.github.io/

欢迎关注我的CSDN:https://blog.csdn.net/qq352642663

需要联系请加QQ:352642663

欢迎联系我共同交流

猜你喜欢

转载自blog.csdn.net/qq352642663/article/details/80555329