随笔分类 - 自表达代码
自表达代码
——阅读时无需停顿的代码书写方法
可以理解为Don't Make Me Think的Coding版
摘要:最近在写《自表达代码》一书,该书第22章将会介绍一个Android平台上的日文输入法的开发过程。通过该开发过程展示如何在程序开发过程中保持代码的可读性、可扩展性和可变更性。在写该部分之前,首先需要进行输入法引擎的设计。下面是一个相对来说傻大笨粗的输入法引擎设计思路。虽然傻大笨粗,但是由于数据量并不大,数据算法次数并不多,所以该设计仍然是“可以接受的”。即处理时间上比较快、存储空间上占用不大。但是距离十分优秀的输入法还有很长的距离要走。输入法的基本工作原理就是,输入一堆英文字符,然后利用英文字符到一个字典中去查找英文字符应该翻译成什么对应的自然语言文字。这里提到的输入法引擎就按照这个思路来设计的
阅读全文
摘要:Java 8 将要推出Lambda表达式,可以在下面的地址了解一下什么是Lambda表达式,为什么要应用Lambda表达式,Lambda表达式又解决了什么问题之类的。http://www.lambdafaq.org/在下列地址可以下载Java8的JDK和JRE(前瞻版的)2012年12月20日刚放出来的。http://jdk8.java.net/download.html而Java8中对于Lambda表达式的支持JDK需要在这个地址下载http://openjdk.java.net/projects/lambda/Eclipse目前并不支持Java 8,所以想要调试Java8的话,所以我们用能
阅读全文
摘要:最后我们来讲一下代码风格的问题1. 魔法数字,也有叫数字常量的 总之,就是一个数字戳在那,谁也不知道这是什么意思, 这种代码还会导致一个问题就是代码的值发生变化的时候,无法确保所有的相关代码都得到修改。 OpenWnn里这种情况太多了,就不一一列举了。 同样的字符串常量也是一个问题。 对于这种情况,定义成常量并不是解决问题的唯一办法,还有很多更好的办法,比如,拆分类。2. 静态表 Java代码中的静态块static{}可以让一部分固定的赋值代码提前执行,但是如果用不好这个特性,反而这个会成为代码的问题。 RomKan代码中的romkanTable ,表示输入的英文字母是如何转换成为假名的。 但
阅读全文
摘要:结构问题是所有问题中最严重的问题,这里的很多问题都反映了作者缺少基本常识。代码的结构就像房屋的结构一样,是支撑整个代码的框架。如果房屋的结构不够结实,房屋就会倒塌。如果代码的结构不够良好那么修改Bug或者对应需求变更的时候就要付出昂贵的代价。1. 缺少MVC结构 严重程度:非常高 输入法和其他应用程序一样,都是由:数据(Model),视图(View)和控制器(Control)构成的,但是OpenWnn没有按照MVC划分类包,也难以区分哪部分代码是数据,那部分代码是视图。2.错误的从属关系 严重程度:非常高 各种对象之间应该有一定的从属关系,例如:图书管理有书架,书架上面有图书。就绝不可以说书里
阅读全文
摘要:接前文,我们继续分析OpenWnn的注释问题1. 为了注释而注释 严重程度:中 注释就是把方法或者变量的名称再重写一遍,这种工作纯属是浪费时间,可以不用花费这种工时。/** Current key-mode */ protected int mCurrentKeyMode; 这种情况在OpenWnn中特别多。2. 啰嗦的注释 严重程度:低 本来可以很短就能够写完的注释,却要写很长的注释,结果也没有因为写的长对于理解产生有益的帮助。 这种情况在OpenWnn中非常少。3. 步步皆注释 严重程度:中 这种情况会拉开代码间距,使代码变得不再流畅。 这种情况在OpenWnn中也非常少。4.缺少注释..
阅读全文
摘要:什么是错题本? 最近一直有热心读者提出:能否找到一个写的不太好的工程例子,然后解析其中的代码错误,让我们能够从中更为直观的体会到糟糕的代码书写。这么多年接触了许多糟糕的代码,但是苦于不能公开,也难以做到。不过,后来接触到了OpenWnn,这是一个很好的工程,它的代码中几乎充斥着各种各样的代码书写坏习惯。就好像中学生的错题本一样,打开一看都是各式各样的错误。足以警醒以后不再犯同样的错误。本章我们将对OpenWnn的代码问题进行解析,从命名、注释、结构和风格四个方面分别进行阐述。什么是OpenWnn呢? 我在前面的博客里至少两次提到这个工程。这是一个Android下的开源日文输入法,由Omron
阅读全文
摘要:我们以Android平台下的输入法为例。假设在OpenWnn输入法(代码请到http://source.android.com/source/downloading.html上找),接入硬件盘的时候,日文输入模式下,按下Shift + T键输入的不是T。应该怎么定位?onKeyDown(int keyCode,KeyEvent event)是入口,然后找到硬件盘的处理方法onEvent();然后再继续找processHardwareKeyboardInputChar(),再继续...再继续...----这种恶梦式的Bug定位主要原因是代码的架构问题。代码的架构不够清晰导致Bug发生时无法快速定
阅读全文
摘要:1.面向对象编程(Object Oriented Programming) 面向对象编程把所有的事物都抽象为对象。即使虚拟的存在也要抽象为对象,比如:关系,状态;有些即使在客观世界中不被定义为对象的东西在面向对象的世界里也会被定义为对象,比如:行为,动作。 和面向过程编程强调:顺序、选择、循环不同,面向对象强调:包含、继承、实现、组合这些关系。面向对象的特点是:封装(Encapsulate)、多态(Polymophism)和继承(Inheritage)。2.依赖注入(Dependency Injection) 当依赖是动态的时候,可以通过在外部配置依赖类的名称的方式,通过反射来将依赖逐步引入。
阅读全文
摘要:自表达代码的的特点1. 代码的返回值意思明确看一个报名程序的书写,这是采用非自表达方式书写的。 1 public String registerLesson(int userId, int lessonId) { 2 int code = checkUserId(userId); 3 if (code != 0) { 4 return "user does not exist."; 5 } 6 7 code = checkLessonId(lessonId); 8 if (code != 0) { 9 return "l...
阅读全文
摘要:除前文所介绍的技巧之外,下列的内容也往往由于不知道而没有加以利用。1. transient关键词2. volatile关键词3. static块4. inline关键词5. Serializable接口6. synchronized关键词下述的方法7.toString()方法8.clone()方法9.equals()方法10.getClass()方法*这一章简略写了。
阅读全文
摘要:劣质代码产生的另外一个原因是管理者的误导,具体的误导行为有如下几种形式:1. 莫名其妙的代码规范 代码规范是为了能够让团队的程序员写出的代码像是一个人写的。本身是好事,但是如果代码规范制定的时候只是照搬照抄,那么代码规范很可能沦为损害代码质量的帮凶。 A. 每行修改的代码都要加注释每行修改的代码都要增加注释是在没有版本管理工具的时候的做法。因为这样可以对比修改的代码。 这种代码的修改方式导致了一个很重要的功能——重构——无法使用。因为每次重构的时候都会变更很多代码,并且没有增加注释。 正确的做法是把修改履历增加到版本工具里。 B. 修改时减少代码的修改量 修改代码时尽量减少代码的修改量是为了减
阅读全文
摘要:我们在研究自表达代码之前,首先要先弄明白代码的本质。在研究代码的本质之前,我们看一下音乐设备的发展:留声机 -> 磁带 -> CD -> Mp3不论设备怎么变化,有一点没有变化的是:这些设备都是用来记录声波信息的——不管记录的形式是塑料还是磁介质。那么代码是如何发展的呢?纸带打孔 -> 汇编语言 -> 解释语言(BASIC) -> 高级语言(C) -> 面向对象语言(C++) ...->一般情况来说,编程语言的主要作用是在人和计算机之间建立翻译机制,把人类能懂的语言写出代码转换成二进制代码。但是,除此之外,代码还有一个更重要的作用被忽视了——代码
阅读全文
摘要:软件开发到处都需要英语。对于人英语不是母语来说,英语能力不足直接影响到代码中用到的单词以及语法,以及能够表达的意思。1、单词试试看,下列单词,不查字典能认识几个:a.wildcardb.assertionc.infinited.inherite.concurrentf.offsetg.abbreviationh.acceleratei.cryptoj.cipherk.gregorianl.exponentm.asteriskn.semicolono.flushp.atomicq.EOFr.SSLs.CSSt.pythonu.weak referencev.NaNw.duplicate上述这些单
阅读全文
摘要:产生劣质代码的另外一个原因是对编程环境的不熟悉。原本想简略讲一讲这一章的,网上关于如何使用IDE的文章到处都是,特意写这么一章给人一种凑数的感觉。但是,回到现实当中,当我发现有这样一些行为的时候,深感对于编程环境的不熟悉是一个造成不能集中精力去思考的很重要的原因之一。这些行为是(在Eclipse里):1. 从行尾移动到行首: 不停地按左键。 正确的方法是按Home2. 为某个变量改名: 拖动滚动条,肉眼搜索,然后用Backspce删除找到的单词,再把复制的名字粘贴进去。 正确的方法是双击变量,按Alt + Shift + R,然后改名3. 某个长方法中的一段想要提出来,变成另外一个方法: ..
阅读全文
摘要:6.空对象模型当需要访问一个对象有可能是空的时候,需要进行空校验。 比如,下面的例子。1 public class User {2 int id;3 String name;4 public void save() {5 System.out.println("Save user");6 }7 }1 public void saveUser(int id, String name) {2 User user = findUserById(id);3 if (user == null) {4 return;5 ...
阅读全文
摘要:3.正则表达式 a. 白名单 下列代码是用来进行白名单校验的,即如果输入的文字符合条件的话就返回true,否则返回false。 1 private static final String[] ENABLED_TEXTS = new String[]{"a", "b", "c", "d", "e"}; 2 3 public boolean isEnabled(String input) { 4 for (String text : ENABLED_TEXTS) { 5 if (text.equal
阅读全文
摘要:2.反射 (Reflect)反射是Java1.5开始出现的特性,反射是通过名称访问类、方法、域、声明的方法。反射方法的出现为Java增加了更多的特性。 a.访问private类型的属性和方法 由于不能访问private的域和方法而无法对相应的功能进行xUnit的测试。但是反射提供了访问private方法的途径,所以,对于private的方法可以进行xUnit测试。1 public class Testee {2 3 private void execute(){4 System.out.println("method called"); 5 }6 } 1...
阅读全文
摘要:产生劣质代码的另外一个原因是对编程员的知识掌握的不够充分。很多特性如果得到正确的利用,会让代码变得更为简练易懂。但是由于对这些特性不够了解或者根本就不知道。只好写出不太好的代码。本文以Java语言为例,将一些高级特性列出来以飨读者。1.声明 (Annotation) 在Java5中就开始引入了Annotation概念。这个概念帮助 a. 编译用声明例如:@Deprecated, @Override b. 语法检验用声明例如:@SuppressWarnings c. 运行时声明例如:@d.自定义声明 例一:根据annotation来进行页面校验。 假设一个考试成绩登记页面,登记的成绩不能超过10
阅读全文
摘要:ISO/IMC 9126对于软件的质量进行了定义,其中包括如下几项: 可理解性(Understandabiliy)、可维护性(Maintainability)、可扩展性(Extensibility)、容错性(Fault Tolerance)和可测试性(Testability)。 这些都和阅读质量相关。在诸多组织里,管理人员和开发人员一样都把目光集中在软件的运行质量上,而很少关心代码的阅读质量。其中很重要的原因是,这些人从来没有听过这些概念。即使有些组织提出过编码规范的要求,但是这也只是一种形式上的要求,至于实际上做的如何,很少有人关心。那么代码的阅读质量为什么这么重要,它又用哪些指标进行衡量呢
阅读全文
摘要:劣质代码令人深恶痛绝。那么它们究竟是怎么产生的呢?只有明白了它们的产生根源,才能够从根本上杜绝劣质代码的产生。劣质代码的产生主要来自于几个方面:1. 理论知识的匮乏 缺少理论知识,以至于不知道什么是优质代码,什么是劣质代码。本文将从质量、2. 编程语言知识不足 由于对编程语言的接触只限于表面的常见功能,更多的高级功能从来没有用过,所以不知道有能够写出更精简的代码的方法。 本文将以Java为例,阐释那些高级而又不常用到的功能。3. 编程工具的不熟悉。 也许有些夸张,我见过有人用键盘上的箭头移动光标到最开始,而不是用Home键的,见过全局替换用眼睛而不是用工具的。尽管每天都在使用编程工具,但是却不
阅读全文