自表达代码的特点
自表达代码的的特点
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 "lesson does not exist."; 10 } 11 12 code = checkLessonExpired(lessonId); 13 if (code != 0) { 14 return "lesson is expired."; 15 } 16 17 code = checkLessonVacance(lessonId); 18 if (code != 0) { 19 return "lesson has no vacance."; 20 } 21 22 code = registerLessonRemote(userId, lessonId); 23 if (code != 0) { 24 return "failed to register lesson."; 25 } 26 return ""; 27 }
上述代码在阅读方面有如下问题:
1. code变量的意思在不停的变化。
2. 返回值的String类型在上层很难使用。
这段代码改为自表达方式书写是如下形式:
public void registerLesson(int userId, int lessonId) throws BusinessException { checkUserId(userId); checkLessonId(lessonId); checkLessonExpired(lessonId); checkLessonVacance(lessonId); registerLessonRemote(userId, lessonId); }
这两种代码的书写方式的差别很明显,自表达的方式有如下优点
1. 没有局部变量
2. 代码不需要返回值
3. 方法签名的异常对上层调用来说很方便。
2. 基本不需要注释
代码需要注释的原因是因为代码的名称和参数不容易理解。比如 (a+ b) >>> 1;意思不是很容易理解。
自表达代码主张代码的书写本身就是自己的意思。这也正是自表达代码的意思由来。
自表达代码阅读起来就像读小说一样,就植物大战僵尸为例:
1 public abstract class Plant { 2 public Weapon weapon; 3 public Health health; 4 5 public void fire() { 6 weapon.fire(); 7 } 8 }
而武器的定义:
1 public abstract class Weapon { 2 public Bullet bullet; 3 public void fire() { 4 GameWorld.getInstance.append(bullet); 5 } 6 }
如此这般,代码基本上不需要注释就很容易明白。
3. 代码结构清晰
比如,书写一个Android输入法的时候,需要判定输入方式的语言类型:Hiragana,Full-Katakana,Half-Katakana, Full-Alphabet, Half-Alphabet, Half-Number。而且需要考虑输入的键盘类型,QWERTY键盘,Kana键盘,12键键盘。
那么在判定一个输入的时候代码会写成这样:
1 public boolean onKey(int primaryCode) { 2 String keyChar =""; 3 if (keyMode = QWERTY) { 4 keyChar = getQwertChar(primaryCode); 5 } else if (keyMode == JAPANESE_50) { 6 keyChar = getJapanese50Char(primaryCode); 7 } else if (keyMode == NUMBER) { 8 keyChar = getNumberChar(primaryCode); 9 } 10 appendComposingChar(keyChar); 11 }
上述代码中的每个方法都要判定当前的语言类型,例如:
1 public String getJapanese50Char(int primaryCode) { 2 switch (language) { 3 case HIRAGANA: 4 return HIRAGANA_TABLE[primaryode]; 5 case FULL_KATAKANA: 6 return FULL_KATAKANA[primaryCode]; 7 case HALF_KATAKANA: 8 return HALF_KATAKANA[primaryCode]; 9 case FULL_ALPHABET: 10 return FULL_ALPHABET[primaryCode]; 11 case HALF_ALPHABET: 12 return HALF_ALPHABET[primaryCode]; 13 case HALF_NUMBER: 14 return HALF_NUMBER[primaryCode]; 15 } 16 }
同样,其他的方法也要如此的写。
但是当键盘上的键按下时,并不是组装候选文字的情况,代码需要继续扩展。到处都会是重复和类似。
简单的改写如下:
1 public interface Language { 2 String getKey(int primaryCode); 3 }
1 public Hiragana implements Language { 2 public String getKey(int primaryCode) { 3 return HIRAGANA[primaryCode]; 4 } 5 }
这会让代码能够具备更好的扩展性。
并且分层清晰,让代码更容易理解。
-----------------------------------------------------------------
现为独立咨询师。为软件企业或者其他企业的软件采购部门提供咨询,帮助改进软件开发流程,员工技术能力提升,以帮助企业在质量成本交货期三方面得到改善。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库