描述

读牛人技术博客 A Java Geek,最开始觉得这样的想法很有创意。提前使用静态代码块把对象存入map容器中,在需要的时候在取。他也有提到可以使用DI的方式把需要的对象提前注入好,但是这两种方式都会造成内存的浪费,因为有一些对象可能是频繁使用,而有些对象用的概率小甚至一次都没有用到,那么这样的方式是不好的。而且,我们是去除if…else…的语句,这样的方式虽然好像没有了if…else…语句,但是本质上并不是最好的方式,只是提供了一种思维方式。

读《重构 改善既有代码的设计》有一条就是,以多态取代条件表达式。这是才是最本质的解决方式。

这里的去除if…else…语句,不是遇见了if…else…语句就去除。这里是这样描述的:你手上有个条件表达式,它根据对象类型的不同而选择不同的行为。而不是平时编写代码遇见一些普通的条件表达式就去把它去除,不是这样的。

而且,一般来说编程语言都有switch语句去替代if…esle…语句。从性能上看这两个语法也只有非常细微的差别,根本无需关心自己使用了哪个语法。

以多态取代条件表达式

代码的坏味道一:

double getSpeed() {

switch_ (_type) {

case EUROPEAN:

return getBaseSpeed();

case AFRICAN:

return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;

case NORWEGIAN_BLUE:

return (is_Nailed) ? 0 : getBaseSpeed(_voltage);

}

throw new RuntimeException("Should be unreachable");

}

代码的坏味道二:

public Foo getFoo(Bar bar) {

if (bar instanceof BarA) {

return new FooA();

} else if (bar instanceof BarB) {

return new FooB();

} else if (bar instanceof BarC) {

return new FooC();

} else if (bar instanceof BarD) {

return new FooD();

}

throw new BarNotFoundException();

}

思路

将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将原始函数声明位抽象函数。

动机(为什么我们要使用多态取代条件表达式?)

多态最根本的好处就是:如果你需要根据对象的不同类型而采取不同的行为,多态使你不必编写明显的条件表达式。

范例来自《重构 改善既有代码设计》,因为去除if…else…语句是很重要的,所以手动记录下来。“员工与薪资”的例子。

类图

根据代码的坏味道一和二以及类图关系,我们可以得到一个初始版本的代码

Employee

class Employee...

int payAmount() {

switch (getType()) {

case EmployeeType.ENGINEER:

return _monthlySalary;

case EmployeeType.SALESMAN:

return _monthlySalary + _commission;

case EmployeeType.MANAGER:

return _monthlySalary + _bonus;

default:

throw new RuntimeException("Incorrect Employee");

}

}

int getType() {

return _type.getTypeCode();

}

private EmployeeType _type;

EmployeeType

abstract class EmployeeType...

abstract int getTypeCode();

Engineer

class Engineer extends EmployeeType...

int getTypeCode() {

return Employee.ENGINEER;

}

Manager

class Manager extends EmployeeType...

int getTypeCode() {

return Employee.MANAGER;

}

Salesman

class Salesman extends EmployeeType...

int getTypeCode() {

return Employee.SALESMAN;

}

最终结果代码布局

Employee

class Employee...

int payAmount() {

return _type.payAmount(this);

}

private EmployeeType _type;

EmployeeType

class EmployeeType...

abstract int payAmount(Employee emp);

Engineer

class Engineer extends EmployeeType...

int payAmount(Employee emp) {

return emp.getMonthlySalary();

}

Manager

calss Manager extends EmployeeType...

int payAmount(Employee emp) {

return emp.getMonthlySalary() + emp.getBouns();

}

Salseman

class Salseman extends EmployeeType...

int payAmount(Employee emp) {

return emp.getMonthlySalary() + emp.getCommission();

}

理解

a, 把Employee中的原来的属性_monthlySalary,_commission,_bonus变成最终的采用一个函数获取。

b, 注意的地方就是谁组合了谁。这里就是Employee组合了EmployeeType。或者可以理解为谁持有了谁的引用。

c, 其次就是一个继承关系。

小结

由于偶然读到别人技术博客关于if…else…的取代文章,发现这也是一个思路,但是不够那么好,于是记录下《重构 改善既有代码设计》的一个以多态取代条件表达式的范例。

注意什么时候可以用到这个范例。以及理解到它的动机。

虽然这样确实处理了if…else…语句,但是一旦使用多态取代条件表达式的方式,必定会引入一个继承或者实现体系,其实,这是增加了理解的复杂度。

面向对象的编程,如果增加了扩展性必定会引入设计模式,而一旦引入设计模式必定增加理解的复杂度,因为总有继承体系和实现体系结构,这种结构也是面向对象编程的特色。面向对象编程不一定比面向过程好。在实际的编码过程中,还是需要权衡这两种方式。

java中if条件中删除此行代码_Java中我如何去除if...else...语句?相关推荐

  1. java jmf 视屏监控的核心代码_Java中利用JMF编写摄像头拍照程序_java

    我把程序分为两种,有趣的和无趣的,最近做了几个有趣的项目,其中一个,应当就算是摄像头拍照程序了.用于现场拍照,生成照片,主要用到java Media Framework(JMF). 首先到SUN下载最 ...

  2. java keytool 代码_java中Keytool的使用总结

    java中Keytool的使用总结 以前用过几次这个东东,但每次都重新查询一次.本文原始出处是这里 . ------------------------------------------------ ...

  3. java单例代码_java中的单例模式的代码怎么写

    单例模式在我们日常的项目中十分常见,当我们在项目中需要一个这样的一个对象,这个对象在内存中只能有一个实例,这时我们就需要用到单例. 一般说来,单例模式通常有以下几种: 1.饥汉式单例 public c ...

  4. 多线程中的互斥控制程序代码_Java中的并发——线程安全性

    一.什么是线程安全性? 当多个线程访问某个类时,不管运行时环境采用何种调度方式,或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,则这个类是线程安全的 ...

  5. java的map键值类型是否固定_Java中Map根据键值(key)或者值(value)进行排序实现

    我们都知道,java中的Map结构是key->value键值对存储的,而且根据Map的特性,同一个Map中 不存在两个Key相同的元素,而value不存在这个限制.换句话说,在同一个Map中Ke ...

  6. java域的控制修饰符可分为_Java中的类和方法的修饰符

    java 中的类和方法的修饰符Java程序在定义类时,除了使用class关键字标识之外,还可以在class之前增加若干类的修饰符来修饰限定所定义的类的特性.类的修饰符分为访问控制符和非访问控制符两大类 ...

  7. java中字符 的含义 有什么作用_Java中字符串常见题之String相关讲解

    今天给大家带来的是在面试中经常被问到的一道题: 无论在Java还是Android中,String是一个很常见的类,但是大家真的很了解吗,我这里有几个题: 1. String str1 = " ...

  8. java的import和python的import对比_Java中的Import和Pacakge作用生动详解(感觉python中的import作用差不多)...

    转自:http://apps.hi.baidu.com/share/detail/6510541 有些人写了一阵子Java,可是对於Java的package跟import还是不太了解很多人以為原始码. ...

  9. java中两种遍历集合的方式_Java中Map集合的两种遍历方式

    Java中的map遍历有多种方法,从最早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下Java中Map集合的两种遍历方式! 关于遍历Map集合的几 ...

最新文章

  1. 性能测试---商场模型分析
  2. java短横线转驼峰_第二讲:Java的运作原理
  3. 最详细的SQL注入相关的命令整理
  4. java防止用户越权访问文件_针对功能权限(url访问)如何避免越权访问
  5. MyBatis——动态SQL语句——if标签和where标签复合使用
  6. TIS教程04-客户端
  7. LintCode Find the Weak Connected Component in the Directed Graph
  8. java font.getfont_java – 无法解析方法’getFont(?)’
  9. Web前端——CSS层叠样式表
  10. git ssh配置完后拉取代码_使用git在gitlab上拉取代码的方法
  11. mongodb 监控权限_分布式监控系统Zabbix3.4-针对MongoDB性能监控操作笔记
  12. 封装一个时间百分比多个数比较
  13. LaTeX tikz初探——空间矢量旋转示意图,四元数(4)
  14. Linux 命令之 yum 软件仓库
  15. Rust: String 与 str
  16. TableViewCell 自定义分割线
  17. 2020最新版《神经网络与深度学习》中文版更新完毕,pdf开放下载
  18. ps动作储存覆盖原文件的原因
  19. python爬取网易云飙升榜数据
  20. Namenode处于安全模式时,对hadoop进行查看操作,edits_inprogress_txid中没有事物事件的增加,txid没有增加?

热门文章

  1. 绝对干货:供个人开发者赚钱免费使用的一些好的API接口
  2. 进程和线程的联系和区别
  3. windows 9X, 2000, xp所有版本注册表设置(1)
  4. Shell 反引号、$() 和 ${} 的区别
  5. C++11 原生字符串
  6. centos7永久修改ip地址
  7. db2电话号码加密脚本
  8. gdb调试中出现optimized out
  9. WebService基础学习
  10. 编程序常用英语单词是什么