ifelse优化方案
优化 if else:https://blog.csdn.net/FBB360JAVA/article/details/103832405
利用java8特性优化: https://blog.csdn.net/sco5282/article/details/118639405
参考:《阿里巴巴java编码规范》、《设计模式》(清华大学出版)、https://blog.csdn.net/mifffy_java/article/details/95201289
1、 阿里编程归约
说明:如果不得不使用 if()...else if()...else... 方式表达逻辑,【强制】避免后序代码维护困难,请勿超过3层。
正例:超过3层的 if else 逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现,其中卫语句示例如下:
public void today(){ if(isBusy()){ System.out.println("change time."); return; }
2、 switch 语句
多个if else的,使用switch case 语句:
switch(status){ case 'A': functionA(); break; case 'B': functionB(); break; case 'C': functionC(); break; default: break; }
3、数组
来自google解释,这是一种编程模式,叫做表驱动法,本质是从表里查询信息来代替逻辑语句。
【案例1】
定义一个接口数组,这是一个函数式接口,其中的方法是单参数无返回值的。
可以使用不同的样式打印传入的参数:
Consumer[] consumers = { System.out::println, arg -> System.out.println("[" + arg + "]"), arg -> System.out.println("(" + arg + ")"), arg -> System.out.println("{" + arg + "}") }; for (Consumer consumer : consumers) { consumer.accept("这句话会打印出来"); }
【案例2】
if else 的写法:定义一个方法,获取星期数。
private static String getWeekDay(int weekStat) { if (0 == weekStat) { return "星期天"; } if (1 == weekStat) { return "星期一"; } if (2 == weekStat){ return "星期二"; } if (3 == weekStat){ return "星期三"; } if (4 == weekStat){ return "星期四"; } if (5 == weekStat){ return "星期五"; } if (6 == weekStat){ return "星期六"; } return null; } // 使用该方法获取星期一 int weekStat = 1; String weekDay = getWeekDay(1); System.out.println(weekDay); 使用数组优化: String[] week = { "星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; // 使用数组获取星期一 int weekStat = 1; String weekDay = week[weekStat]; System.out.println(weekDay)
4、Optional解决判空的if else
环境:基于 jdk8 (高版本还有更厉害、方便的方法,这里不做讨论) String pictureName = "真香.png"; // 当其不为空时,打印在控制台 Optional.of(pictureName).ifPresent(System.out::println); /** * 举个例子:实体类;篇幅原因就不写get set方法了。 */ class User { String name; String password; } public class Demo { public static void main(String[] args) { User user = new User(); user.name = "小冯"; // 过滤到密码是 123456 的目标用户 // 若用户不为 null 则打印用户信息 Optional.of(user) .filter(u -> "123456".equals(u.password)) .ifPresent(System.out::println); // 当用户名存在时,打印用户名 Optional.of(user).map(u -> u.name).ifPresent(System.out::println); } }
5、策略设计模式
5.1 枚举实现
定义一个枚举类: /** * 定义了一周的每一天要干什么 */ enum WeekDay { /**星期天要作甚?*/ Sunday("Sunday"){ @Override void weekRun() { System.out.println(weekName + ":和朋友出去玩!"); } }, /**星期1要作甚?*/ Monday("Monday"){ @Override void weekRun() { System.out.println(weekName + ":在学校学习英语"); } }, /**星期2要作甚?*/ Tuesday("Tuesday"){ @Override void weekRun() { System.out.println(weekName + ":在学校学习java"); } }, /**星期3要作甚?*/ Wednesday("Wednesday"){ @Override void weekRun() { System.out.println(weekName + ":在学校学习语文"); } }, /**星期4要作甚?*/ Thursday("Thursday"){ @Override void weekRun() { System.out.println(weekName + ":在学校学习历史"); } }, /**星期5要作甚?*/ Friday("Friday"){ @Override void weekRun() { System.out.println(weekName + "在学校玩"); } }, /**星期6要作甚?*/ Saturday("Saturday"){ @Override void weekRun() { System.out.println(weekName + "和朋友在家看电影"); } }; public String weekName; abstract void weekRun(); WeekDay(String weekName){ this.weekName = weekName; } } 使用该枚举类: public class Demo { public static void main(String[] args) { // 调用的写法1 WeekDay.valueOf("Sunday").weekRun(); // 调用的写法2 WeekDay.Monday.weekRun(); } }
5.2 多态实现
/** * 跑的行为抽象 */ @FunctionalInterface interface RunStrategy { void run(); } 针对该行为抽象,有几种实现: /** * 人跑的行为 */ class PeopleRunStrategy implements RunStrategy { @Override public void run() { System.out.println("人用腿跑"); } } /** * 汽车跑的行为 */ class CarRunStrategy implements RunStrategy { @Override public void run() { System.out.println("汽车用轮子跑"); } } /** * 鱼跑的行为 */ class FishRunStrategy implements RunStrategy { @Override public void run() { System.out.println("鱼在水里游"); } } 调用: RunStrategy peopleRun = new PeopleRunStrategy(); peopleRun.run();
5.3 map 优化
针对 5.2 多态实现的策略设计模式,使用映射来调用: Map<String, RunStrategy> runStrategyMap = new HashMap<>(16); runStrategyMap.put("people", new PeopleRunStrategy()); runStrategyMap.put("car", new CarRunStrategy()); runStrategyMap.put("fish", new FishRunStrategy()); // 获取汽车的跑的实现,当没有该实现时,调用人的跑的实现 RunStrategy runStrategy1 = runStrategyMap.getOrDefault("car", new PeopleRunStrategy()); // 获取鸟的跑的实现,当没有该实现时,调用人的跑的实现 RunStrategy runStrategy2 = runStrategyMap.getOrDefault("bird", new PeopleRunStrategy()); // 打印:汽车用轮子跑 runStrategy1.run(); // 打印:人用腿跑 runStrategy2.run(); 5.4 工厂设计模式优化 接口与实现类: 与 5.2 中的【案例2】一致。 工厂类: /** * 工厂类 */ class RunStrategyFactory { private RunStrategyFactory(){} private static final Map<String, RunStrategy> RUN_STRATEGY_MAP = new ConcurrentHashMap<>(16); /* * 初始化数据:在Spring框架中,使用反射扫描了包、类, * 再通过类名反射出目标对象,这里使用静态代码块代替这一步骤, * 直接将对象放入 map 容器中。 */ static { RUN_STRATEGY_MAP.put("peopleRunStrategy", new PeopleRunStrategy()); RUN_STRATEGY_MAP.put("fishRunStrategy", new FishRunStrategy()); } /** * 从容器中获取实例:默认为人的策略对象 * @param strategy 策略对象、行为 * @return {@link RunStrategy} */ public static RunStrategy getInstance(String strategy){ return RUN_STRATEGY_MAP.getOrDefault(strategy, new PeopleRunStrategy()); } public static Map<String, RunStrategy> getRunStrategyMap(){ return RUN_STRATEGY_MAP; } /** * 给容器中注册一个策略实例 * @param runStrategy RunStrategy实现类的对象:不能用Lambda;不能用匿名内部类 */ public static void registerStrategy(RunStrategy runStrategy){ String strategy = runStrategy.getClass().getSimpleName(); // 将首字母小写并返回结果 strategy = strategy.substring(0, 1).toLowerCase() + strategy.substring(1); RUN_STRATEGY_MAP.put(strategy, runStrategy); } /** * 给容器中注册一个策略实例 * @param runStrategy RunStrategy实现类的对象或行为 */ public static void registerStrategy(String strategy, RunStrategy runStrategy){ RUN_STRATEGY_MAP.put(strategy, runStrategy); } } 运行测试: public static void main(String[] args) { // 直接获取 RunStrategyFactory.getInstance("fishRunStrategy").run(); // 注册实现类 RunStrategyFactory.registerStrategy(new CarRunStrategy()); // 注册行为 RunStrategyFactory.registerStrategy("snakeRunStrategy",() -> System.out.println("蛇在地上爬")); // 遍历执行 RunStrategyFactory.getRunStrategyMap().forEach((k, v) -> { System.out.println("Strategy = " + k); v.run(); }); } 运行结果: 鱼在水里游 Strategy = carRunStrategy 汽车用轮子跑 Strategy = peopleRunStrategy 人用腿跑 Strategy = fishRunStrategy 鱼在水里游 Strategy = snakeRunStrategy 蛇在地上爬
6、 状态设计模式
/** * Created by Feng on 2020/1/4 11:37<br> * 抽象状态行为:定义不同状态对应的方法 * 方法的实现由其实现类完成 */ @FunctionalInterface interface State { void handle(); } 具体的状态类: /** * 具体的状态类:空闲状态 */ class FreeState implements State { @Override public void handle() { System.out.println("闲着就写代码!!"); } } /** * 具体的状态类:繁忙状态 */ class BusyState implements State { @Override public void handle() { System.out.println("忙了还得写代码!!!"); } } 环境类: /** * 环境类:拥有状态的对象。 * 在环境中维护一个抽象状态类 State 的实例,这个实例定义当前状态。 * 还可以定义初始状态 */ class Context { private State state; /** * 设置状态:调用handle方法 */ public void setState(State state){ this.state = state; state.handle(); } public State getState(){ return state; } }
/** * 客户端:测试 */ public class ContextClient { public static void main(String[] args) { Context context = new Context(); context.setState(new FreeState()); context.setState(new BusyState()); context.setState(() -> System.out.println("这是Lambda 状态啊!!!")); } } 测试结果: 闲着就写代码!! 忙了还得写代码!!! 这是Lambda 状态啊!!!
学海无涯 代码作伴