• 初探策略模式


    策略模式:定义了算法族,并分别封装起来,把算法与使用者独立出来,可以在运行时更改类行为或其算法。

    场景:假如有一个游戏用户的账号,这个账号有个元宝属性,并且有充值元宝,使用元宝等行为;充值元宝又分为支付宝充值,微信充值,银联卡充值等。

    最初的想法是这样的
    package pattern.strategy;
    
    public class Account {
        int yuanBao = 0;
    
        public void useYuanBao(int use){
            yuanBao = yuanBao - use;
        }
    
        public void recharge(String type,int yuanBao){
            if(type.equals("支付宝")){
                /*-----------------支付宝充值算法--------------------*/
                System.out.println("使用支付宝充值");
                this.yuanBao = this.yuanBao + yuanBao;
            }else if(type.equals("微信")){
                /*-----------------微信充值算法--------------------*/
                System.out.println("使用微信充值");
                this.yuanBao = this.yuanBao + yuanBao;
            }else{
    
            }
        }
    }

      当前端点击充值的按钮是,传给后端充值类型(type)和元宝数量(yuanBao)并让后端选择充值方式付款。但是这个设计把充值的算法直接写在使用类里面,假如增加一个新的充值方式,那么就要在Account类里面增加代码。当然改善这个代码有很多方式,但是我们来看看策略模式的思想。

      第一步,把充值方法抽离出来我们定义一个充值接口

    package pattern.strategy;
    
    public interface Recharge {
        
        public void recharge();
    }

      并且实现每种充值方式

    支付宝:

    package pattern.strategy;
    
    public class AliPayRecharge implements Recharge {
        @Override
        public void recharge() {
            System.out.println("支付宝充值算法");
        }
    }

    微信:

    package pattern.strategy;
    
    public class WeChatRecharge implements Recharge {
        @Override
        public void recharge() {
            System.out.println("微信充值算法");
        }
    }

      第二步,使用类(Account)与算法(Recharge)关联

    package pattern.strategy;
    
    public class Account {
        int yuanBao = 0;
    
        public void useYuanBao(int use){
            yuanBao = yuanBao - use;
        }
        
        public void recharge(Recharge recharge,int yuanBao){
            recharge.recharge();
            this.yuanBao = this.yuanBao + yuanBao;
        }
    }

      第三部,选择算法进行充值

    package pattern.strategy;
    
    public class RechargeController {
        public static void main(String[] args) {
            String type = "微信";
            int yuanBao = 100;
    
            Recharge recharge = null;
            if(type.equals("微信")){
                recharge = new WeChatRecharge();
            }else if(type.equals("支付宝")){
                recharge = new AliPayRecharge();
            }
            Account account = new Account();
            account.recharge(recharge,yuanBao);
        }
    }

    运行结果:微信充值算法

      至此,策略模式已完成代码的改造,策略模式的优势是使用类与算法之间解耦,用户不用关心算法的实现过程,只要结果就行。增加一个新功能不需要修改使用类,便于扩展和维护。如果使用枚举来进行对算法的选择会更佳,这样的话,前端直接传枚举值就能进行算法的选择。


    举个更简单的例子,计算器大家都知道吧,我们来封装一下计算器的计算算法。

      首先把算法提取出来

    package pattern.strategy.cal;
    
    public interface Operate {
        public int operate(int num1,int num2);
    }

      封装加减乘除的算法

    package pattern.strategy.cal;
    
    public class Add implements Operate {
        @Override
        public int operate(int num1, int num2) {
            return num1 + num2;
        }
    }
    package pattern.strategy.cal;
    
    public class Mul implements Operate {
        @Override
        public int operate(int num1, int num2) {
            return num1 * num2;
        }
    }
    package pattern.strategy.cal;
    
    public class Sub implements Operate {
        @Override
        public int operate(int num1, int num2) {
            return num1 - num2;
        }
    }

      其次,我们实现一个计算器

    package pattern.strategy.cal;
    
    public class Cal {
        private Operate operate;
        
        public Cal(Operate operate){
            this.operate = operate;
        }
        
        public int execute(int num1,int num2){
            return operate.operate(num1,num2);
        }
        
    }

      最后我们测试一下这个计算器

    package pattern.strategy.cal;
    
    public class CalTest {
        public static void main(String[] args) {
            System.out.println("1+1="+(new Cal(new Add())).execute(1,1));
            System.out.println("1*1="+(new Cal(new Mul())).execute(1,1));
            System.out.println("1-1="+(new Cal(new Sub())).execute(1,1));
        }
    }

    输出:

    1+1=2
    1*1=1
    1-1=0

  • 相关阅读:
    如何计算时间复杂度
    注意线程
    java中一个类要当作线程来使用有两种方法
    压缩和解压
    init [0123456]
    linux文件目录
    为什么使用combiner?【Hadoop】
    JAVA标识符
    关键字:java
    转 java 中int String类型转换
  • 原文地址:https://www.cnblogs.com/yzdtofly/p/9430819.html
Copyright © 2020-2023  润新知