专栏首页面试系列(java&Android)大厂面试必备之设计模式:漫画策略模式
原创

大厂面试必备之设计模式:漫画策略模式

小安实现的代码如下:

/**
 * @Author: 程序员小安
 * @description: 购物车
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class ShopCart {
    public ShopCart() {
    }
    public void pay(String payType) {
        if (Constant.WEIXIN_PAY.equals(payType)) {
            //调用微信支付SDK
            System.out.println("您选择的微信支付");
        } else if (Constant.ALI_PAY.equals(payType)) {
            //调用支付宝支付SDK
            System.out.println("您选择的支付宝支付");
        } else if (Constant.WEIXIN_FRIEND_PAY.equals(payType)) {
            //调用微信好友支付SDK
            System.out.println("您选择的找微信好友支付");
        } else if (Constant.QQ_PAY.equals(payType)) {
            //调用QQ支付SDK
            System.out.println("您选择的QQ钱包支付");
        } else {
            System.out.println("您选择的支付方式暂未开通");
        }
    }
}
/**
 * @Author: 程序员小安
 * @description: 购物车常量
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class Constant {
    public static final String WEIXIN_PAY = "1";//微信支付
    public static final String ALI_PAY = "2";//支付宝支付
    public static final String WEIXIN_FRIEND_PAY = "3";//找微信好友支付
    public static final String QQ_PAY = "4";//QQ钱包支付
}
public class MyClass {
    public static void main(String[] args){
        ShopCart shopCart = new ShopCart();
        shopCart.pay(Constant.WEIXIN_PAY);
    }
}

运行结果:

您选择的微信支付

策略模式:

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

官方定义不太好理解,我翻译一下,在策略模式中,会针对一个行为(比如支付),定义多个实现类,每个类都封装具体的实现算法,并且为了保证他们是同一行为,通常这些实现类,都会实现同一个接口。比如微信支付,支付宝支付,微信好友支付,QQ支付,缺省支付方式都是一个算法。

采用策略模式的UML图:

行为接口:

/**
 * @Author: 程序员小安
 * @description: 支付接口
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public interface Payment {
    void pay(String price);
}

具体的支付算法:

/**
 * @Author: 程序员小安
 * @description: 微信支付方式
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class WeixinPay implements Payment {
    @Override
    public void pay(String price) {
        //调用微信支付SDK
        System.out.println("微信支付金额:" + price);
    }
}
/**
 * @Author: 程序员小安
 * @description: 微信好友支付方式
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class WeixinFriendPay implements Payment{
    @Override
    public void pay(String price) {
        //调用微信好友支付SDK
        System.out.println("微信好友支付金额:" + price);
    }
}
/**
 * @Author: 程序员小安
 * @description: QQ支付方式
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class QQPay implements Payment{
    @Override
    public void pay(String price) {
        //调用QQ支付SDK
        System.out.println("QQ支付金额:" + price);
    }
}
/**
 * @Author: 程序员小安
 * @description: 支付宝支付方式
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class AliPay implements Payment {
    @Override
    public void pay(String price) {
        //调用支付宝支付SDK
        System.out.println("支付宝支付金额:" + price);
    }
}
/**
 * @Author: 程序员小安
 * @description: 无支付方式
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class DefaultPay implements Payment{
    @Override
    public void pay(String price) {
        //无支付方式
        System.out.println("您选择的支付方式暂未开通");
    }
}

购物车代码:

/**
 * @Author: 程序员小安
 * @description: 购物车
 * @CreateDate: 2019/10/27
 * @Version: 1.0
 */
public class ShopCart {
    private Payment payment;

    public ShopCart() {
    }

    public void setPayment(Payment payment) {
        this.payment = payment;
    }

    public void pay(String price) {
        payment.pay(price);
    }
}
public class MyClass {
    public static void main(String[] args){
        ShopCart shopCart = new ShopCart();
        WeixinPay weixinPay = new WeixinPay();
        shopCart.setPayment(weixinPay);
        shopCart.pay("12");
    }
}

运行结果:

微信支付金额:12

采用策略模式后,当新增支付方式时,只需要实现一个继承Payment接口的类即可,Shopcart类不需要做任何改动,做到了对修改关闭,对扩展开放的原则,同时也做到针对接口编程,而不是针对实现编程的设计原则。其实真正的项目中,Shopcart是个很复杂的类,里面会有很多业务逻辑,在新增业务不改动旧逻辑,会增加项目的稳定性,也减少测试的工作投入。

策略模式的优点

(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。

(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。

策略模式的缺点

(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。

(2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。

什么时候使用:

某些业务中,某一个行为,会有多个实现类,并且在一次运行中,当前业务只会选择一种实现类。比如商场卖衣服,会有个会员行为,普通会员,银牌会员,金牌会员,客户只能是会员中的一个,不同的人是不同类型的会员,所以他们之间是可以动态替换的。

text_aHR0cHM6Ly9jYW95aW5mZWkuYmxvZy5jc2RuLm5ldA==,size_16,color_FFFFFF,t_70)

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 大厂面试必备之设计模式:漫画单例模式

    饿汉模式中的类实例是当类被加载时就被初始化出来的,所以在应用初始化时,会占用不必要的内存。同时,由于该实例在类被加载的时候就创建出来了,所以他是线程安全的。因为...

    天才少年
  • 面试官问我:Andriod为什么不能在子线程更新UI?

    看完《你为什么在现在的公司不离职?》,很多同学踏上了面试之路,作为颜值担当的天才少年_也开始了面试之路。

    天才少年
  • java之接口

    有时必须从几个类中派生出一个子类,继承它们所有的属性和方法,但是,Java不支持多继承,就有了接口,就可以得到多重继承的效果。

    绝命生
  • 如何对修改密码接口进行压测

    做接口测试中,对于一般性的单业务接口测试很多工具可供选择,但是对于一些相关业务相关性的关联接口测试就比较麻烦,使用工具比如jmeter、postman、soap...

    FunTester
  • 如何对修改密码接口进行压测

      做接口测试中,对于一般性的单业务接口测试很多工具可供选择,但是对于一些相关业务相关性的关联接口测试就比较麻烦,使用工具比如jmeter、postman、so...

    小老鼠
  • Zuul详解

      微服务具有系统小(一个程序员可以独立完成开发),可以独立部署,能快速进行迭代等优点。因为系统切分的小,必然也就意味着会有更多的系统需要进行维护。在实际应用中...

    良辰美景TT
  • 设计模式之适配器模式

    网购支付:(工商支付,建设支付2种)很显然这是两个不同的开发商做的开发,故提供的接口方法不一致,也理所当然。

    用户7657330
  • java接口

    接口中常量的修饰关键字:public,static,final(常量) 函数的修饰关键字:public,abstract 如果没有写全,系统在编译时会自动加上 ...

    用户3030674
  • 扩展资源服务器解决oauth2 性能瓶颈

    详细性能瓶颈分析,请参考上篇文章《扩展jwt解决oauth2 性能瓶颈》

    冷冷
  • 扩展资源服务器解决oauth2 性能瓶颈

    详细性能瓶颈分析,请参考上篇文章《扩展jwt解决oauth2 性能瓶颈》 本文是针对传统使用UUID token 的情况进行扩展,提高系统的吞吐率,解决性能...

    冷冷

扫码关注云+社区

领取腾讯云代金券