【设计模式三】策略模式简介,并利用策略模式和反射优化if-else

在这里插入图片描述

定义

定义一组算法,将每个算法都封装起来,并使他们之间可以互换。

策略模式是对算法的封装,把一系列算法分别封装到对应的类中,并且这些类实现相同的接口,这些类之间可以互相替换。

StrategyContext

package com.zhangyu.myapplication.strategy;

public class StrategyContext {

    private StrategyAbstract strategyAbstract;

    public void setStrategyAbstract(StrategyAbstract strategyAbstract) {
        this.strategyAbstract = strategyAbstract;
    }

    public float price(int km){
        return strategyAbstract.calculatePrice(km);
    }
}

StrategyAbstract

package com.zhangyu.myapplication.strategy;

public interface StrategyAbstract {
    float calculatePrice(int km);
}

Strategy1

package com.zhangyu.myapplication.strategy;

public class StrategyBus implements StrategyAbstract {
    @Override
    public float calculatePrice(int km) {
        return km * 1;
    }
}

Strategy2

package com.zhangyu.myapplication.strategy;

public class StrategySubway implements StrategyAbstract {
    @Override
    public float calculatePrice(int km) {
        return km * 2;
    }
}

调用

        float price;
        int km = 20;
        StrategyContext strategyContext = new StrategyContext();

        strategyContext.setStrategyAbstract(new StrategyBus());
        price = strategyContext.price(km);
        Log.e(TAG, "bus price = " + price);

        strategyContext.setStrategyAbstract(new StrategySubway());
        price = strategyContext.price(km);
        Log.e(TAG, "subway price = " + price);

测试结果

2020-03-29 13:59:17.441 8541-8541/? E/MainActivity: bus price = 20.0
2020-03-29 13:59:17.441 8541-8541/? E/MainActivity: subway price = 40.0

策略模式+反射,优化if-else

if-else 过多时代码就会变得臃肿并且要修改已有的代码,这就违背了对修改关闭对扩展开放的设计原则,这种情况下就引出了策略模式。

if(a){
  //dosomething
}else if (b){
  //doshomething
}else if(c){   
  //doshomething
} else{   
  doshomething
}

在这里插入图片描述
左边是一个常规的策略模式,将这几种情况分别封装到各自的类中。
右边定义了Strategy枚举类,其中包含所有Strategy的信息,StrategySelector中获取到Strategy中的所有策略,然后根据传入的参数创建对应的策略对象。
在这里插入图片描述

方案一,利用反射,通过类名创建类对象

利用反射,通过类名创建类对象。以供StrategyContext使用

package com.zhangyu.StrategyIfElse.context;

import com.zhangyu.StrategyIfElse.strategy.IStrategy;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class StrategySelector {

    public enum Strategy {

        Bronze("青铜用户", "com.zhangyu.StrategyIfElse.strategy.StrategyBronze"),
        Silver("白银用户", "com.zhangyu.StrategyIfElse.strategy.StrategySilver"),
        Gold("黄金用户", "com.zhangyu.StrategyIfElse.strategy.StrategyGold");

        String description;
        String className;

        Strategy(String description, String className) {
            this.description = description;
            this.className = className;
        }

        public String getDescription() {
            return description;
        }

        public String getClassName() {
            return className;
        }

        public static Map<String, String> getAllClass() {
            Map<String, String> map = new HashMap<>();
            for (StrategySelector.Strategy strategy :
                    StrategySelector.Strategy.values()) {
                map.put(strategy.getDescription(), strategy.getClassName());
            }
            return map;
        }
    }

    public static IStrategy getInstance(String desc) {
        //得到所有的策略类
        Map<String, String> allClass = Strategy.getAllClass();
        //得到需要的策略类类名
        String className = allClass.get(desc);
        //根据类名创建类对象
        IStrategy strategy = null;
        try {
            strategy = (IStrategy) Class.forName(className).getDeclaredConstructor().newInstance();
        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return strategy;
    }
}


方案二:不使用反射

package com.zhangyu.StrategyIfElse.context;

import com.zhangyu.StrategyIfElse.strategy.IStrategy;
import com.zhangyu.StrategyIfElse.strategy.StrategyBronze;
import com.zhangyu.StrategyIfElse.strategy.StrategyGold;
import com.zhangyu.StrategyIfElse.strategy.StrategySilver;

import java.util.HashMap;
import java.util.Map;

public class StrategySelector2 {

    public static IStrategy getInstance(String desc) {
        //得到所有的策略类
        Map<String, IStrategy> strategyMap = new HashMap<>();
        strategyMap.put("青铜用户", new StrategyBronze());
        strategyMap.put("白银用户", new StrategySilver());
        strategyMap.put("黄金用户", new StrategyGold());

        return strategyMap.get(desc);
    }
}

Main

package com.zhangyu.StrategyIfElse;

import com.zhangyu.StrategyIfElse.context.StrategyContext;
import com.zhangyu.StrategyIfElse.context.StrategySelector;
import com.zhangyu.StrategyIfElse.strategy.IStrategy;

public class Main {
    public static void main(String[] args) {
        //服务器返回来的信息
        String vipLevel = "白银用户";
        //选择具体的策略
        IStrategy strategy = StrategySelector.getInstance(vipLevel);
        //执行对应的操作
        StrategyContext strategyContext = new StrategyContext(strategy);
        strategyContext.execute();
    }
}

剩下的部分是常规的策略模式

IStrategy接口

package com.zhangyu.StrategyIfElse.strategy;

public interface IStrategy {
    void doSomething();
}

接口的实现类

package com.zhangyu.StrategyIfElse.strategy;

public class StrategyGold implements IStrategy{
    @Override
    public void doSomething() {
        System.out.println("黄金用户的操作");
    }
}

上下文

package com.zhangyu.StrategyIfElse.context;

import com.zhangyu.StrategyIfElse.strategy.IStrategy;

public class StrategyContext {
    IStrategy strategy;

    public StrategyContext(IStrategy strategy) {
        this.strategy = strategy;
    }

    public void execute(){
        strategy.doSomething();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值