设计模式之策略模式

策略模式(Strategy Pattern)是一种简单常用的设计模式,也叫做政策模式(Policy Pattern),定义一组算法,将每个算法封装起来,并且使他们相互转换。

结构组成

  • Context封装角色

它也叫做上下文角色,起承上启下的封装作用,屏蔽高层模块对策略,算法的直接访问,封装可能存在的变化。

  • Strategy抽象策略角色

策略、算法的抽象,通常为接口,定义每个策略或算法必有的方法和属性。

  • 具体策略(ConcreteStrategy)角色

实现抽象策略中的具体操作,该类含有具体的算法。
策略模式实例结构

示例(改编自网红代码)

以下代码改编自业界盛传的某超级大厂的网红代码。

public class VIPCenter {

    /**
     * user共同属性
     */
    class BaseUser {
        //do something
    }

    /**
     * 穷逼user,送的那种
     */
    class SlumDogVIP extends BaseUser {
        //do something
    }

    /**
     * 正儿八经买vip的user
     */
    class RealVIP extends BaseUser {
        //do something
    }
	
	/**
     * 实际业务处理
     */
    public void serviceVIP(BaseUser user) {
        if (user instanceof SlumDogVIP) {
            //穷逼VIP,活动送的那种
            System.out.println("穷逼");
        } else {
            //正儿八经的VIP
            System.out.println("不穷");
        }
    }
}

对于这段代码,业务逻辑集中在一起,当出现新的用户类型时, 比如,增加一个SuperVIP用户类型,这就需要直接去修改服务方法代码实现(在serviceVIP方法里面在加else if),违反了开关原则(Open-Close)(对新增开放,对修改关闭)。这可能会意外影响不相关的某个用户类型逻辑。

改进

public class VIPCenterImprove {
    //抽象策略
    private ServiceHandler serviceHandler;
    //构造函数设置具体策略
    public VIPCenterImprove(ServiceHandler serviceHandler) {
        this.serviceHandler = serviceHandler;
    }
    /**
     * Context封装角色
     * 封装后的策略方法
     */
    public void serviceVIP(BaseUser user) {
        this.serviceHandler.service(user);
    }
    /*------------------------------------------------*/

    /**
     * user共同属性
     */
    static class BaseUser {
        private String desc;

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }
        //do something
    }
    /*------------------------------------------------*/
    /**
     * 穷逼user,送的那种
     */
    static class SlumDogVIP extends BaseUser {
        //do something
    }
    /*------------------------------------------------*/
    /**
     * 正儿八经买vip的user
     */
    static class RealVIP extends BaseUser {
        //do something
    }
    /*------------------------------------------------*/
    /**
     * 可以为所欲为的VIP
     */
    static class SuperVip extends BaseUser{

    }
    /*------------------------------------------------*/
    /**
     * Strategy抽象策略角色
     */
    interface ServiceHandler{
        void service(BaseUser user);
    }
    /*------------------------------------------------*/
    /**
     * 具体策略(ConcreteStrategy)角色
     * 处理穷逼VIP
     */
    static class SlumDogVIPServiceHandler implements ServiceHandler{
        @Override
        public void service(BaseUser user){
            System.out.println("该用户是:" + user.getDesc());
            System.out.println("穷逼");
        }
    }
    /*------------------------------------------------*/
    /**
     * 具体策略(ConcreteStrategy)角色
     * 处理正常的VIP
     */
    static class RealVIPServiceHandler implements ServiceHandler{
        @Override
        public void service(BaseUser user) {
            System.out.println("该用户是:" + user.getDesc());
            System.out.println("正常人");
        }
    }
    /*------------------------------------------------*/
    /**
     * 具体策略(ConcreteStrategy)角色
     * 处理可以为所欲为的VIP
     */
    static class SuperVipServiceHandler implements ServiceHandler{
        @Override
        public void service(BaseUser user) {
            System.out.println("该用户是:" + user.getDesc());
            System.out.println("可以为所欲为的VIP");
        }
    }
    /*------------------------------------------------*/

    public static void main(String[] args) {
        //声明一个具体的策略
        ServiceHandler serviceHandler1 = new SlumDogVIPServiceHandler();
        BaseUser user1 = new SlumDogVIP();
        user1.setDesc("穷逼");
        //声明一个上下文对象
        VIPCenterImprove vipCenter1 = new VIPCenterImprove(serviceHandler1);
        //执行封装后的方法
        vipCenter1.serviceVIP(user1);

        //第二种策略
        serviceHandler1 = new RealVIPServiceHandler();
        user1 = new RealVIP();
        user1.setDesc("正常");
        //只需“注入”策略实现类(RealVIPServiceHandler)
        vipCenter1 = new VIPCenterImprove(serviceHandler1);
        vipCenter1.serviceVIP(user1);
        
        //第三种策略
        /*serviceHandler1 = new SuperVipServiceHandler();
        user1 = new SuperVip();
        user1.setDesc("富豪");
        vipCenter1 = new VIPCenterImprove(serviceHandler1);
        vipCenter1.serviceVIP(user1);*/
    }

上面的示例,将不同的对象分类的服务方法进行抽象,把业务逻辑的紧耦合关系拆开,实现代码隔离方便扩展。如果以后再出现新的用户类型,只需要重新实现一个策略接口ServiceHandler即可,然后将其注入到VIPCenterImprove(Context),这样比直接在serviceVIP方法里面加else if 优雅!

优缺点

优点

  • 算法自由切换,只需要将具体的实现类“注入”到Context中即可
  • 避免多重条件判断
  • 扩展性良好

缺点:

  • 策略类数量增多
  • 所有的策略类必须都需要对外暴露。

使用场景:

  • 多个类只有在算法或行为上的不同
  • 算法需要自由切换
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值